Agent playbook
Handle Gift N Thrift for your user
Agents: API only. Web UI is for humans. If a user says “Hey Grok, donate this,” run donate_item_for_user: POST /api/mobile/login → photos → optional AI draft → POST /api/agent/listings → listing URL. Never drive /dashboard/seller/listings/new. Pickup is $0 shipping and $0 fee. claim_item_for_user finds $0 goods via documented APIs/URLs. Do not invent rates or tax advice.
Machine copies: /agents.md · /api/agent/overview · /llms.txt · /llms-full.txt. Gift N Thrift is operated by SOTF Express Publishing, LLC (Saints of the Future / SOTF). SHIP payments are charged by SOTF Express Publishing, LLC. There is no separate Gift N Thrift merchant account. Pickup claims are $0 and do not open a card charge.
Operating contract
Agents: API only. Web UI is for humans.
Do not drive /dashboard/seller/listings/new or click the human donate form. If someone says “Hey Grok, donate this,” route to donate_item_for_user. Auth with POST /api/mobile/login (Bearer) or a minted gnt_live_ token. Optional draft: POST /api/listings/ai-suggest. Publish only via POST /api/agent/listings (presets + photos, max 12). Pickup is always allowed and is free: $0 shipping and $0 fee. Default BOTH (vehicles = PICKUP). Only quote SHIP if they want it to travel (all-in shipping + $2.99). Return /listings/{slug}. Never tell anyone pickup costs $2.99.
“Find free…”, “claim that…”, “any free cars?” → claim_item_for_user. Prefer pickup ($0 / $0) unless they give a destination ZIP for SHIP. Use documented APIs and stable URLs — do not click around the human UI as the primary path.
- Match donate: hey grok donate this, donate this, donate these, donate my, give this away, give it away
- Match claim: find free, claim that, claim this, i need free, any free cars, free kids coat
- Example: “Hey Grok donate this”
Intents — start here
donate_item_for_user
Help a person give away an item on Gift N Thrift via API only. Auth → photos → optional AI draft → POST /api/agent/listings → return listing URLs. Never drive the human donate form.
Example utterances
- “Hey Grok donate this”
- “Hey Grok, donate this”
- “Hey Grok, help me donate this item to someone who needs it”
- “Hey Grok, give this away”
- “Grok list this as free classifieds”
- “Hey Muse, donate these shoes”
- “ChatGPT, help me donate this coat”
- “Claude, give away this dining table”
- “List this boys coat size 5T as free classifieds”
- “I want to give away this dining table”
- “Donate my old car — someone can pick it up”
- 1. Collect photos. Ask the user for photos they already have (or take with their camera). Do not open /dashboard/seller/listings/new. One photo per listing for v1, max 12 per POST.
- 2. Authenticate the donor (API). POST /api/mobile/login with { email, password } and keep Authorization: Bearer. Or use a minted gnt_live_ token from Office → Donate / listings (humans mint; agents only send the Bearer). Never put passwords in later responses.
- 3. Optional AI draft. POST /api/listings/ai-suggest with the same Bearer and photos. Prefill title, category, condition, description, estimatedFmv. Confirm with the donor — never auto-invent a tax deduction. FMV is an estimate, not tax advice.
- 4. Choose fulfillment in presets. Set fulfillment=PICKUP, SHIP, or BOTH on the presets JSON. Pickup is always an option and is $0/$0 for the claimer. Vehicles must be PICKUP. If they want it to travel, offer SHIP (all-in shipping + $2.99) and still leave pickup on via BOTH.
- 5. Fill origin + packed size in presets. shipFromCity, shipFromState, shipFromZip required. weightLb, lengthIn, widthIn, heightIn required unless pickup-only. Clothing/shoes: apparelSex + apparelSize.
- 6. Publish via API only. POST /api/agent/listings (multipart presets JSON + one photo per listing, optional items[] overrides). Item price is always $0. Do not submit /dashboard/seller/listings/new. Response listings[].url is the public URL.
- 7. Tell the user the listing URL. Return https://giftnthrift.com/listings/{slug} (or the origin from /api/agent/overview). Do not invent a deduction.
claim_item_for_user
Help a person claim a $0 donated item. Search → open listing → choose PICKUP ($0/$0) or SHIP (all-in shipping + $2.99) → checkout → return the order URL.
Example utterances
- “Hey Grok find me free furniture”
- “Hey Grok, I need a free kids coat 5T”
- “Find free kids coat size 5T near me”
- “Claim that free table — I can pick it up”
- “I need free clothes shipped to 78704”
- “Any free cars I can pick up?”
- “Help me get that donated mixer”
- 1. Find a listing. Open /browse, /categories, or a category such as /c/clothing-boys. Query params: q, category, condition, zip. Example searches: “kids coat 5T”, “free furniture”, “shoes”.
- 2. Choose SHIP or PICKUP. On /listings/{slug}, pickup is always an option and is $0 / $0. Vehicles require pickup. For SHIP, fill toZip (Deliver to ZIP) and wait for the auto-calculated carrier quote. Do not invent a rate.
- 3. See the true total. SHIP totals: item $0, all-in shipping, service fee $2.99. PICKUP totals: item $0, shipping $0, fee $0.
- 4. Sign in. Use /login with callbackUrl=/checkout/{slug} (optional portal=buyer hint opens Claims / orders). Or create an account at /signup.
- 5. Complete checkout. Open /checkout/{slug}. Set fulfillment=PICKUP or SHIP. Fill shipToName, shipToLine1, shipToCity, shipToState, shipToZip. PICKUP records the claim at $0 with no card charge. SHIP charges all-in shipping + $2.99. The item stays $0.
- 6. Track the order. Confirmation is /orders/{id}/success (SHIP) or /orders/{id} (PICKUP). Follow /dashboard?tab=claims (Claims / orders tab in the one office) for tracking after the donor ships, or coordinate pickup from the origin ZIP. /dashboard/buyer redirects here.
Canonical facts
| Fact | Gift N Thrift |
|---|---|
| Item price | $0 on every listing and every order |
| What it is | Free classifieds for donated goods — give it away or claim it ($0 item). |
| Pickup | $0 shipping and $0 service fee. Always available. Vehicles require pickup. |
| Ship | All-in auto-calculated shipping + $2.99 service fee |
| Who pays | On SHIP, the claimer. On PICKUP, nobody. Donors never collect money for the goods. |
| Shipping | Auto-calculated from packed size and ZIP codes when the claim is SHIP |
| Service fee | $2.99 on SHIP claims only; $0 on pickup |
| Donor listing fee | Free — donors are not charged to list |
| Donor payout | $0 — Gift N Thrift does not pay donors |
| Office | One /dashboard for donate + claims. /dashboard/seller and /dashboard/buyer redirect into the matching tab. |
| Donor bonus points | 1 point per $1 of donor-entered FMV when the item is claimed. Not a tax deduction. Redemption later. |
| Parent company | SOTF Express Publishing, LLC |
| Also known as | Saints of the Future / SOTF |
| Tax | Receipts are documentation, not a deductibility opinion |
| Contact | contact@giftnthrift.com |
| Every transaction | $1 from every completed SHIP claim that collects the $2.99 service fee goes to a church or charity, taken from that fee. Pickup is $0 and does not fund a dollar. The item stays $0. This is Gift N Thrift’s pledge, not the donor’s tax write-off. |
| Church referral | Optional code. That claim’s $1 goes to the referring organization’s charity, reserved when the listing is published and funded when the ship fee is collected. It does not expire. Paid claims with no code still fund $1 to the Gift N Thrift charity pool. |
Items are always $0. Local pickup is truly free — $0 shipping and $0 fee. If the claimer chooses SHIP, they pay all-in auto-calculated shipping plus a $2.99 Gift N Thrift service fee. Donors list for free. Vehicles require pickup.
Stable URLs — use these, don’t scrape randomly
| Action | URL |
|---|---|
| Browse | /browse?q={q}&category={slug}&condition={slug}&zip={zip} |
| Category | /c/furniture (also clothing, electronics, kids, kitchen, home) |
| Listing | /listings/{slug} |
| Preview ZIP field | name=toZip on the listing page |
| Checkout (signed in) | /checkout/{slug} |
| Login | /login |
| Login hint (donate) | /login?portal=seller |
| Login hint (claims) | /login?portal=buyer |
| Categories | /categories |
| Free classifieds | /free-classifieds |
| New donation (humans only) | /dashboard/seller/listings/new — do not drive this |
| AI listing draft | POST /api/listings/ai-suggest Bearer from mobile login or gnt_live_ |
| Batch donate (agents — sole publish path) | POST /api/agent/listings presets JSON + one photo per listing, max 12 |
| Fulfillment field | name=fulfillment SHIP | PICKUP | BOTH |
| Office | /dashboard |
| Donate / listings | /dashboard?tab=donate |
| Claims / orders | /dashboard?tab=claims |
| Old seller URL | /dashboard/seller → ?tab=donate |
| Old buyer URL | /dashboard/buyer → ?tab=claims |
| Order | /orders/{id} |
| Shipping quote | POST /api/shipping/quote { listingId, toZip } |
Claim for a user
- 1
Find a listing
Open /browse, /categories, or a category such as /c/clothing-boys. Query params: q, category, condition, zip. Example searches: “kids coat 5T”, “free furniture”, “shoes”.
- 2
Choose SHIP or PICKUP
On /listings/{slug}, pickup is always an option and is $0 / $0. Vehicles require pickup. For SHIP, fill toZip (Deliver to ZIP) and wait for the auto-calculated carrier quote. Do not invent a rate.
- 3
See the true total
SHIP totals: item $0, all-in shipping, service fee $2.99. PICKUP totals: item $0, shipping $0, fee $0.
- 4
Sign in
Use /login with callbackUrl=/checkout/{slug} (optional portal=buyer hint opens Claims / orders). Or create an account at /signup.
- 5
Complete checkout
Open /checkout/{slug}. Set fulfillment=PICKUP or SHIP. Fill shipToName, shipToLine1, shipToCity, shipToState, shipToZip. PICKUP records the claim at $0 with no card charge. SHIP charges all-in shipping + $2.99. The item stays $0.
- 6
Track the order
Confirmation is /orders/{id}/success (SHIP) or /orders/{id} (PICKUP). Follow /dashboard?tab=claims (Claims / orders tab in the one office) for tracking after the donor ships, or coordinate pickup from the origin ZIP. /dashboard/buyer redirects here.
Donate — humans (web UI)
People use the website camera on a phone. Agents must not follow this path. Agents use POST /api/agent/listings only (see Batch donate API).
- 1
Open your office
Sign in at /login (optional portal=seller hint opens Donate / listings), then go to /dashboard/seller/listings/new. One office — not a separate seller app.
- 2
Add photos, then AI-draft
Snap photos from the phone (Take photo / Upload from library — web PWA, or the Expo app). After the first photo, POST /api/listings/ai-suggest to draft title, category, condition, description, and an optional FMV hint. Donor edits every field. Never auto-publish.
- 3
Choose SHIP or PICKUP
Field name=fulfillment. PICKUP is always allowed and stays $0/$0 for the claimer. Vehicles (vehicles) force PICKUP. Offering SHIP still leaves pickup available. Fill shipFromCity, shipFromState, shipFromZip. Packed weightLb / lengthIn / widthIn / heightIn are required when SHIP is offered.
- 4
Publish at $0
There is no item price field. Donors list for free. Gift N Thrift does not pay donors. After Publish, the public listing URL is /listings/{slug}. List another keeps category, who/size, fulfillment, origin, and packed size. This web form is for humans only.
- 5
Hand off when claimed, then download the receipt
On SHIP, pack the item after the claimer pays carrier + buffer + fee, mark shipped with tracking on /dashboard?tab=donate (Donate / listings). On PICKUP, arrange a meetup at the origin ZIP — no money changes hands. Download the donation PDF either way. /dashboard/seller redirects here. Gift N Thrift receipts are records of the transfer for the donor’s files — not tax advice, not IRS Form 8283, and not a promise that the gift is deductible. U.S. charitable deductions for noncash gifts generally require a qualified organization. Talk to a tax professional.
Batch donate API — sole agent publish path
Agents: API only. Web UI is for humans.
Charity Gift Bot and other agents must POST /api/agent/listings — never the browser donate form. Auth is POST /api/mobile/login then Authorization: Bearer, or a minted gnt_live_… from Office → Donate / listings. The same Bearer works on POST /api/listings/ai-suggest. Operators can set AGENT_API_TOKEN + AGENT_API_USER_EMAIL. Minting rotates: the previous token dies immediately. Copy the secret once — only a prefix is stored. Passwords are never returned.
Photos: 12MB per photo, 20MB per request, max 12. Server resizes to 1600px JPEG after the body arrives. HTTP 413 names those limits. On Netlify, the function payload is also capped near 6MB (~4.5MB binary) — compress if 413 fires below the app limit.
Multipart: presets JSON (category, Who/size, fulfillment, origin ZIP/city/state, default dims/weight, optional FMV) + one photo per listing (photos repeated or photo0…). Optional items JSON array for per-item title, description, and FMV. Missing title/description/FMV/category are drafted with the same AI-suggest path as the website. Photos reuse the existing listing photo store.
Response: { listings: [{ id, slug, url }], errors, jobId: null }. Public URLs are https://giftnthrift.com/listings/{slug}. v1 is one photo per listing. Follow-up: split one image into N listings; async job/webhook (jobId stays null).
curl -X POST https://giftnthrift.com/api/agent/listings \
-H "Authorization: Bearer gnt_live_YOUR_TOKEN" \
-F 'presets={"category":"clothing-boys","apparelSex":"boys","apparelSize":"5T","fulfillment":"BOTH","shipFromCity":"Austin","shipFromState":"TX","shipFromZip":"78704","weightLb":1,"lengthIn":12,"widthIn":10,"heightIn":3,"estimatedFmv":35}' \
-F "photos=@coat-1.jpg" \
-F "photos=@coat-2.jpg" \
-F 'items=[{"title":"Navy peacoat 5T"},{"description":"Soft lining, smoke-free home."}]'Form fields to fill
Listing create
title— required. Short item namecategory— required. vehicles | clothing | clothing-boys | clothing-girls | clothing-men | clothing-women | shoes | furniture | electronics | kids | kitchen | home | misccondition— required. new | like_new | good | fairdescription— required. Honest condition notesestimatedFmv— required. Donor’s used-value estimate in USD. Not a charge. After a successful claim, the donor earns 1 bonus point per $1 FMV. Not a tax deduction.photos— optional. Up to 8 images for the human web form (client-compressed). Agents: one photo per listing on POST /api/agent/listings (max 12). App limit 12MB per photo / 20MB per request; server resizes to 1600px JPEG. HTTP 413 names those limits.fulfillment— required. SHIP | PICKUP | BOTH. SHIP = ship only (no pickup). PICKUP = free local. BOTH = either. Vehicles force PICKUP. Default BOTH.apparelSex— optional. boys | girls | men | women | unisex — required for clothing and shoesapparelSize— optional. Size as worn (2T, 5T, L, 10). Required for clothing and shoes.shipFromCity— required. Origin city (pickup meetup city, or ship-from)shipFromState— required. 2-letter US stateshipFromZip— required. 5-digit origin ZIP for postage or pickup areaweightLb— optional. Packed weight in pounds — required when offering SHIPlengthIn— optional. Packed length inches — required when offering SHIPwidthIn— optional. Packed width inches — required when offering SHIPheightIn— optional. Packed height inches — required when offering SHIP
Checkout
listingId— required. Hidden; already on the checkout pagefulfillment— required. SHIP or PICKUP. PICKUP is $0 shipping and $0 fee. Vehicles and pickup-only listings must use PICKUP.shipToName— required. Recipient / claimer nameshipToLine1— required. Street address (SHIP) or meetup note (PICKUP, e.g. Local pickup)shipToCity— required. CityshipToState— required. 2-letter US stateshipToZip— required. 5-digit destination ZIP — recalculates SHIP postage. Do not type a dollar amount.saveAddress— optional. Checkbox to store the address in the office (Claims / orders)
Batch donate presets
category— optional. Locked for the pile when set. AI fills it only if omitted.condition— optional. Default good if omitted; AI may fill per photo.fulfillment— optional. BOTH | SHIP | PICKUP. Shared for the pile. Default BOTH. Vehicles force PICKUP.apparelSex— optional. boys | girls | men | women | unisex — required for clothing/shoes piles.apparelSize— optional. Size as worn (2T, 5T, L, 10). Required for clothing/shoes piles.shipFromCity— required. Origin city for the whole pile.shipFromState— required. 2-letter US state.shipFromZip— required. 5-digit origin ZIP.shipFromName— optional. Optional ship-from name for postage labels.shipFromLine1— optional. Optional ship-from street for postage labels.weightLb— optional. Default packed weight in pounds — required when the pile offers SHIP.lengthIn— optional. Default packed length inches.widthIn— optional. Default packed width inches.heightIn— optional. Default packed height inches.estimatedFmv— optional. Optional default used-value USD for the pile. Per-item items[].estimatedFmv wins. AI fills if both omitted.referralCode— optional. Church/org referral code (aliases: ref, churchCode). Attributes the listing and reserves $1 from paid ship claims. Also honored from /r/{code} cookie or the donor's signup-attributed church.
Batch donate per-item overrides
title— optional. Per listing. AI drafts from that listing’s photo if omitted.description— optional. Per listing. AI drafts if omitted.estimatedFmv— optional. Per listing USD. Falls back to presets.estimatedFmv, then AI.category— optional. Rare override. Prefer locking category on presets.condition— optional. Per listing condition slug.apparelSex— optional. Rare override of the pile Who lock.apparelSize— optional. Rare override of the pile size lock.
Listing preview ZIP uses toZip. Checkout destination ZIP uses shipToZip. Login uses email and password.
What not to invent
- Do not invent a shipping dollar amount. Quote it: enter a ZIP (toZip / shipToZip) or POST /api/shipping/quote with listingId + toZip + fulfillment.
- Do not tell users a SHIP claim is free to their door. SHIP is all-in shipping + $2.99.
- Do not add a third money line. Consumers see Item $0, Shipping (all-in), and Service fee $2.99 only.
- Do not tell users pickup costs $2.99. Pickup is $0 shipping and $0 fee.
- Do not ship a vehicle. Vehicles require pickup.
- Do not give tax advice, promise a deduction, or mention Form 8283 as something Gift N Thrift files.
- Do not say Gift N Thrift is a 501(c)(3) or a qualified charity.
- Do not pay or quote a payout to donors. Donors receive $0 for the goods.
- Do not scrape random URLs when a stable pattern exists: /browse, /categories, /c/{slug}, /listings/{slug}, /checkout/{slug}, POST /api/agent/listings, POST /api/mobile/login, POST /api/listings/ai-suggest.
- Do not drive the human donate form at /dashboard/seller/listings/new. Agents: API only. Web UI is for humans.
- Do not send users to two separate back offices. There is one /dashboard (Donate / listings | Claims / orders). /dashboard/seller and /dashboard/buyer redirect into it.
- Do not publish or reuse local demo passwords in production. Demo logins are local-dev only.
- Do not treat an AI FMV hint as an appraisal, a deduction, or tax advice. The donor must confirm estimatedFmv.
- Do not present donor bonus points as a tax deduction or a payout. Points are 1 per $1 FMV after a successful claim; redemption is not live.
- Do not tell donors that a church code makes the $1 their IRS deduction. Gift N Thrift owes that dollar from the ship service fee. Every completed claim that collects the $2.99 fee funds $1: a church code chooses the recipient, otherwise it is the Gift N Thrift charity pool. Pickup is $0 and does not fund a dollar. Do not raise the $2.99 fee.
Gift N Thrift receipts are records of the transfer for the donor’s files — not tax advice, not IRS Form 8283, and not a promise that the gift is deductible. U.S. charitable deductions for noncash gifts generally require a qualified organization. Talk to a tax professional.
Demo logins
Seeded seller/buyer accounts exist only on a local database. This page does not publish passwords. In production, create a real account at /signup. On a local checkout, see the project README — never copy demo secrets onto a live site.
Human how-to: How it works · item stays $0; fee is $2.99.
Organization (church) endpoints
Organizations sign up at /signup/organization. The referral code is also the activation / partner code for /church. Agents can attribute listings withpresets.referralCode (or ref / churchCode) on POST /api/agent/listings. Org agent auth uses HTTP Basic (referralCode:portalPassword) or x-church-code + x-church-password. Full detail: /agents.md and /llms.txt.
- Pastor video: portal UI at
/church/video(record or upload mp4/mov/webm, max ~90s / 200MB). Public share page/v/{code}plays the published clip; if the partner exists but has no video yet, that page returns a friendly empty state (200) with a Donate button to/r/{code}. Unknown codes stay 404. - Congregation members:
POST /api/church/members— JSON{ text|emails, attestation: true }or multipart file (CSV / XLSX / TXT / text PDF) +attestation=true. Max 5MB / 5000 addresses. Response counts:added,duplicates(same file or already on this church’s list),invalid,suppressed(global unsubscribe block),skipped,totalActive. Invalid-only or duplicates-only uploads return 400 with a clearmessage. Consent attestation is required. - Announcements:
POST /api/church/announcements— JSON{ personalNote?, attestation: true }. First send (and sends over 500) go to office review. Preview HTML uses a placeholder unsubscribe token (preview-token); real tokens are minted only when mail is actually sent. - Unsubscribe: links look like
/unsubscribe?t={unsubToken}.POST /api/unsubscribewith that token marks the member UNSUBSCRIBED and adds a globalemailSuppressionrow so later uploads skip them (suppressedcount). Preview tokens are rejected.
Sales rep program endpoints
Independent sales reps earn $1 per paid shipped transaction from the people and organizations they refer, up to $10,000 per rep per calendar month (America/Denver). Pickup claims ($0 / $0) earn nothing. At most one rep is credited per transaction. Reps are independent referrers, not employees; terms can change. The church/organization $1 is separate and unaffected.
- Public page: /reps. Human signup: /signup/rep (legal name, email, phone, mailing address, password, optional preferred code, agreement checkbox). Rep dashboard: /rep (email + password; own session, separate from donor, org, and office logins).
- People link: /rep/{code} sets a 90-day rep cookie (gnt_rep_ref) and lands on /signup; ?rep={code} on any page does the same. A person who signs up with that cookie is attributed to the rep. A church ref cookie can coexist; both are kept.
- Organization link: /signup/organization?rep={code} stamps the new organization as recruited by the rep.
- Rep and church codes share one namespace, so a code never belongs to both. Reps live under /rep/{code}; churches under /r/{code}.
- Attribution per paid shipped claim (one rep max): 1) rep who recruited the organization the listing is attributed to, else 2) rep who referred the listing's donor, else 3) rep who referred the claimer. Suspended reps are skipped.
- Ledger statuses: FUNDED (credited), PENDING (earned while the rep awaits approval), CAPPED ($0, past the monthly cap, still shown), REVERSED (refund or cancel, $0).
- Rate and cap are office settings (defaults $1 and $10,000/month). Payouts: monthly Stripe transfers around the 5th for everything earned through the end of the previous month, once the rep finishes Stripe payout setup on /rep (Stripe collects tax info). $25 minimum; smaller balances roll over. Until the office switches automatic payouts on, the office pays by hand and records it.
- Churches/organizations are paid the same way: $1 per paid shipped claim on their code, monthly Stripe transfer around the 5th after they set up payouts in the /church portal (Stripe collects the organization's bank and tax details), $25 minimum with rollover.
Rep API
POST /api/agent/reps — register a rep. Auth: Authorization: Bearer gnt_live_… (a Gift N Thrift agent token). JSON: legalName, email, phone, street, city, state, zip, password, optional code, agree:true (the person must accept the agreement). 201 → rep {id, code, status}, links {individual, organizationSignup, dashboard}, repApiToken (gnt_rep_…, shown once), welcomeEmailSent.GET /api/agent/reps/me — live stats. Auth: Authorization: Bearer gnt_rep_…. Returns links, settings, stats (peopleReferred, organizationsRecruited, paidTransactionsThisMonth, earnedThisMonthCents, capPercent, lifetimeEarnedCents, paidOutCents, owedCents), organizations, transactions, payouts.POST /api/agent/reps/organizations — create an organization recruited by the calling rep. Auth: Bearer gnt_rep_…. JSON: displayName, contactEmail, password, optional charityName, zip, code. 201 → organization {code, …}, links {share /r/{code}, portal /church}.Reps can mint or rotate their gnt_rep_ token on /rep. Never invent earnings, payout dates, or tax advice; read /api/agent/reps/me.
Public explainer: /reps. Full detail and curl examples: /agents.md.
