Tollbridge Docs

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

  1. Challenge. Call a paid endpoint without payment → HTTP 402 with a base64 PAYMENT-REQUIRED header describing the requirements (scheme, network, asset, amount — derived from PRICING, payTo, EIP-3009 extra).
  2. Pay. Sign the EIP-3009 transferWithAuthorization authorization and retry with a base64 PAYMENT-SIGNATURE header.
  3. Receipt. On success the response carries the settlement receipt in the base64 PAYMENT-RESPONSE header ({ success, transaction, network, payer }).
  4. 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 receipt

Verify 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), scheme exact, well-formed positive integer amount within an optional maxAmountAtomic cap. 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.

On this page