x402 Pay-per-call
x402 (HTTP 402 Payment Required) turns Pry into a crypto pay-per-call
API — no account, no subscription, no API key. Clients pay USDC/USDT per
call directly from a wallet, and AI agents can pay automatically.
Enable it with:
PRY_X402_ENABLED=true
PRY_X402_PAY_TO=0x... # or set via gopass: gopass insert -m pry/x402_wallet
PRY_X402_FACILITATOR=https://x402.org/facilitator # or your own facilitator
How x402 works
- Client calls a paid endpoint without a payment → Pry responds
402 Payment Requiredwith aPAYMENT-REQUIREDheader (Base64-encodedPaymentRequiredJSON: wallet, amount, asset, facilitator). - Client pays — sends USDC/USDT (or native asset) to the receiving wallet on the configured chain.
- Client submits the tx to
POST /v1/x402/paywith thetx_hash. - Pry verifies the transaction on-chain (via the facilitator router, or
EIP-7702 self-verify), then returns an access token (
payment_id). - Client replays the token with the
X-Payment-Idheader until it expires (PRY_X402_PAYMENT_TTL, default 3600s).
The x402 v1 spec is implemented per
github.com/coinbase/x402. The middleware
reads the PAYMENT-SIGNATURE header (Base64-encoded JSON of the signed
payment) for facilitator flow, and issues the PAYMENT-REQUIRED header on
402s.
Payment headers
| Header | Direction | Meaning |
|---|---|---|
PAYMENT-REQUIRED | 402 response | Base64-encoded PaymentRequired body (wallet, amount, asset, facilitator) |
PAYMENT-SIGNATURE | request | Base64-encoded JSON of the signed payment (facilitator flow) |
X-Payment-Id | request | Access token from /v1/x402/pay — replay until TTL expires |
X-Batch-Payment-Id | request | Access token for a batch payment covering multiple operations |
GET /v1/x402/pricing
Get the authoritative price list for all paid operations.
curl http://localhost:8005/v1/x402/pricing
Response (200): per-operation prices in USD:
{
"scrape": {"price_usd": 0.001, "description": "Single URL scrape"},
"crawl": {"price_usd": 0.01, "description": "Crawl up to 10 pages"},
"extract": {"price_usd": 0.005, "description": "Structured extraction"},
"monitor": {"price_usd": 0.02, "description": "Create scheduled monitor"},
"llm_call": {"price_usd": 0.01, "description": "LLM extraction call"},
"template_execute": {"price_usd": 0.002, "description": "Execute scraper template"},
"bulk_crawl": {"price_usd": 0.10, "description": "Crawl up to 1000 pages"},
"browser_automation":{"price_usd": 0.05, "description": "Browser automation"},
"pdf_extract": {"price_usd": 0.01, "description": "PDF table extraction"},
"ocr_extract": {"price_usd": 0.005, "description": "Image OCR"},
"schema_extract": {"price_usd": 0.002, "description": "Schema.org/JSON-LD extraction"}
}
The server is authoritative — client-supplied underpayment is rejected.
validate_client_amount refuses any amount below the server price for the
operation. Unknown operations are not gated.
Full pricing table (as shipped)
| Operation | Price (USD) | Description |
|---|---|---|
scrape | $0.001 | Single URL scrape |
crawl | $0.01 | Crawl up to 10 pages |
bulk_crawl | $0.10 | Crawl up to 1000 pages |
extract | $0.005 | Structured extraction |
schema_extract | $0.002 | Schema.org / JSON-LD extraction |
llm_call | $0.01 | LLM extraction call |
monitor | $0.02 | Create scheduled monitor |
browser_automation | $0.05 | Browser automation |
pdf_extract | $0.01 | PDF table extraction |
ocr_extract | $0.005 | Image OCR |
template_execute | $0.002 | Execute scraper template |
template_batch_execute | $0.01 | Execute up to 20 template items |
graphql_query | $0.003 | GraphQL query execution |
POST /v1/x402/payment
Create a payment request for a paid operation. Returns payment details (wallet, amount, asset) for the client to pay.
Request body:
| Field | Type | Description |
|---|---|---|
operation | string | Required. Operation being paid for (e.g. scrape) |
metadata | object | Optional metadata |
Response (200): { "wallet": "...", "amount": 0.001, "asset": "USDC", "facilitator": "...", ... }
POST /v1/x402/require-payment
Generate a 402 Payment Required response for a paid endpoint.
Request body: same as /v1/x402/payment (operation, optional metadata).
Response (402): spec-compliant 402 with the PAYMENT-REQUIRED header.
POST /v1/x402/pay
Process an x402 payment and get an access token.
Flow: user gets 402 from a paid endpoint → sends USDC to the wallet in the
402 response → calls this endpoint with the tx_hash → Pry verifies the
transaction through the facilitator router → returns an access token
(payment_id) for the X-Payment-Id header.
Request body:
| Field | Type | Default | Description |
|---|---|---|---|
operation | string | — | Required. Operation paid for |
tx_hash | string | — | Required. On-chain transaction hash |
payer_wallet | string | — | Required. Payer wallet address |
network | string | — | Chain (e.g. base, solana, ethereum) |
asset | string | — | Asset (USDC/USDT/native) |
amount_usd | number | 0.0 | Paid amount in USD |
Response (200): { "payment_id": "...", "expires_at": "...", ... }
POST /v1/x402/verify
Verify a payment has settled on-chain via the facilitator router.
Request body:
| Field | Type | Description |
|---|---|---|
payment_id | string | Required. Payment ID from /v1/x402/pay |
tx_hash | string | Required. Transaction hash |
network / asset / amount_usd | — | Optional verification context |
Batch payments
For multi-operation calls (e.g. a crawl that triggers many extractions), use batch payments to pay once:
| Endpoint | Purpose |
|---|---|
POST /v1/x402/batch-payment | Create a single x402 payment covering multiple operations → returns a PaymentRequired body with the combined amount |
POST /v1/x402/batch-verify | Verify the on-chain payment for a batch and mark it paid → returns X-Batch-Payment-Id |
Supported assets & chains
x402 supports USDC, USDT, and native assets on:
Base, Solana, Ethereum, Polygon, Arbitrum, Optimism, BNB, Avalanche
(plus Base Sepolia for testing). Canonical ERC-20 addresses per chain are
validated during EIP-7702 self-verify. Default asset: USDC
(PRY_X402_ASSET).
EIP-7702
Pry supports EIP-7702 self-verify: instead of relying solely on a facilitator, verification can read the canonical token addresses and RPC endpoints directly (public defaults, overridable via env) to confirm the payment transaction on-chain. EIP-7702 allows EOAs to delegate account code, which the x402 flow leverages for cheap, facilitator-independent settlement verification.
Facilitators supported: coinbase, payai, cloudflare, eip-7702 — with a
smart router that auto-falls back to the next available facilitator.
Turning the API into revenue
x402 is one of three monetization lanes (see Pricing & Monetization):
- Self-hosted free — run Pry yourself, MIT core. No per-call fees.
- x402 pay-per-call — enable
PRY_X402_ENABLED=true, pointPRY_X402_PAY_TOat your wallet, and every scrape/crawl/extract earns micropayments from AI agents and bots. Prices above are defaults; the pricing table lives inx402.pyand is served by/v1/x402/pricing. - Hosted subscription — the managed service at pry.dev with Pro/Team plans.
AI agents integrate automatically through the
MCP server — pry_x402_pricing is one of the built-in
MCP tools.
:::warning Dev-only bypass
PRY_X402_OFFLINE=true makes every verify succeed without a facilitator —
it requires DEBUG=true (or PRY_DEBUG=true) and must never be enabled in
production.
:::
Next steps
- Pricing & Monetization — the three lanes
- MCP Integration — AI agents pay automatically