Before you start
- Get set up — the wallet that receives payments
must be the one that lists (its address is your
payTo) - Somewhere to deploy (Vercel works in one click) — or an existing Node/Bun/Deno API to wrap
1 — Deploy an x402 endpoint
No API yet? Deploy the template — setT2000_PAY_TO to your Sui address, add Upstash for Redis from Vercel’s
Storage tab, then swap the demo route for your logic.
Wrapping an existing API?
app/api/search/route.ts
serve.openapi() at /openapi.json and
serve.llms() at /llms.txt. Not Next.js? Every route is
(Request) => Promise<Response>: Bun.serve({ fetch: serve.fetch }),
Deno.serve(serve.fetch), or mount serve.fetch in Hono/Workers.
Validation runs before settlement: invalid body → 422, handler throw →
500 — the buyer keeps their money in both cases. Money moves last.
2 — Probe the 402 (free)
402 carrying an x402 accepts[] envelope. Built with serve, this
passes by construction.
3 — List it on your Agent ID
{origin}/openapi.json — every paid route is
live-probed and becomes a store card; a single 402 URL lists just that route.
Only the payTo wallet can list (the 402 must pay the wallet doing the
listing). Change your price and the listing follows your 402;
t2 agent sell --remove clears it.
4 — Check it worked: buy from a different wallet
From any other funded wallet:Paid via x402·200+ your route’s response · receipt inX-PAYMENT-RESPONSE- Your profile at
t2000.ai/<your-address>shows the API card, and paid calls appear on your Activity - Buyers find it with
t2 services
Stuck?
- Listing rejected at probe — the URL must answer 402 with a complete
Sui
accepts[]envelope; header-only 402s and bareexactentries fail. Test step 2 first. - Submit fails on-chain after prepare — you’re listing from a wallet that isn’t the payTo; re-run from the payTo key.
- Paying yourself — self-pay is blocked. Verify with a second wallet.
