# x402 Payments

> Gate HTTP routes behind crypto payments using the x402 protocol.

Section: Accepting Payments
Source: https://coincircuit.io/docs/guides/x402/
Interactive version: https://coincircuit.io/api-reference?tab=guides&guide=x402

## API reference

- POST `/api/v1/x402/requirements`: [Build payment requirements](https://coincircuit.io/api-reference/#tag/x402/POST/api/v1/x402/requirements)
- POST `/api/v1/x402/verify`: [Verify an x402 payment](https://coincircuit.io/api-reference/#tag/x402/POST/api/v1/x402/verify)
- POST `/api/v1/x402/settle`: [Settle an x402 payment](https://coincircuit.io/api-reference/#tag/x402/POST/api/v1/x402/settle)

x402 builds on the HTTP 402 status code to let AI agents and automated clients pay for API resources programmatically. It pairs a `402 Payment Required` response with gasless stablecoin payments, so a machine can pay $0.002 for an API call autonomously and settle it in the same request.

CoinCircuit is the x402 facilitator. Your server states what a request costs, the agent signs a gasless payment, and CoinCircuit verifies it, covers gas, settles on-chain, and returns the transaction hash. The flow is stateless.

![x402 payment flow: an agent, your API, the CoinCircuit facilitator, and the blockchain](https://coincircuit.io/images/features/x402-flow.png)

## Key concepts

**Resource server:** Your API. It returns the `402` with payment requirements, receives the signed payment, and calls CoinCircuit to settle before releasing the resource.

**Facilitator:** CoinCircuit. It verifies and settles the signed payment and sponsors gas. Your server authenticates to it with your API key.

**Payment requirements:** The terms in the `402` (scheme, network, amount, destination, token). CoinCircuit builds them for you from a chain, asset, and amount.

**Gasless payment:** The agent signs an authorization to move funds from its wallet to your address. CoinCircuit submits it on-chain and pays the network fee. The agent needs only a wallet and a signing key.

**Destination:** Funds land at the `payTo` you choose. Leave it unset and CoinCircuit uses your deposit address, so the payment credits your balance automatically.

## How the x402 flow works

1. The agent requests a protected resource from your API.
2. Your server builds requirements with `POST /api/v1/x402/requirements` and returns them in a `402 Payment Required`.
3. The agent reads the requirements and signs a gasless payment for the scheme its chain uses.
4. The agent retries the request with the signed payment.
5. Your server settles it with `POST /api/v1/x402/settle`.
6. CoinCircuit verifies the payment, covers gas, settles on-chain, and returns the transaction hash.
7. Your server releases the resource.

## Step-by-step integration

### 1. Agent requests your resource

```http
GET /api/premium-data
```

### 2. Build the payment requirements

```http
POST https://api.coincircuit.io/api/v1/x402/requirements
x-api-key: sk_live_your_key
Content-Type: application/json

{
  "chain": "base",
  "asset": "USDC",
  "amount": "0.10",
  "resource": "https://your-api.com/api/premium-data"
}
```

The response is the ready-to-return 402 body. It carries a friendly summary plus the canonical `accepts` array a standard x402 client reads.

```json
{
  "x402Version": 1,
  "chain": "base",
  "asset": "USDC",
  "amount": "0.10",
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "maxAmountRequired": "100000",
      "resource": "https://your-api.com/api/premium-data",
      "payTo": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
      "maxTimeoutSeconds": 60,
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ]
}
```

### 3. Return the 402 challenge

Return the body with a `402` status. A standard x402 client reads `accepts[0]` and signs against it.

```json
HTTP/1.1 402 Payment Required

{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "maxAmountRequired": "100000",
      "resource": "https://your-api.com/api/premium-data",
      "payTo": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
      "maxTimeoutSeconds": 60,
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ]
}
```

### 4. Receive the signed payment

The agent signs a payment for the scheme its chain uses and sends back the canonical `paymentPayload`.

```json
{
  "x402Version": 1,
  "scheme": "exact",
  "network": "eip155:8453",
  "payload": {
    "signature": "0xb91c5d2e8a4f0c7d3e6b9a1f2c4d5e6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f90a1b2c3d4e5f6a7b8c9d0e1f2a3b4c1b",
    "authorization": {
      "from": "0x1A2b3C4d5E6f7A8b9C0d1E2f3A4b5C6d7E8f9A0b",
      "to": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
      "value": "100000",
      "validAfter": "0",
      "validBefore": "1774055094",
      "nonce": "0x9b2c4d6e8f0a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e0f2a4b6c8d0e1f3a5b7c"
    }
  }
}
```

### 5. Settle through CoinCircuit

Forward the signed payload and the requirements you issued.

```http
POST https://api.coincircuit.io/api/v1/x402/settle
x-api-key: sk_live_your_key
Content-Type: application/json

{
  "x402Version": 1,
  "paymentPayload": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "eip155:8453",
    "payload": {
      "signature": "0xb91c5d2e8a4f0c7d3e6b9a1f2c4d5e6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f90a1b2c3d4e5f6a7b8c9d0e1f2a3b4c1b",
      "authorization": {
        "from": "0x1A2b3C4d5E6f7A8b9C0d1E2f3A4b5C6d7E8f9A0b",
        "to": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
        "value": "100000",
        "validAfter": "0",
        "validBefore": "1774055094",
        "nonce": "0x9b2c4d6e8f0a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e0f2a4b6c8d0e1f3a5b7c"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "eip155:8453",
    "maxAmountRequired": "100000",
    "resource": "https://your-api.com/api/premium-data",
    "payTo": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
    "maxTimeoutSeconds": 60,
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "extra": { "name": "USD Coin", "version": "2" }
  }
}
```

A successful response returns the settled transaction.

```json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
    "txHash": "0x4b7a1f0c9d2e5a6f8b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3",
    "status": "confirmed",
    "amlCheck": "passed",
    "errorReason": null,
    "network": "eip155:8453",
    "chain": "base",
    "asset": "USDC",
    "payer": "0x1A2b3C4d5E6f7A8b9C0d1E2f3A4b5C6d7E8f9A0b",
    "payTo": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
    "amount": "0.10",
    "fee": "0",
    "blockNumber": 21048765,
    "explorerUrl": "https://basescan.org/tx/0x4b7a1f0c9d2e5a6f8b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3",
    "createdAt": "2026-06-25T21:09:02.000Z"
  }
}
```

Deliver the resource once settlement succeeds, and persist the transaction hash for reconciliation.

Each signed payment settles once. If the same payment is submitted again, settle returns `409 Conflict`; the chain never moves funds twice.

## Resource server example

```typescript
app.get("/api/premium-data", async (_req, res) => {
  const requirements = await fetch("https://api.coincircuit.io/api/v1/x402/requirements", {
    method: "POST",
    headers: {
      "x-api-key": process.env.COINCIRCUIT_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      chain: "base",
      asset: "USDC",
      amount: "0.10",
      resource: "https://your-api.com/api/premium-data",
    }),
  }).then((response) => response.json());

  return res.status(402).json(requirements.data);
});

app.post("/api/premium-data/pay", async (req, res) => {
  const { paymentPayload, paymentRequirements } = req.body;

  const result = await fetch("https://api.coincircuit.io/api/v1/x402/settle", {
    method: "POST",
    headers: {
      "x-api-key": process.env.COINCIRCUIT_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ x402Version: 1, paymentPayload, paymentRequirements }),
  }).then((response) => response.json());

  return res.json({ data: "premium resource", txHash: result.data.txHash });
});
```

## Pre-validate before settling

Use `POST /api/v1/x402/verify` to dry-run a signed payment without touching the blockchain. It takes the same body as settle and runs the requirement and on-chain checks: destination, amount, timestamp, nonce replay, and sender balance.

## Discover supported networks

`GET /api/v1/x402/supported` returns the chains and assets you can accept, and the Solana fee payer to use.

## Look up settled payments

Every settlement is recorded against your account. List them, or fetch one by hash. Both return the same transaction object that settle returns.

```http
GET https://api.coincircuit.io/api/v1/x402/transactions?chain=base&status=confirmed&page=1&size=20
x-api-key: sk_live_your_key
```

Filter with `chain`, `asset`, `status`, `search` (transaction hash or address), `startDate`, and `endDate`. Page with `page` and `size`.

```json
{
  "success": true,
  "data": [
    {
      "id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
      "txHash": "0x4b7a1f0c9d2e5a6f8b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3",
      "status": "confirmed",
      "amlCheck": "passed",
      "errorReason": null,
      "network": "eip155:8453",
      "chain": "base",
      "asset": "USDC",
      "payer": "0x1A2b3C4d5E6f7A8b9C0d1E2f3A4b5C6d7E8f9A0b",
      "payTo": "0x9f1c4a2b7De3a01F5b8c2D4e6A7b9C0d1E2f3A4b",
      "amount": "0.10",
      "fee": "0",
      "blockNumber": 21048765,
      "explorerUrl": "https://basescan.org/tx/0x4b7a1f0c9d2e5a6f8b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3",
      "createdAt": "2026-06-25T21:09:02.000Z"
    }
  ],
  "meta": { "page": 1, "size": 20, "total": 1, "totalPages": 1 }
}
```

Fetch a single payment by its transaction hash:

```http
GET https://api.coincircuit.io/api/v1/x402/transactions/0x4b7a1f0c9d2e5a6f8b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3
x-api-key: sk_live_your_key
```

## Signing schemes

The wire scheme is always `exact`. CoinCircuit selects the on-chain mechanism from the network and asset.

| Asset | Networks | Mechanism |
| :--- | :--- | :--- |
| USDC | Base, Arbitrum, BSC, Solana | EIP-3009 (EVM), partial signing (Solana) |
| USDT | Base, Arbitrum, BSC, Solana | Permit2 (EVM), partial signing (Solana) |

**EVM (USDC, USDT):** the agent signs an EIP-712 authorization, using `extra.name` and `extra.version` from the requirements, and sends `{ signature, authorization }`.

**Solana (USDC, USDT):** the agent builds an SPL token transfer, sets `extra.feePayer` from the requirements as the transaction fee payer, partially signs it, and sends `{ transaction }` as base64. CoinCircuit co-signs as fee payer at settlement.

## Why your server settles

The agent signs the authorization; your backend settles it through CoinCircuit. The agent stays simple: just a wallet and a signing key. Your server stays in control: validate the request, settle, then release the resource only after confirmation.

## Use cases

- Metered API endpoints billed per call
- AI agent tool calls and MCP resource access
- Paywalled datasets, reports, and one-time content
- Compute, inference, storage, and SaaS actions priced per request
