> ## Documentation Index
> Fetch the complete documentation index at: https://nevermined.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# The x402 rail

> Paying x402 services through the Router — networks, assets, schemes, and how the 402 is negotiated.

x402 is the HTTP-native payment protocol where a server answers an unpaid request with **HTTP 402** and an `accepts` array describing what it will take. The Router reads that array, picks an option it can fund, signs the payment from your custodial wallet, and hands back a credential.

You don't need the service to know anything about Nevermined. If it speaks x402, it's payable.

## What a challenge looks like

The Router supports both protocol versions and works out which one it's talking to.

<Tabs>
  <Tab title="x402 v2">
    Requirements arrive base64-encoded in a **`PAYMENT-REQUIRED`** response header. The credential goes back in a **`PAYMENT-SIGNATURE`** request header.
  </Tab>

  <Tab title="x402 v1">
    Requirements arrive in the **JSON body** of the 402. The credential goes back in an **`X-PAYMENT`** request header.

    ```json theme={null}
    {
      "x402Version": 1,
      "accepts": [
        {
          "scheme": "exact",
          "network": "base-sepolia",
          "maxAmountRequired": "1000",
          "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
          "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
          "maxTimeoutSeconds": 60,
          "extra": { "name": "USDC", "version": "2" }
        }
      ]
    }
    ```
  </Tab>
</Tabs>

In [mode B](/docs/products/catalog/router/how-it-works) you never see any of this — the Router probes, negotiates the version, and pays. You only need the shape above if you're using mode A and passing the challenge yourself as `target`.

## What's supported

|              | Supported                                                                                                 |
| ------------ | --------------------------------------------------------------------------------------------------------- |
| **Scheme**   | `exact` — an EIP-3009 `TransferWithAuthorization`, a single-use signed authorization the merchant redeems |
| **Networks** | `base` (chain `8453`) and `base-sepolia` (chain `84532`), by name or as CAIP-2 (`eip155:8453`)            |
| **Assets**   | `USDC` and `EURC` — 6-decimal stablecoins                                                                 |

Anything outside that isn't payable on this rail today: other schemes, other chains, and non-EVM networks such as Solana.

<Note>
  A **mixed-chain 402 still works** as long as one option is fundable. If a service advertises both a Solana option and a Base option, the Router skips the one it can't parse and pays the Base one. It only fails if *no* entry survives the filter — that's `400 BCK.ROUTER.0001`.
</Note>

### How an option gets chosen

Given several fundable entries, the Router filters to `scheme: "exact"` on a funded network with a funded asset, then prefers **USDC**. The asset symbol is resolved from the entry's **`asset` address**, matched against the canonical token addresses for that chain — never from `extra.name`, which is something else entirely (see below). A token the Router doesn't recognise on that chain isn't fundable, however the entry labels it.

### `extra.name` is the EIP-712 domain, not a ticker

`extra.name` and `extra.version` are the settlement token's **EIP-712 domain** — the `name()` and `version()` the token contract itself signs under, and what the payment authorization is signed against. They are frequently *not* the ticker: canonical Base-mainnet USDC signs under `"USD Coin"`, while the Base Sepolia deployment signs under `"USDC"`.

Both fields are **required**, and the Router checks them **byte for byte** against the domain it holds for that token. It signs under its own value, never one taken from the 402. A service that advertises a domain its own token does not sign under gets `400 BCK.ROUTER.0012`, with nothing signed, charged or reserved — such an authorization is unspendable anyway, so there is nothing to lose by stopping.

<Note>
  **If you're the seller:** copy `extra.name`/`extra.version` from the token contract's `name()` and `version()`, exactly. Guessing the ticker is the usual way to trip this.
</Note>

## Money and budget

Amounts are in the asset's smallest unit. USDC and EURC have 6 decimals, so:

```
1_000_000 atomic units = 1 USDC = 100 cents
    10_000 atomic units = 1 cent
```

Your Delegation cap is denominated in **cents**, so every payment is converted and **rounded up** to the next whole cent before it's checked against the cap. A payment of 5,000 atomic units (half a cent) reserves 1 cent. Sub-cent calls therefore cost you a full cent of budget each — worth knowing if you're planning a long loop of very cheap calls.

