Payments with x402
Pay for an HTTP resource per request with the open x402 protocol on Tenzro Network 1: read the 402 challenge, send a signed credential, check the receipt, and sell your own paid routes.
x402 is an open protocol that puts the HTTP 402 Payment Required status to work. A client asks for a resource, the server answers with a price, the client retries with a signed payment, and the server returns the resource with a receipt. There are no accounts, subscriptions or API keys, which makes it a good fit for agents and machines that buy one call at a time. Every paid route on a Tenzro node, including the OpenAI-compatible inference APIs, accepts x402.
Prerequisites
- A wallet with TNZO or stablecoins: a passkey wallet from the console, or a delegated agent wallet from Build an AI payment agent.
curlandjq.- Background: x402.
1. Ask for a paid resource
Call a paid route with no credential. Here it is chat completions:
curl -si https://rpc.tenzro.xyz/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"qwen3.6-35b-a3b","messages":[{"role":"user","content":"hello"}]}'The node answers with a challenge. The WWW-Authenticate header carries it in the IETF Payment auth-scheme form, and the body carries the same challenge as JSON for clients that want the details:
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment id="ch_7k9m2p4q8r", realm="/v1/chat/completions", method="x402", intent="charge", request="eyJjaGFsbGVuZ2VfaWQiOi...", expires="2026-10-02T12:35:00Z"
Payment-Required: true
Content-Type: application/json{
"challenge_id": "ch_7k9m2p4q8r",
"protocol": "x402",
"resource": "/v1/chat/completions",
"amount": 100,
"asset": "USDC",
"recipient": "0x<provider-wallet>",
"chain": "<caip2>",
"expires_at": "2026-10-02T12:35:00Z",
"extra": { "scheme": "tenzro-hybrid" }
}amount is in the smallest unit of asset. extra.scheme names how the payment will be verified.
2. See which schemes the node verifies
curl -s https://rpc.tenzro.xyz \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tenzro_listX402Schemes","params":[]}'| Scheme | How the payment is authorised |
|---|---|
tenzro-hybrid | A hybrid classical and ML-DSA-65 signature from the payer's account over the canonical payment message. Quantum-safe. |
exact-eip3009 | An EIP-3009 transferWithAuthorization for stablecoins on EVM chains. |
permit2 | A signed Permit2 transfer for ERC-20 tokens. |
erc7710 | Redemption of an ERC-7710 delegation from a smart account. |
3. Send a signed credential
The client answers the challenge with a credential that names the challenge, the payer, the amount and the asset, signed by the payer's key. With the tenzro-hybrid scheme the credential carries both signatures and the payer's ML-DSA-65 public key. Your wallet produces the signatures inside its hardware; the credential never contains a private key.
{
"credential_id": "cr_2f61c0",
"challenge_id": "ch_7k9m2p4q8r",
"protocol": "x402",
"payer_did": "did:tenzro:machine:<controller>:<agent-id>",
"payer_address": "0x<agent-wallet>",
"amount": 100,
"asset": "USDC",
"signature": [ "...classical signature bytes..." ],
"pq_signature": [ "...ML-DSA-65 signature bytes..." ],
"pq_public_key": [ "...ML-DSA-65 public key bytes..." ],
"extra": { "scheme": "tenzro-hybrid" }
}Base64-encode the JSON and retry the same request with it in the Authorization header:
CRED=$(base64 -w0 < credential.json)
curl -si https://rpc.tenzro.xyz/v1/chat/completions \
-H 'content-type: application/json' \
-H "Authorization: x402 $CRED" \
-d '{"model":"qwen3.6-35b-a3b","messages":[{"role":"user","content":"hello"}]}'Before it verifies the payment, the node checks the payer's identity: a suspended or revoked DID is refused, and a delegated agent's payment must fit its delegation scope (amount, daily cap, protocol and chain).
In application code you do not build credentials by hand. The @tenzro/ai SDK does steps 1 to 3 for every call when you pass a signer and payment: { protocol: "x402", maxPrice }; see Build an AI payment agent.
4. Read the receipt
On success the node settles the payment, serves the request and adds an X-PAYMENT-RESPONSE header: base64-encoded JSON describing the settlement.
curl -si ... | grep -i '^x-payment-response' | cut -d' ' -f2 | base64 -d | jq .Receipts are also retrievable by id, which is useful for reconciliation:
curl -s https://rpc.tenzro.xyz \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tenzro_getPaymentReceipt","params":[{"receipt_id":"<receipt-id>"}]}'A receipt records the protocol, challenge and credential ids, amount, asset, chain, the settlement transaction and the time, plus the chain of principals behind the payer: for an agent, the human or organisation that controls it.
5. Handle failures
| Response | Meaning | What to do |
|---|---|---|
402 with a new challenge | The challenge expired or no credential was sent | Pay the new challenge |
400 invalid_credential | The header could not be decoded or parsed | Check the base64 and the JSON fields |
401 verification_failed | The signature, amount or payer did not verify, or the payer's identity or delegation scope refused it | Sign with the key bound to payer_address, pay the exact amount, or raise the agent's limits |
Retrying a request after a network error must not pay twice. Derive a stable idempotency id for the offer and reuse it on every retry:
tenzro x402 payment-id --payer-did did:tenzro:machine:<controller>:<agent-id> \
--requirement-file challenge.json --rpc https://rpc.tenzro.xyz
# pay_<hex>6. Sell your own resource over x402
Any paid route you host on Tenzro can charge over x402. To let buyers and agents find it, publish a listing in the network's discovery catalog. Publishing is an owner call signed by the seller's account.
tenzro x402 register-resource \
--seller-did did:tenzro:human:<your-id> \
--resource https://api.example.org/v1/weather \
--scheme tenzro-hybrid \
--network <caip2> \
--asset USDC \
--pay-to 0x<your-wallet> \
--max-amount-required 2000 \
--description "Hourly weather by coordinates" \
--tags weather,data \
--rpc https://rpc.tenzro.xyzBuyers browse listings with the CLI or the web API:
tenzro x402 discover-resources --asset USDC --tags weather --rpc https://rpc.tenzro.xyz
curl -s 'https://api.tenzro.xyz/discovery/resources?asset=USDC&tags=weather&limit=20'Next steps
- Sessions and streamed billing: Payments with MPP.
- Stablecoins end to end: Pay for inference in stablecoins.
- Protocol reference: x402.