Skip to Content
For AgentsX402 Payment Flow

X402 Payment Flow

The X402 protocol  uses HTTP status code 402 (“Payment Required”) as a payment negotiation mechanism. Here’s how it works under the hood.

If you use the x402-fetch library, all of this is handled automatically. This page explains what happens behind the scenes.

Initial request

Your agent sends a POST request to the endpoint:

curl -X POST https://402claw.cloud/api/x402/nano-banana \ -H "Content-Type: application/json" \ -d '{"prompt": "A photorealistic cat riding a skateboard"}'

Receive 402 challenge

The server responds with HTTP 402 Payment Required and includes payment details in the response body:

{ "error": "X402: Payment Required", "accepts": [ { "scheme": "exact", "network": "base", "asset": "USDC", "amount": "50000", "recipient": "0x1234...abcd" } ], "x402Version": 1 }

The amount is in USDC’s smallest unit (6 decimals), so 50000 = $0.05 USDC.

Sign EIP-712 payment

Your agent creates an EIP-712 typed data signature using its wallet private key. This signature proves the agent authorizes the payment without making an on-chain transaction.

import { createWalletClient, http } from 'viem' import { privateKeyToAccount } from 'viem/accounts' import { base } from 'viem/chains' const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY) const client = createWalletClient({ account, chain: base, transport: http() }) // The x402-fetch library handles this signing automatically const signature = await client.signTypedData({ // ... EIP-712 typed data from the 402 response })

Retry with payment header

The agent retries the original request with the signed payment in the X-PAYMENT header:

curl -X POST https://402claw.cloud/api/x402/nano-banana \ -H "Content-Type: application/json" \ -H "X-PAYMENT: <base64-encoded-signed-payment>" \ -d '{"prompt": "A photorealistic cat riding a skateboard"}'

Receive task ID

If the payment signature is valid, the server creates a generation task and returns:

{ "success": true, "taskId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "statusUrl": "/api/task/a1b2c3d4-e5f6-7890-abcd-ef1234567890", "message": "Generation started. Poll statusUrl for results." }

Poll for results

Poll the status URL every 2 seconds until you get a terminal status:

curl https://402claw.cloud/api/task/a1b2c3d4-e5f6-7890-abcd-ef1234567890

Processing:

{ "taskId": "...", "status": "processing", "elapsed": 5 }

Success:

{ "taskId": "...", "status": "success", "resultUrl": "https://cdn.example.com/generated-image.png", "elapsed": 12 }

Failed:

{ "taskId": "...", "status": "failed", "error": "Generation failed after 3 retries", "code": "GENERATION_FAILED", "retries": 3, "elapsed": 45 }

Important Notes

  • No on-chain transaction needed — The EIP-712 signature authorizes payment without gas fees. The facilitator settles later.
  • One payment per request — Each generation requires its own payment. Payments cannot be reused.
  • Async by default — Results are not returned inline. You must poll the status endpoint.
  • Auto-retry — The server automatically retries failed generations up to 3 times before marking as failed.

Rate Limits

EndpointLimit
POST /api/x402/*10 requests per 60 seconds per IP
GET /api/task/*5 requests per second per IP
Last updated on