x402
The standard payment flow — challenge, pay, receipt, repeat. USDC on Base, EIP-3009, no accounts.
Tollbridge uses the standard x402 flow — no custom payment protocol. Everything on the wire
is x402 v2: scheme exact, EIP-3009 transferWithAuthorization over USDC on Base
(eip155:8453).
No account. No API key. Your agent holds its own USDC and pays per call, directly to the settlement address published in the challenge. There is nothing to register, nothing to prepay, and nothing to revoke but your own key.
The standard flow: challenge → pay → receipt → repeat
- Challenge. Call a paid endpoint without payment → HTTP
402with a base64PAYMENT-REQUIREDheader describing the requirements (scheme,network,asset,amount— derived from PRICING,payTo, EIP-3009extra). - Pay. Sign the EIP-3009
transferWithAuthorizationauthorization and retry with a base64PAYMENT-SIGNATUREheader. - Receipt. On success the response carries the settlement receipt in the base64
PAYMENT-RESPONSEheader ({ success, transaction, network, payer }). - Repeat. Every call is independent — pay per decision, per surface, as often as needed.
Replayed payments (one-time EIP-3009 nonce) are rejected with
402 PAYMENT_REPLAYED.
# 1) get the challenge
curl -i https://api.tollbridge.app/v1/decisions \
-H 'content-type: application/json' \
-d '{"asset":"BTC","question_id":"S06_funding_anomaly"}'
# → 402, PAYMENT-REQUIRED: <base64>
# 2) sign the requirements with an x402 client (EIP-3009 USDC on Base) and retry
# (any x402 SDK performs steps 1–3 automatically)
curl -i https://api.tollbridge.app/v1/decisions \
-H 'content-type: application/json' \
-H "PAYMENT-SIGNATURE: <base64 payment payload>" \
-d '{"asset":"BTC","question_id":"S06_funding_anomaly"}'
# → 200 with PAYMENT-RESPONSE receiptVerify is read-only (signature/balance/simulation); settlement happens only after the resource handler succeeds — the authorization flow means the client is uncharged when a handler fails.
Security properties
- The client defensively verifies the challenge before signing: expected network
(
eip155:8453), expected asset (the PRICING USDC mint), schemeexact, well-formed positive integer amount within an optionalmaxAmountAtomiccap. Hostile challenges are refused client-side with zero signed retries. - One-time nonces: replayed payments are rejected
402 PAYMENT_REPLAYED(enforced at rest by unique constraints on(network, nonce)and(network, transaction)). - The server never talks to your wallet; you never talk to the facilitator — verify/settle are the resource server's business.
Agent examples
TypeScript agent (automatic payment)
import { Tollbridge } from '@tollbridge/sdk-typescript';
import { account } from './wallet';
const agent = new Tollbridge({
baseUrl: 'https://api.tollbridge.app',
x402: { signer: account, maxAmountAtomic: '1000000' }, // $1 entry tier — raise for $2 / $5
});
// The SDK runs challenge → verify → sign → retry → receipt automatically:
const decision = await agent.decision({ asset: 'BTC', question_id: 'S06_funding_anomaly' });
decision.payment; // { success, transaction, network, payer }TypeScript agent (decide-then-pay)
import { Tollbridge, PaymentRequiredError } from '@tollbridge/sdk-typescript';
const toll = new Tollbridge({ baseUrl: 'https://api.tollbridge.app' });
try {
await toll.decision({ asset: 'BTC', question_id: 'S06_funding_anomaly' });
} catch (err) {
if (err instanceof PaymentRequiredError) {
// err.challenge.x402Version === 2
// err.requirements.amount / .payTo / .asset — the agent decides whether to pay.
}
}MCP agent
Over MCP the payment rides the tool-call _meta (or the HTTP header fallback) — see
the MCP payment semantics.
Economics
Per-call pricing keeps the surface honest for agents: no subscriptions to manage, no keys to rotate, no account to breach. The full table (generated from the single price source) lives on Pricing; running a decision starts at $1 (1,000 credits — the entry tier), your first 3 entry-tier questions per payer address are free, and identical inputs under the same policy version are re-served, never double-billed as new decisions.