Suggested frameworks
How the hosted paywall works and the one pattern worth adding on your side.
Hosted proxy architecture
Bags runs the payment layer for you — the 402 challenge, payment verification, settlement, and catalog discovery all live in the hosted proxy. Your backend stays untouched:
| Concern | Bags | Your API |
|---|---|---|
| Payment challenge & verification (x402) | Yes | — |
| Settlement & payout | Yes | — |
| Catalog discovery | Yes | — |
| Signed forwarding to your endpoint | Yes | — |
| Business logic | — | Yes |
| Rejecting paywall-bypass calls | — | Yes (below) |
What Bags forwards to your API
One payment link maps to exactly one targetUrl — no path passthrough; create one link per endpoint. Query strings pass through (caller params are merged onto the targetUrl). All standard methods are supported; bodies are forwarded for POST / PUT / PATCH.
Request headers are allowlisted: only content-type, accept, accept-language, user-agent, and x-bags-* reach your API. Authorization and Cookie never do — agents can't smuggle credentials.
Pricing: flat or metered
exact(default) — every paid call settles the link amount.upto— the link amount is a ceiling. Your API declares the actual usage per call in anx-bags-settle-amountresponse header (decimal USD), and only that settles. Missing header settles the ceiling;0delivers the response free.uptois EVM-only.
Protect your API from paywall bypass
Every proxied request is signed, so your server can tell a paid call apart from someone hitting your targetUrl directly.
Let your coding agent do this. Paste into Claude Code, Cursor, or Codex:
Read https://www.getbags.app/merchants.md and add Bags proxy signature verification to my API endpoint. Reject unsigned requests, but keep accepting requests authenticated with our existing API keys.
Each request carries x-bags-proxy-signature (t=<unix-seconds>,v1=<hex hmac>) and x-bags-proxy-timestamp. The signature is HMAC-SHA256 over:
{timestamp}.{METHOD}.{pathWithQuery}.{sha256HexOfRawBody}Fetch your signing key once and store it server-side:
curl https://www.getbags.app/api/merchant/proxy-signing-secret \
-H "Authorization: Bearer <your key from Dashboard → Developers>"Verify by recomputing the HMAC over the raw body (constant-time compare, reject timestamps older than ~5 minutes) and reject unsigned requests — while still accepting your existing customers' API keys.
Failure semantics
Payment is verified first, your endpoint is called, and funds settle only when you respond with HTTP < 400. A wallet is never silently charged for a failed request:
| Condition | Agent sees | Charged? |
|---|---|---|
| Upstream 4xx/5xx | Same status relayed | No — same authorization retryable |
| No response headers within 30 s | 504 | No — retryable |
| Reusing an authorization after success | 409 | Each authorization pays for one successful call |
Responses stream end-to-end (SSE and LLM token streams included); the first byte reaches the agent after settlement. upto usage must be declared in headers before the body starts.
Test it end-to-end
- Create a payment link on a testnet (e.g.
base_sepolia) with the dashboard in test mode curlyour x402 URL — you should see the 402 payment instructions- Pay it like a buyer would: any x402-capable client funded with testnet USDC from Circle's faucet
- Confirm the payment appears in your dashboard and the call reached your API signed