The `settlement.approxCents` field on every response tells you what the merchant charged. A [routing fee](/docs/products/catalog/router/how-it-works#the-routing-fee), when one is configured, is reserved on top of it — `fee.capChargedCents` is the total that came off your cap.

## Funding your wallet

The payment is a **pull**: your signature authorizes the merchant to take the amount from your own wallet. So the wallet must already hold that asset **on that chain** before you call.

Get the address from your Delegation's `providerPaymentMethodId` — see [step 3 of the quickstart](/docs/products/catalog/router/quickstart#3-fund-your-wallet).

<Warning>
  **On x402 the Router does not check your balance before signing.** A short wallet isn't refused up front: the credential is minted, your Delegation budget is reserved, and the shortfall only appears when the merchant attempts the transfer on-chain. The payment then lands as `Failed` — and the reserved **merchant** leg is **not** given back. (`402 BCK.ROUTER.0009` is an [MPP-only](/docs/products/catalog/router/rails-mpp#funding-your-wallet) error; this rail never raises it.)

  Only a routing fee reserved on top can be credited back, and only on [the closed list of paths that release one](/docs/products/catalog/router/how-it-works#when-a-fee-is-not-collected) — never the merchant leg.

  Fund for the merchant's amount **plus** any [routing fee](/docs/products/catalog/router/how-it-works#fund-for-the-amount-plus-the-fee) — the fee is a second transfer from the same wallet, so the quoted price alone doesn't cover both.
</Warning>

The asset to send is the one the service's 402 advertises — `USDC` or `EURC`, 6 decimals, on the network in that entry. Base mainnet USDC is `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`.

<Warning>
  `base` is **Base mainnet** and moves real funds; `base-sepolia` is the testnet. **Which of them your deployment will fund is decided by the environment you are pointed at, not by the service.** A sandbox deployment funds testnets only and a live deployment funds mainnet only — that split is the real-money firewall and an operator cannot widen it. If you call a mainnet service from sandbox, no entry survives the filter and you get `400 BCK.ROUTER.0001`. Read `settlement.network` on the response to be sure what just happened.
</Warning>

## Authorization lifetime

The signed authorization carries a validity window, capped by the operator (one hour by default) with a small allowance for clock skew between you and the merchant. A merchant asking for a longer window than the operator permits gets the operator's cap, not its own request.

In practice this only matters in mode A: if you mint a credential and sit on it, it can expire before you redeem it. The budget stays reserved and the record stays `Issued`. Mint credentials when you're about to use them.

## Settling the record

When the merchant accepts the credential it returns a settlement reference in a `PAYMENT-RESPONSE` (or `X-PAYMENT-RESPONSE`) header — the on-chain transaction hash.

* **Mode B** reads it and closes the record for you: status `Settled`, hash on the ledger.
* **Mode A** leaves the record `Issued` until you report it with `POST /api/v1/router/payments/{paymentId}/settled`.

See [the ledger](/docs/products/catalog/router/ledger) for what those statuses mean and how to reconcile them.

## Operator configuration

These are set per deployment, not per call. You only need them if you run your own Nevermined deployment.

| Env var                    | Default                    | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                          |
| -------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ROUTER_FUNDED_NETWORKS`   | derived from `ENVIRONMENT` | Networks the Router will fund a payment on. Sandbox derives the testnets, live derives mainnet; only a local/dev instance falls back to the permissive `base,base-sepolia`. On a deployed instance this variable can only **narrow** the derived set — it can never add a network, so it cannot move a box across the sandbox/live firewall. Setting it to an empty string is an explicit "fund nothing", not "use the default". |
| `ROUTER_FUNDED_SYMBOLS`    | `USDC,EURC`                | Asset symbols it will pay in                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ROUTER_PREFER_SYMBOL`     | `USDC`                     | Which symbol wins when a 402 offers several                                                                                                                                                                                                                                                                                                                                                                                      |
| `ROUTER_MAX_AUTH_TTL_SECS` | `3600`                     | Ceiling on the signed authorization's validity window                                                                                                                                                                                                                                                                                                                                                                            |

## Next

<CardGroup cols={2}>
  <Card title="The MPP rail" icon="credit-card" href="/docs/products/catalog/router/rails-mpp">
    The other supported protocol, and how it differs.
  </Card>

  <Card title="Guardrails" icon="shield-check" href="/docs/products/catalog/router/guardrails">
    Every check the Router runs before it signs.
  </Card>
</CardGroup>


## Related topics

- [The MPP rail](/docs/products/catalog/router/rails-mpp.md)
- [Router quickstart](/docs/products/catalog/router/quickstart.md)
- [An agent buying on its own](/docs/products/catalog/router/agent-autonomy.md)
- [Router Overview](/docs/products/catalog/router/overview.md)
- [How the Router works](/docs/products/catalog/router/how-it-works.md)
