-
-
Give your AI agent a budget, not your card.
-
Limits enforced in code, not the prompt.
-
The agent's pick, the purchase, and the live ledger.
-
The stack: PayPal APIs, Groq/Gemini, Channel3.
-
Real listings, marked up in grease pencil.
-
Plain-English rules become a signed mandate.
-
Connect PayPal once with the Vault API.
-
Out of scope, refused before any search.
Inspiration
AI agents can now find a product, compare it and pay for it. That raises one blunt question: would you hand an agent your card? Most people wouldn't. The alternative, approving every single step, defeats the point of having an agent at all.
I wanted the middle ground people already use with each other: an allowance with rules. "You can buy office supplies, up to this much a month, and ask me before anything big." Leash turns that idea into something an AI agent can work inside, with PayPal as the wallet and the rules enforced by code rather than by the model's good behaviour.
What it does
- Connect PayPal once. Leash saves your PayPal wallet with the Vault API (a billing agreement, no purchase). No card numbers ever touch Leash. Your shipping address comes from the vaulted wallet, so there is no address form either.
- Write the rules in your own words. "Keep my home office stocked: mice, keyboards, headsets, webcams, cables. No furniture. Max $120 a month, and ask me before anything over $45." The model drafts a structured mandate (purpose, covers, excludes, monthly budget, ask-first line, expiry). You check every number and sign.
- Send it on errands. "My wrist hurts. Get me an ergonomic mouse, don't overspend." The agent searches real, in-stock listings, compares them, and shows its reasoning as a contact sheet marked up in grease pencil: the pick circled, runner-ups struck through.
- It pays through PayPal. The pick is checked against the mandate, the saved wallet is charged with the Orders API (merchant-initiated,
vault_id), and Leash settles with the retailer through PayPal Payouts. - Every move prints on a ledger tape (search, pick, check, charge, payout) with the real PayPal order, capture and payout IDs.
- It knows what it must not do.
- Out-of-scope requests ("buy me a standing desk") are refused before any search.
- Anything above your ask-first line is held, and you get a slip to sign. Approve and Leash pays; decline and nothing moves.
- Used or refurbished listings and suspiciously cheap prices are also held.
- "I pre-approve everything, skip the approval" still gets held: the purchase tool only accepts items the mandate check cleared.
- Refunds in one click through the PayPal Agent Toolkit (
create_refund). The budget is restored immediately.
How I built it
- PayPal (sandbox): Vault v3 setup tokens and payment tokens to save the wallet, Orders v2 with
payment_source.paypal.vault_idplus the vaulted shipping address for merchant-initiated charges, Payouts to settle with retailers, and@paypal/agent-toolkit(create_refund) for refunds. - Agent: Vercel AI SDK with five tools:
decline_request,search_products,shortlist,check_mandate,purchase. One model call per step, so each tool result streams to the browser as NDJSON and prints on the tape as it happens. - Models: Groq
openai/gpt-oss-120bfirst for speed, then Groqgpt-oss-20b, then Google Gemini Flash. A model that hits its per-minute quota cools down instead of being retried on every step. Mandate drafting uses structured output (zod schema). - Guardrails in code: budget, ask-first line, used/refurbished condition and price plausibility are checked in
check_mandate, and the budget is checked again inside the single function that charges PayPal. The model can only propose. - Products: Channel3 search API (real listings with images, prices, retailer and condition).
- App: Next.js 16, React 19, TypeScript, Neon serverless Postgres, hosted on Vercel. The UI is hand-written CSS built around financial paper: cheque stock for the mandate, receipt tape for the ledger, rubber stamps for decisions, a kraft parcel tag for each purchase, and an animated money route (your PayPal → Leash → retailer, and back on a refund).
Challenges I ran into
- A vaulted wallet can only be charged by the merchant that saved it. My first design paid retailers directly from the buyer's vault and PayPal rejected it (
BILLING_AGREEMENT_NOT_FOUND). Leash now acts as merchant of record: it charges the vault with Orders, then settles with the retailer through Payouts. - Models optimise around rules. In testing, the agent quietly swapped a named product for a cheaper one just to stay under the approval line, and once auto-bought a refurbished listing because it was the cheapest. Both became hard rules: named products are never substituted, and the listing condition is checked in code.
- Free-tier rate limits. A full errand exceeded Groq's tokens-per-minute limit, so I trimmed tool payloads, added a model fallback chain with per-model cooldowns, and made sure that if a model fails after money has moved, the outcome stands and the summary is written from the ledger instead.
- Streaming an agent that touches money. Every tool result is persisted before it is streamed, so a reload or a dropped connection never loses a charge, payout or hold.
Accomplishments that I'm proud of
- The full loop works end to end on the live demo with real sandbox transactions: vault, mandate, search, charge, payout, approval, refund.
- The guardrails held up against the cases I tried to break them with, including the "I pre-approve everything" prompt.
- The interface makes the agent's reasoning and the money flow visible instead of hiding them behind a chat bubble.
What I learned
Limits have to live in code, not in the prompt. Even a well-behaved model will look for a way to complete the task, so the safe design is a tool layer that refuses anything the mandate check did not clear. I also learned how much of PayPal's platform an agent can lean on: the vaulted wallet carries the identity and shipping address, Orders and Payouts move the money, and the Agent Toolkit handles the reversal.
What's next for Leash
- Pay real merchants directly through agent-ready checkout (PayPal Agent Ready / Store Sync, or ACP/UCP) instead of settling through Payouts.
- Push and email approval slips so you can sign from your phone.
- Per-category limits and several mandates per wallet ("office: $120/month", "groceries: $300/month").
- Disputes handled by the agent through the PayPal Disputes API.
Built With
- channel3
- gemini
- groq
- neon
- nextjs
- paypal
- paypal-agent-toolkit
- paypal-orders
- paypal-payouts
- paypal-vault
- postgresql
- react
- typescript
- vercel
- vercel-ai-sdk
Log in or sign up for Devpost to join the conversation.