Skip to content
Alchemy Logo

x402 payments

Pay compatible x402 v2 APIs in USDC from the Alchemy CLI. Decode 402 Payment Required quotes, set a spend cap, pay with an Agent Wallet session, and get a payment receipt.

alchemy x402 request <url> is curl that can pay. When a compatible x402 v2 endpoint returns 402 Payment Required, the CLI selects a supported EVM payment option and applies your spend cap or asks for confirmation. It signs with your Agent Wallet session, retries the request once, and returns the resource with a payment receipt.

Automated capped payments support recognized USDC. In an uncapped interactive terminal, the CLI may also present another compatible exact-scheme asset for manual confirmation.

This command is available in @alchemy/cli 0.22.0 and later. Run alchemy help x402 for the current command surface.

This page is about paying compatible third-party x402 v2 APIs. It is not the global --x402 flag or alchemy config set x402, which use x402 gateway auth to pay for access to Alchemy APIs — see Wallet auth for Alchemy APIs.

  1. The CLI sends your request with no payment attached.
  2. If the resource is free, the server responds normally and the CLI returns it — nothing else happens.
  3. If payment is required, the server responds 402 Payment Required with a machine-readable quote (price, network, and accepted payment schemes).
  4. The CLI checks your authorization (a spend cap or your confirmation), verifies the quote, and signs the selected payment with your configured signer.
  5. The CLI retries the request with the signed payment attached and returns the resource along with a payment receipt.

This is the open x402 protocol. The CLI supports x402 v2 endpoints that offer compatible EVM exact payments, including Circle Gateway batched payments. It does not support x402 v1, Solana payment options, or other payment schemes.

  • Install the CLI: npm i -g @alchemy/cli@latest
  • For session signing, run alchemy auth and connect an Agent Wallet session with alchemy wallet connect --mode session
  • Fund the payment path the server offers. Capped payments use wallet-held USDC for direct settlement or a Gateway balance. An uncapped interactive quote for another asset requires that asset in the signing wallet.

After installing the CLI, you can use --estimate without signing in, configuring a signer, or funding USDC. It decodes the quote and pays nothing, so it's the best first command to run against an unfamiliar x402 URL.

--estimate sends the request, decodes the 402 quote, and prints it. It never signs or pays, so it's always free to run.

alchemy x402 request https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs --estimate

An abbreviated human-readable result looks like:

  Provider  nano.blockrun.ai
  Resource  Get all active exact-matched market pairs
  Scheme    exact (Circle Gateway batched)
  Network   eip155:137 (polygon-mainnet)
  Amount    0.005 USDC
  Decision  estimate only

The full output also lists every payment option and why each one is eligible or excluded. The price, scheme, and network are set by the server and may change; this is what BlockRun advertised when this page was written.

If you see a decoded quote, the CLI handled a live 402 end to end. Nothing was signed and nothing was spent.

The CLI never pays on its own authority. Every payment needs an explicit authorization:

  • Any invocation with --max-payment <usdc>: the cap authorizes a payment at or below that amount. The CLI does not ask for another confirmation.

  • Interactive terminal without a cap: the CLI prints the exact quote and asks you to confirm before signing.

  • Non-interactive run without a cap — a script, --json, piped output, or --no-interactive — exits without paying.

  • Any non-estimate invocation with -y/--yes also requires --max-payment. The cap already suppresses confirmation, so --yes does not authorize anything beyond it. --yes without a cap fails before the request is sent:

    alchemy --json x402 request https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs --yes
    {
      "error": {
        "code": "INVALID_ARGS",
        "message": "--yes requires --max-payment <usdc> to set an explicit payment limit.",
        "retryable": false
      }
    }

A quote priced above your cap is not paid. For example, a 0.005 USDC quote with --max-payment 0.004 exits with code 9 and reports:

Cheapest acceptable option costs 0.005 USDC on eip155:137, above --max-payment 0.004.
InvocationWhat happens
Any mode with --max-payment <usdc>The cap authorizes payment without a confirmation prompt
Interactive terminal without a capA prompt asks you to confirm the exact quote
Non-interactive mode without a capThe command exits without paying

Paid requests spend real assets. For automated USDC payments, treat --max-payment as the authorization boundary and set it to the smallest value that gets the job done. In an uncapped interactive terminal, verify any non-USDC asset before confirming.

The CLI issues at most one payment authorization per command. If the paid retry comes back 402, it stops instead of signing a second payment.

The payment step below can spend real USDC. The URLs are placeholders — replace them with the x402 endpoint you're actually calling.

Confirm your signer and, for Circle Gateway payments, your Gateway balance:

alchemy wallet status
alchemy x402 balance

Decode the quote before paying anything:

