Agent-pay (x402)
Let autonomous agents pay per request. No API keys, no advance top-ups, no human in the loop — just HTTP and a signed payment blob. This is MeterCall's implementation of the x402 pattern.
Why x402 #
API keys were designed for trusted, long-lived clients. Agents are the opposite — they spin up, make a few calls, spin down, and often don't know what they'll call until they're running. Instead of provisioning a key for each ephemeral agent, we resurrect the 402 Payment Required status code and pay per call with a signed header.
- No account creation.
- No stored card on file.
- The agent's wallet signs each payment, so no credentials ever leak.
- Settlement is either off-chain (USDC escrow) or on-chain (receipt relayed to Base).
The 402 handshake #
- Agent calls
POST /v1/module/:slug/callwith no payment. - MeterCall returns
402 Payment Requiredwith price, nonce, and pay-to address. - Agent signs a payment blob (see next section) and retries with
X-Payment. - MeterCall verifies the signature, debits the agent's wallet, runs the module, and returns
200with the result and a signed receipt.
// 1. First request — no payment
POST /v1/module/weather/call
Accept: application/json
// 2. Response
HTTP/1.1 402 Payment Required
WWW-Authenticate: X-Payment realm="metercall"
X-Price-Cents: 1
X-Pay-To: 0xMeterCallEscrow...
X-Nonce: n_01HY...
X-Accepted-Methods: usdc-base,credits
// 3. Retry with X-Payment
POST /v1/module/weather/call
X-Payment: eyJ2ZXIiOiJ4NDAyLjEi...
The X-Payment header #
Base64-url-encoded JSON. Canonical shape:
{
"ver": "x402.1",
"nonce": "n_01HY...",
"method": "usdc-base",
"pay_to": "0xMeterCallEscrow...",
"amount": "0.010000",
"payer": "0xAgentAddress...",
"expires_at": "2026-04-16T19:20:00Z",
"signature": "0xabc123..."
}
The signature is over the canonical JSON (keys sorted, no whitespace) with everything except the signature field itself. Use EIP-191 for EVM chains, Ed25519 for native MeterCall agents.
Verification #
When we receive an X-Payment blob we check, in order:
- The nonce is one we issued in the last 60 seconds and hasn't been used.
- The signature is valid for the declared
payer. - The
amountis at leastX-Price-Centsfor the target module. - The payer has that much available — either in their MeterCall wallet or in the on-chain allowance they've pre-approved to our escrow.
Any failure returns 402 with a X-Error header explaining which check failed.
Settlement #
By default, MeterCall batches on-chain settlement every 5 minutes. Off-chain (MeterCall-credit) payers settle instantly. The agent receives a settled receipt either way:
{
"call_id": "call_01HY...",
"amount": "0.010000",
"chain": "base",
"tx": "0x5b...",
"block": 12839402,
"sig": "ed25519:..."
}
Agent pays agent #
The same header works for agent-to-agent calls. If agent A is calling a module owned by agent B, MeterCall splits the payment: 80% to agent B, 20% to MeterCall as the toll. Configure splits at /api/agent/build when publishing.
agentPay() helper that handles the 402 response, signs the blob, and retries automatically. See SDKs.