# 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.

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

`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](docs/agent-wallets), 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.

<Note>
  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](docs/alchemy-for-agents).
</Note>

## How it works

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](https://www.x402.org/). 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.

## Before you begin

* Install the CLI: `npm i -g @alchemy/cli@latest`
* For session signing, run `alchemy auth` and connect an [Agent Wallet session](docs/agent-wallets) with `alchemy wallet connect --mode session`
* Fund the [payment path](#how-payment-schemes-work) 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.

<Tip>
  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.
</Tip>

## Decode a quote with --estimate

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

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

An abbreviated human-readable result looks like:

```text
  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.

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

## Authorize payments: cap or confirm

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:

  ```bash
  alchemy --json x402 request https://nano.blockrun.ai/api/v1/pm/matching-markets/pairs --yes
  ```

  ```json
  {
    "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:

```text
Cheapest acceptable option costs 0.005 USDC on eip155:137, above --max-payment 0.004.
```

| Invocation | What happens |
|---|---|
| Any mode with `--max-payment <usdc>` | The cap authorizes payment without a confirmation prompt |
| Interactive terminal without a cap | A prompt asks you to confirm the exact quote |
| Non-interactive mode without a cap | The command exits without paying |

<Warning>
  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.
</Warning>

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.

## Make a paid request

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

<Steps>
  <Step title="Check funding">
    Confirm your signer and, for Circle Gateway payments, your Gateway balance:

    ```bash
    alchemy wallet status
    alchemy x402 balance
    ```
  </Step>
  <Step title="Estimate first">
    Decode the quote before paying anything:

    ```bash
    alchemy x402 request https://api.example.com/paid-endpoint --estimate
    ```
  </Step>
  <Step title="Pay with a cap">
    ```bash
    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`:

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

  </Step>
  <Step title="Read the receipt">
    A successful paid request returns the resource plus a receipt. This abridged, illustrative Gateway receipt uses placeholder addresses and a synthetic Gateway transfer ID:

    ```json
    {
      "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.
  </Step>
</Steps>

### Request flags

| Flag | Description |
|---|---|
| `-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 |
| `--estimate` | Decode the payment quote without signing or paying |
| `--max-payment <usdc>` | Maximum USDC to pay, e.g. `0.01`. Required for non-interactive payment. |
| `-y, --yes` | Skip 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.

## How payment schemes work

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`) |
|---|---|---|
| Settlement | Batched nanopayments through Circle Gateway | EIP-3009 by default, or Permit2 when the server advertises it |
| Funding source | A prefunded USDC balance in Circle Gateway | For capped payments, USDC held in the signing wallet; an uncapped interactive request uses the quoted asset |
| Settlement gas | None | None; setting a Permit2 allowance may require gas unless the provider sponsors it |
| Best for | Repeated micro-payments, down to fractions of a cent | One-off payments with no Gateway setup |
| Prerequisite | Deposit before paying and top up as needed | The 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.

## Fund Circle Gateway for batched payments

Circle Gateway payments draw on USDC you deposit in advance using [Circle's own deposit flow](https://developers.circle.com/gateway/nanopayments/howtos/x402-buyer) — the Alchemy CLI does not perform deposits. Top up the balance as needed.

<Warning>
  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.
</Warning>

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

```bash
alchemy x402 balance
```

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

```bash
alchemy --json x402 balance --address 0x1111111111111111111111111111111111111111
```

An abbreviated illustrative response looks like:

```json
{
  "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 it from agents and scripts

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

```bash
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`:

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

An abbreviated estimate response looks like:

```json
{
  "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
  }
}
```

<Accordion title="JSON envelope reference">
  Every completed non-estimate `x402 request` response — paid or free — shares one shape on stdout:

  ```json
  {
    "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](#make-a-paid-request). `--estimate` uses a different shape: `payment.required`, `payment.options` (every option the server offered, each annotated `eligible`), `payment.selected`, and `payment.cap`.
</Accordion>

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](#troubleshooting) 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`.

## Security and trust model

* 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](docs/agent-wallets).

## Troubleshooting

<AccordionGroup>
  <Accordion title="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.
  </Accordion>
  <Accordion title="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.
  </Accordion>
  <Accordion title="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.
  </Accordion>
  <Accordion title="Circle Gateway balance too low">
    Gateway payments need funds already deposited to Circle Gateway. Check `alchemy x402 balance` and [top up through Circle](#fund-circle-gateway-for-batched-payments) — 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.
  </Accordion>
  <Accordion title="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.
  </Accordion>
</AccordionGroup>

## Next steps

* [Agent Wallets](docs/agent-wallets)
* [Alchemy CLI x402 reference](docs/alchemy-cli#x402)
* [Wallet auth for Alchemy APIs](docs/alchemy-for-agents) — the other x402: authenticating and paying Alchemy itself
* [x402.org](https://www.x402.org/)
* [Circle Gateway documentation](https://developers.circle.com/gateway/nanopayments/howtos/x402-buyer)