alchemy x402 request https://api.example.com/paid-endpoint --estimate
alchemy --json x402 request https://api.example.com/paid-endpoint --max-payment 0.01

curl-style flags work the same way. -d sets the method to POST automatically when you don't pass -X:

alchemy x402 request https://api.example.com/reports \
  -H "content-type: application/json" \
  -d '{"query":"latest"}' \
  --max-payment 0.05 \
  -o report.json

A successful paid request returns the resource plus a receipt. This abridged, illustrative Gateway receipt uses placeholder addresses and a synthetic Gateway transfer ID:

{
  "url": "https://api.example.com/paid-endpoint",
  "status": 200,
  "ok": true,
  "body": { "...": "the resource you paid for" },
  "bodyEncoding": "json",
  "payment": {
    "paid": true,
    "scheme": "exact",
    "gateway": true,
    "network": "eip155:137",
    "asset": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
    "amount": "5000",
    "amountUSDC": "0.005",
    "payTo": "0x6E007731870EDe419CfB31889Cd5C4493CEcb04c",
    "payer": "0x1111111111111111111111111111111111111111",
    "transaction": "00000000-0000-4000-8000-000000000000",
    "settled": true,
    "signerAddress": "0x1111111111111111111111111111111111111111",
    "signerKind": "session",
    "recovered": true
  }
}

settled describes the settlement receipt, not the HTTP response. null means the server returned no decodable PAYMENT-RESPONSE header; the CLI does not poll for an update. false means the receipt reported a settlement failure, even if the provider returned the resource with HTTP 200. signerKind tells you whether the session or a local key signed. The transaction value is scheme-dependent: Gateway uses a transfer ID, while direct exact settlement commonly returns an EVM transaction hash.

FlagDescription
-X, --method <method>HTTP method. Defaults to POST when --data is set.
-H, --header <header>Request header as "Name: value", repeatable
-d, --data <body>Request body
-o, --output <file>Write the response body to a file
--estimateDecode the payment quote without signing or paying
--max-payment <usdc>Maximum USDC to pay, e.g. 0.01. Required for non-interactive payment.
-y, --yesSkip payment confirmation. Paid requests require --max-payment; the cap authorizes payment.
--scheme <gateway|exact|any>Filter payment options. gateway selects Circle Gateway-marked quotes, exact selects non-Gateway exact quotes, and any selects the cheapest eligible option.
--signer <session|local>Override the active signer for this request
-n, --network <id>Filter which payment networks the CLI will pay on

Run alchemy help x402 request for the current flag surface.

When you pass -d/--data without -X, the CLI uses POST. Combining -d with an explicit -X GET or -X HEAD fails before the request is sent.

A server can offer more than one way to pay. Both paths below use the x402 protocol's exact scheme; the CLI recognizes Circle Gateway options by their Gateway marker. The --scheme flag filters between those options.

With --scheme any (the default), the CLI picks the cheapest eligible option and Circle Gateway wins ties. In estimate output, eligible only means an option passed the quote-selection filters; it does not guarantee payment creation will succeed. Confirm the selected network starts with eip155: because payment support is EVM-only. The CLI does not check balances before selection or fall back after a selected option fails. If Gateway is selected but unfunded, the server also offered a non-Gateway exact option, and your wallet holds the quoted asset on that network, retry with --scheme exact.

Circle Gateway (--scheme gateway)Direct exact (--scheme exact)
SettlementBatched nanopayments through Circle GatewayEIP-3009 by default, or Permit2 when the server advertises it
Funding sourceA prefunded USDC balance in Circle GatewayFor capped payments, USDC held in the signing wallet; an uncapped interactive request uses the quoted asset
Settlement gasNoneNone; setting a Permit2 allowance may require gas unless the provider sponsors it
Best forRepeated micro-payments, down to fractions of a centOne-off payments with no Gateway setup
PrerequisiteDeposit before paying and top up as neededThe quoted asset on the payment network; Permit2 may also require an existing allowance or provider-sponsored approval

Which options are eligible depends on what the server offers and your --scheme, --network, asset, and spend-cap filters. Funding is checked later when the selected payment is created or settled.

Circle Gateway payments draw on USDC you deposit in advance using Circle's own deposit flow — the Alchemy CLI does not perform deposits. Top up the balance as needed.

Do not send USDC to the Circle Gateway contract with a plain ERC-20 transfer. Circle does not credit funds sent that way, and they cannot be recovered. Always deposit through Circle's Gateway deposit flow.

No Alchemy API key is required to check Gateway balances. Without --address, the CLI uses your active signer's address:

alchemy x402 balance

Pass --address to query without a configured signer. Add --testnet when you want to query the Gateway testnet instead:

