Manual x402 client flow (Python)
This page walks through the x402 v2 client handshake in Python withoutx402.http.clients wrappers. It is an advanced protocol reference, not a complete
copy-and-run client: signing, policy validation and recovery must be implemented
separately. The signing snippets deliberately contain placeholders.
For production youโll usually use the httpx or requests quickstarts; this tutorial is for agents or environments that need a minimal, dependency-light implementation or want to understand the protocol step by step.
1. Request the resource
Send a normal GET (or other method) to the protected URL. No special headers yet.2. Handle 402 and decode PAYMENT-REQUIRED
If the server requires payment, it returns 402 Payment Required and puts the payment options in the PAYMENT-REQUIRED header (base64-encoded JSON). This walkthrough stops for any other status. In an application, handle that original response without continuing to payment creation. Decoding JSON alone does not validate untrusted payment requirements.3. Choose an accepted option
Before selecting, validate the message at runtime: version 2, expected resource and recipient, supported exact scheme/network/asset, positive atomic-unit amount within your spending cap, supported transfer method/payment flow and a bounded timeout. Network-prefix matching alone is not spending authorization. The example below assumes that validation and policy decision have already producedapproved_network, approved_asset, approved_recipient and max_amount_atomic.
Keep caps in integer atomic units, never floating-point token amounts.
4. Build the payment payload
For the EIP-3009 variant of exact EVM, produce the authorization and sign its correct EIP-712 domain/types. Do not use this shape for other transfer methods. The outer v2 envelope hasaccepted, with scheme/network nested inside it;
it does not use the old top-level scheme/network layout. Preserve the chosen
requirement, resource and advertised extensions. See x402 Reference.
You need a signer (e.g. eth_account or web3) to produce the signature and authorization fields. Example shape (simplified; real code must use correct domain, types, and signing):
Solana (exact scheme)
For an approved Solana exact option, construct a partially signed transaction with a compatible SDK. Compute-budget limits and optional instruction support depend on the SDK and facilitator policy; they are not universal constants. Validate network, mint, amount, recipient, fee payer and the complete instruction set before signing. Do not add or change transaction instructions after signing. You need a Solana SDK (e.g.solders or solana-py) to build and sign the transaction. The payment payload is JSON with the transaction in payload.transaction as base64:
5. Resend the request with PAYMENT-SIGNATURE
Send the same request again (same URL and method), this time adding the PAYMENT-SIGNATURE header. Do this only after producing a real signature under your spending policy; the placeholders above are not payable. Preserve any original request body and required application headers. Do not forward payment authorization to redirects.6. Parse the response and PAYMENT-RESPONSE
Inspect the HTTP status and any PAYMENT-RESPONSE settlement details separately. An HTTP success alone is not proof of settlement. Decode an available settlement header even on an error response, and validate its fields before using it.settlement_pending is not a confirmed failure.
Retain the original request/payment identifiers and follow
capacity and recovery guidance.
Do not automatically create a fresh payment or infer finality from decoded JSON.
Summary
For exact field names, types, and facilitator usage, see the x402 Reference. For a ready-made client, use the httpx or requests quickstarts.
Need help?
Join our Community
Have questions or want to connect with other developers? Join our Discord server.

