The flow
The quote
When you hit a paid endpoint without payment, the server replies:payment-required:
| Field | Meaning |
|---|---|
scheme | Always exact — pay the precise amount, no upto/up-to-N variants |
network | CAIP-2 chain ID. eip155:8453 = Base mainnet · eip155:84532 = Base Sepolia |
asset | USDC contract on the named chain |
amount | Cost in USDC base units (6 decimals). 100000 = $0.10 |
payTo | Wallet that collects the payment |
maxTimeoutSeconds | After this many seconds the quote can’t be settled |
extra | EIP-712 name + version for the USDC contract — feed into your signer |
The proof
You sign a EIP-3009TransferWithAuthorization
typed-data structure with your private key:
X-PAYMENT request header (base64
of the full PaymentPayload JSON — see the
Coinbase x402 SDK for the precise
shape).
Replay protection
Thenonce field is your replay-protection key. Aegis writes one
row to x402_payments per verified proof, with a UNIQUE(payer, nonce)
constraint. A re-sent X-PAYMENT header gets rejected with 402.
Generate a fresh nonce per request (e.g. os.urandom(32).hex()).
Settlement
The facilitator (default:https://x402.org/facilitator, hosted by
Coinbase) calls USDC.transferWithAuthorization(…) on your behalf.
The transaction lands on Base; the resulting tx_hash is recorded in
our audit log and you can verify it on
Basescan (or
sepolia.basescan.org for testnet).
Networks
Today Aegis settles on Base only. Multi-chain settlement (Polygon, Arbitrum) is on the roadmap — see Networks.Errors
| Status | Meaning |
|---|---|
402 | Missing / invalid / expired / replayed proof. Header payment-required carries a fresh quote |
400 | Malformed {address} or {chain} path parameter |
429 | Rate-limited (60 paid calls/min per IP) |
5xx | Aegis-side failure — payment was settled, but our backend errored. See error codes |