alchemy --json x402 balance --address 0x1111111111111111111111111111111111111111

An abbreviated illustrative response looks like:

{
  "address": "0x1111111111111111111111111111111111111111",
  "environment": "mainnet",
  "token": "USDC",
  "balances": [
    { "chain": "base", "domain": 6, "balance": "0", "pendingBatch": "0" },
    { "chain": "polygon", "domain": 7, "balance": "0", "pendingBatch": "0" }
  ],
  "totalAvailable": "0"
}

Use --json --no-interactive for machine-readable automation. Estimates do not require a cap:

alchemy --json --no-interactive x402 request https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs --estimate

Any request that may pay also requires an explicit --max-payment:

alchemy --json --no-interactive x402 request https://api.example.com/paid-endpoint --max-payment 0.01

An abbreviated estimate response looks like:

{
  "url": "https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs",
  "status": 402,
  "payment": {
    "required": true,
    "x402Version": 2,
    "resource": {
      "url": "https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs",
      "description": "Get all active exact-matched market pairs",
      "mimeType": "application/json"
    },
    "options": [
      {
        "scheme": "exact",
        "network": "eip155:137",
        "asset": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
        "amount": "5000",
        "amountUSDC": "0.005",
        "payTo": "0x6E007731870EDe419CfB31889Cd5C4493CEcb04c",
        "maxTimeoutSeconds": 691200,
        "gateway": true,
        "eligible": true
      }
    ],
    "selected": { "...": "same shape as the option above" },
    "cap": null
  }
}
JSON envelope reference

Every completed non-estimate x402 request response — paid or free — shares one shape on stdout:

{
  "url": "string",
  "status": 0,
  "ok": true,
  "headers": { "content-type": "application/json" },
  "body": "parsed JSON, text, or null",
  "bodyEncoding": "json | text | base64 | file | null",
  "bodyBytes": 0,
  "payment": null
}

payment is null when no payment was required. When a payment was made, it carries paid, scheme, gateway, network, asset, amount, amountUSDC, payTo, payer, transaction, settled, signerAddress, signerKind, and recovered — see the receipt example above. --estimate uses a different shape: payment.required, payment.options (every option the server offered, each annotated eligible), payment.selected, and payment.cap.

Exit code 9 (PAYMENT_REQUIRED) covers x402 failures both before and after a payment authorization is created. Never retry it blindly; use the error message and troubleshooting guidance to determine whether a prior authorization may still settle.

A few rules for agent code:

  • Estimate before paying anything you haven't seen priced before.
  • Set --max-payment on every request that may pay. Estimates do not need one.
  • Read payment.settled, not just the HTTP status — a 200 can still carry settled: false.
  • Never retry exit code 9 blindly; follow the error message and confirm whether the prior authorization settled.

For the current command tree and error catalog, run alchemy --json --no-interactive agent-prompt.

  • The spend cap or your interactive confirmation is the only thing that authorizes a payment. Nothing in a server's response can raise it.
  • Payment quotes from servers are untrusted input. The CLI validates a quote before ever signing against it.
  • Every payment signature is verified locally, before it's sent.
  • Capped payments recognize USDC only by known per-chain asset addresses. A quote naming an unrecognized asset is rejected when --max-payment is set.
  • Without a cap, an interactive terminal may present another exact-scheme asset in base units. Verify the asset contract and amount before confirming it.
  • The CLI issues only one payment authorization per request.
  • With --signer session, your Agent Wallet session signs the payment. No private key or API key is ever exposed to the agent — see Agent Wallets.

Exit code 9 before payment

Exit code 9 covers several pre-payment failures, including a missing or insufficient cap, an invalid quote, no eligible option, and signing or funding failures. Read the error message and correct that specific cause. Set or raise --max-payment only when the message explicitly identifies the cap.

Exit code 9 after authorization

Some exit code 9 errors happen after a signed authorization was sent or released: a transport failure, another 402, or a non-2xx paid response. The payment may still settle. Do not retry until you reconcile the payment with the provider or payment rail, or you could pay twice.

No eligible payment option

The server didn't offer an option that passed the current scheme, network, asset, and cap filters. Check the options array from --estimate for each option's excludedBy reason, try --scheme any, or remove a -n/--network filter.

Circle Gateway balance too low

Gateway payments need funds already deposited to Circle Gateway. Check alchemy x402 balance and top up through Circle — never with a raw ERC-20 transfer. If the server also offers direct exact settlement and your wallet holds USDC on that network, retry with --scheme exact; the CLI does not fall back automatically.

Quote rejected as invalid

Inspect the endpoint's x402 response. The CLI rejects missing payment headers, unsupported x402 versions, unsupported payment schemes, and unrecognized assets on capped requests before signing.

Was this page helpful?