Inspiration
When a product is recalled, small online sellers often have no idea who bought it. PayPal does. Every payment already carries SKU-level line items, the buyer's contact details and a shipping address, and PayPal can pay the money back. We wanted to see how much of a recall response we could build directly on top of that data.
What it does
Recall Desk takes a recall and runs the response from start to finish:
- Find the buyers. It matches the recalled SKUs against SKU-level PayPal sales, optionally within a sold-date window. Only the affected line item counts, not the whole cart.
- Recommend a fix. For each buyer it suggests a refund, replacement or repair and shows why: hazard severity, item value, replacement stock and how old the sale is.
- Notify. Each buyer gets a notice with a private page where they choose their remedy. Email goes out through any SMTP provider. The hosted demo has none configured, so notices are logged to an Outbox with the same link.
- Pay. Refunds are real PayPal sandbox transactions. Within PayPal's 180 day window it partially refunds just the recalled line on the original capture. After that, or when there is no capture, it sends a PayPal Payout to the buyer's email.
- Track. Every case has an audit trail. Money stays "in flight" until PayPal confirms it, including payouts that are still unclaimed.
Around that:
- A recall watch checks recent US CPSC recalls against what the seller has sold. It matches by UPC, then model number, then brand plus product type. Product type alone never counts, so a recall for "space heaters" does not flag every heater.
- The seller can paste a manufacturer's notice and Claude drafts the recall, citing the evidence for each SKU it matched. The seller reviews it before anything is created.
- Channel3 shows whether the recalled model is still listed in stock at other retailers, and suggests in-stock alternatives from other brands to buyers who take a refund.
- An analytics page built on AG Studio has a recall analyst. You can ask it "what would it cost to recall every HTR-200 sold in the last 6 months?"
What the AI does, and what stays with people
Claude Haiku 5.5 does two jobs. It drafts a recall from a pasted notice, and it powers the analyst on the analytics page.
The analyst can run a what-if using the same matching, remedy and refund-route logic the app uses to pay people. It can re-read PayPal for refunds still in flight, run a market check, and create a dashboard page. AG Studio's own agents then build the widgets. None of its tools can send a refund or an email. Refunds happen when the seller applies them or when a buyer picks a remedy on their page.
This matters because the analyst's numbers come from the real code path rather than a copy of it, and because the money stays behind a human decision.
How we built it
- PayPal: the JS SDK v6 for the storefront checkout, the Server SDK for Orders and partial refunds, Payouts for old sales and sales with no capture, Transaction Search to import past sales, and webhook verification plus a manual sync. A sale is keyed on its capture ID, so importing it twice is safe.
- Remedy engine: plain, pure code with unit tests (89 in the repo, covering the engine, the matcher, PayPal status handling and the adapters).
- AG Studio: two dashboards over the ledger, a custom Recall progress widget, a theme driven by the app's color tokens in light and dark mode, and a stacked layout for phones. AG Studio ships no model adapters, so we wrote one that translates its conversation items and AG-UI events to and from the Anthropic Messages API, behind a rate-limited, same-origin proxy that holds the key.
- Channel3: we use its search and similar products APIs. When the recalled product is in Channel3's catalog we seed
/v1/similarwith it. Otherwise we seed it with the closest in-stock match, and we fall back to a plain search if that call fails. - Render: the demo runs from a
render.yamlblueprint as a free web service with a health check. On boot it seeds fresh PayPal sandbox sales. - The rest is Next.js 16, SQLite with Drizzle, and the CPSC recalls API.
The demo ledger has 10 real card-funded sandbox sales and 284 synthetic orders of history with fictional @example.com buyers. Those buyers have no PayPal accounts, so their payouts correctly stay unclaimed.
Challenges
- Refunds expire. PayPal refunds a capture only for 180 days, so older sales needed a second route, Payouts. A payout to someone without a PayPal account stays unclaimed, so "sent" and "resolved" had to be separate states.
- Matching without false alarms. Matching on product type alone would email buyers of safe products, so it never counts. The market check also requires the model number to appear in the listing.
- Running AG Studio's agents on Claude. The conversation has to end on a user turn, Studio's tool arguments arrive flattened and had to be rebuilt, and Studio's agents cannot create pages, so our analyst creates the page first and then hands the widgets over.
What we are proud of
- Real money movement end to end: partial refunds on captures and Payouts, tracked until PayPal confirms them.
- Recalls are matched per line item, so a buyer is refunded for the recalled item only.
- An analyst that answers "what would this recall cost?" with the logic the app uses to pay people, then builds the dashboard for it.
- A buyer page that offers an in-stock alternative next to the refund.
- A public demo that reseeds itself, so it always has refundable data.
What we learned
- PayPal's transaction data is enough to run a recall. The hard part is the rules around it: refund windows, partial refunds and unclaimed payouts.
- Agents are most useful when their tools are the app's real logic, not a copy of it.
What's next
Working today: everything above, in the PayPal sandbox.
Not built yet:
- Seller sign-in. The console's actions are unauthenticated, which is fine for a demo and not for real use.
- Webhook registration on the hosted demo. For now there is a "Sync with PayPal" button.
- Recall feeds beyond the US, tracking numbers pushed to PayPal for replacements, and alerts when a recalled model shows up in stock again.
- A hosted database, so the recall watch and PayPal status sync can run as background jobs.
We are not product safety or compliance experts. The remedy rules (refund for high severity, refund under $20, replace when stock exists) are our own reasonable defaults. Before real use we would validate them with sellers and recall practitioners.
About the demo video
The video is a real run on the live Render site against the PayPal sandbox, so all money is test money and the buyers are test data. Claude Code drove the mouse and keyboard during the recording. The voice, music and sound effects are AI generated (ElevenLabs).
Built With
- ag-grid
- ag-studio
- anthropic
- channel3
- claude
- cpsc-recalls-api
- drizzle-orm
- next.js
- node.js
- nodemailer
- paypal
- paypal-js-sdk-v6
- paypal-payouts
- react
- render
- sqlite
- tailwindcss
- typescript
- vitest
- zod