> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://you.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://you.com/docs/_mcp/server.

# x402

x402 is an open payment protocol that uses the HTTP `402 Payment Required` status code to settle payment for a resource inside the request that asks for it. It is maintained by the x402 Foundation, founded by Coinbase and Cloudflare.

The You.com Web Search and Finance Research APIs accept x402. A client with a funded wallet can call either one with no API key and no You.com account.

Web Search costs \$0.005 per call and Finance Research \$0.11 or \$0.50 depending on the effort tier, all matching the standard credit prices. Payments settle on-chain and do not draw down your credit balance. [MPP](/docs/administration/machine-payments/mpp) costs twice as much for Web Search and the same for Finance Research. See [Pricing](/docs/administration/machine-payments#pricing).

---

## How It Works

1. **The client makes a normal request.** No `X-API-Key`, no payment header.
2. **You.com responds `402 Payment Required`.** The response carries a base64-encoded `PaymentRequired` object in the `PAYMENT-REQUIRED` header. It lists one set of acceptable terms per network in `accepts`.
3. **The client picks a set of terms** matching a network and asset it can pay on.
4. **The client signs a payment authorization.** For EVM networks this is an EIP-3009 `transferWithAuthorization` signed with EIP-712. The client signs but does not broadcast, so settlement is gasless from the client's perspective.
5. **The client retries the same request** with the authorization in the `PAYMENT-SIGNATURE` header.
6. **You.com verifies, runs the request, and settles.** Verification and settlement go through a facilitator, which submits the transfer on-chain and pays gas.
7. **You.com responds `200 OK`** with the results and a `PAYMENT-RESPONSE` header containing the settlement result.

Total added latency is one extra round trip plus settlement, typically a few hundred milliseconds on Base.

### Headers

| Header              | Direction        | Contents                                   |
| ------------------- | ---------------- | ------------------------------------------ |
| `PAYMENT-REQUIRED`  | You.com → client | Base64-encoded `PaymentRequired` object    |
| `PAYMENT-SIGNATURE` | Client → You.com | Base64-encoded `PaymentPayload` object     |
| `PAYMENT-RESPONSE`  | You.com → client | Base64-encoded `SettlementResponse` object |

These are the x402 V2 header names. The older V1 `X-PAYMENT` header is not supported.

---

## Supported Endpoints

| Endpoint                                   | Price per call               | Atomic units (USDC, 6 decimals) |
| ------------------------------------------ | ---------------------------- | ------------------------------- |
| `GET /v1/search`                           | \$0.005                      | `5000`                          |
| `GET /v1/search` with `livecrawl`          | \$0.005 + \$0.001 per result | `5000` + `1000` × `count`       |
| `POST /v1/finance_research` (`deep`)       | \$0.11                       | `110000`                        |
| `POST /v1/finance_research` (`exhaustive`) | \$0.50                       | `500000`                        |

The HTTP method differs per endpoint, and the wrong one returns `401` with no payment terms rather than a helpful error. Web Search offers payment on **GET** only, and Finance Research on **POST** only. `POST /v1/search` and `GET /v1/finance_research` both return `401`.

Both prices match the key-authenticated rate for the same call, so machine payments are not a surcharge. The Contents and Research APIs return `401` on every method and do not offer payment terms.

### Web Search

Query parameters and the response body are the same as the key-authenticated GET endpoint, including `query`, `count`, `freshness`, `country`, `language`, and the domain filters. See the [Web Search API reference](/docs/api-reference/search/v1-search) for the full list.

Result count is `count`, not `num_results`. An unrecognized parameter is ignored rather than rejected, so `num_results=2` silently returns the default 10 results instead of erroring.

`livecrawl` is supported and priced into the quote. Adding it raises the amount in `accepts` by \$0.001 per result, on top of the \$0.005 base call:

| Request                             | Quoted amount | Atomic units |
| ----------------------------------- | ------------- | ------------ |
| `?query=...&count=10`               | \$0.005       | `5000`       |
| `?query=...&count=10&livecrawl=web` | \$0.015       | `15000`      |
| `?query=...&count=50&livecrawl=web` | \$0.055       | `55000`      |

`count` sets how many pages are charged for. The crawl mode does not change the price, so `livecrawl=all` costs the same as `livecrawl=web` at the same `count`.

If you are comparing costs against a key-authenticated integration, machine payments charge per `count` regardless of crawl mode, where [credit billing](/docs/administration/billing) charges per page fetched. At `count=10` with `livecrawl=all` that is 10 pages here and 20 there. Budget from the amount in `accepts`, which is what you actually pay on this path.

Read the price off `accepts` rather than computing it. Because the amount scales with `count`, terms fetched for one request are not valid for a request with a different `count` or a different `livecrawl` setting. Sign against the 402 you were handed for the exact request you intend to send.

### Finance Research

Finance Research takes a JSON body on POST, so there is no query-string form. The financial question goes in `input`, and `research_effort` selects the tier:

```bash
curl -X POST https://api.you.com/v1/finance_research \
  -H "Content-Type: application/json" \
  -d '{"input": "NVDA Q2 guidance vs consensus", "research_effort": "deep"}'
```

The price is fixed per tier rather than scaling with the request, and `deep` is the default when `research_effort` is omitted. See the [Finance Research API reference](/docs/api-reference/finance-research/v1-finance_research) for the response shape.

Send `deep` or `exhaustive` and nothing else. Those are the only values the [Finance Research API reference](/docs/api-reference/finance-research/v1-finance_research) accepts, and it returns `422` for anything else. The 402 is issued before the body is validated, so it will quote a price for an unsupported tier rather than refusing it. Paying against that quote risks spending on a request the endpoint will reject.

Latency is the other thing to plan for. A `deep` call takes under 120 seconds and `exhaustive` under 300, well beyond a typical HTTP client default, so raise your timeout before the payment round trip rather than after.

---

## Networks and Assets

| Network | CAIP-2 identifier                         | Asset | Asset address                                  |
| ------- | ----------------------------------------- | ----- | ---------------------------------------------- |
| Base    | `eip155:8453`                             | USDC  | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`   |
| Solana  | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | USDC  | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |

Solana terms include an `extra.feePayer` address. Use the value from the `accepts` entry you selected rather than caching one, because it changes between challenges.

There is no testnet. Both networks are mainnet, so your first successful call spends real funds. Start with a wallet holding only what you intend to spend while you get the handshake working.

Additional networks are on the roadmap. Read the `accepts` array from the 402 response rather than hardcoding a network, so your client keeps working as we add them.

---

## The 402 Response

```json title="402 Payment Required"
{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "url": "https://api.you.com/v1/search",
    "description": "You.com Search API: real-time web search that returns ranked results (url, title, snippets) plus an optional AI-generated answer.",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "5000",
      "payTo": "0x...",
      "maxTimeoutSeconds": 600,
      "extra": {
        "name": "USD Coin",
        "version": "2"
      }
    },
    {
      "scheme": "exact",
      "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
      "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "amount": "5000",
      "payTo": "...",
      "maxTimeoutSeconds": 600,
      "extra": {
        "feePayer": "..."
      }
    }
  ]
}
```

| Field               | Meaning                                                                                           |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| `x402Version`       | Protocol version. Always `2`.                                                                     |
| `resource`          | What is being paid for, as a URL, description, and MIME type. Sent once, not per entry.           |
| `scheme`            | How payment is formed. `exact` means pay exactly `amount`.                                        |
| `network`           | CAIP-2 network identifier.                                                                        |
| `asset`             | Contract or mint address of the accepted token.                                                   |
| `amount`            | Price in the asset's atomic units. USDC has 6 decimals, so `5000` is \$0.005.                     |
| `payTo`             | The You.com receiving address for this network. Read it from the response, never from these docs. |
| `maxTimeoutSeconds` | How long the terms stay valid. Currently `600`, so 10 minutes to sign and retry.                  |
| `extra`             | Scheme-specific data. Token name and version for EIP-3009, or `feePayer` on Solana.               |

The response also carries an `extensions.bazaar` block, which is an x402 discovery listing describing the endpoint's inputs and outputs for agents that browse the bazaar. You can ignore it when paying directly.

The `payTo` and `feePayer` values above are illustrative. We deliberately do not publish our receiving addresses here, because the live 402 response is the only source that stays correct as we rotate keys, add networks, or change facilitators. Take `payTo`, `asset`, `network`, and `amount` from the `accepts` entry you selected, and sign against those values. A client that hardcodes an address from documentation will keep paying the wrong one after a rotation.

---

## Making a Paid Request

The x402 SDKs wrap `fetch` and handle the 402 retry, so your application code makes one call.

#### TypeScript

```bash
npm install @x402/fetch @x402/evm
```

```typescript
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);

const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));

const fetchWithPayment = wrapFetchWithPayment(fetch, client);

const params = new URLSearchParams({
  query: "best practices for scaling microservices in production",
  count: "10",
});

const response = await fetchWithPayment(`https://api.you.com/v1/search?${params}`);

const data = await response.json();
console.log(data.results.web.map((r) => r.url));
```

#### Python

```bash
pip install x402 eth-account
```

```python
import asyncio
import os

from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client


async def main():
    client = x402Client()
    account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
    register_exact_evm_client(client, EthAccountSigner(account))

    async with x402HttpxClient(client) as http:
        response = await http.get(
            "https://api.you.com/v1/search",
            params={
                "query": "best practices for scaling microservices in production",
                "count": 10,
            },
        )
        data = response.json()
        print([r["url"] for r in data["results"]["web"]])


asyncio.run(main())
```

#### curl (discovery only)

Signing an EIP-3009 authorization by hand is impractical in a shell. This shows the discovery half of the exchange, which is free and useful for inspecting live terms. Use an SDK to actually pay.

```bash
# Request without payment. Returns 402 with terms in the PAYMENT-REQUIRED header.
curl -sS -D - -o /dev/null \
  "https://api.you.com/v1/search?query=nvidia+earnings&count=10"

# Decode the terms.
curl -sS -D - -o /dev/null \
  "https://api.you.com/v1/search?query=nvidia+earnings" \
  | grep -i '^payment-required:' \
  | cut -d' ' -f2 \
  | base64 -d
```

Official clients also exist for Go, Rust, and Java, plus an Axios wrapper and an MCP transport. See the [x402 documentation](https://docs.x402.org) for the current list.

Set a per-request spend ceiling in your client. The SDKs check `amount` against a limit you configure before signing, which protects you if terms change unexpectedly.

---

## Receipts

On success, the `PAYMENT-RESPONSE` header contains a base64-encoded settlement result:

```json
{
  "success": true,
  "transaction": "0x9f2c...c41a",
  "network": "eip155:8453",
  "payer": "0x857b06519E91e3A54538791bDbb0E22373e36b66"
}
```

The transaction hash is your record of payment. There is no invoice and no line item in your credit history, because there is no account. Log the hash alongside your request if you need an audit trail.

---

## Limits and Safeguards

**Replay protection.** Each authorization carries a unique nonce and is valid for exactly one request. A replayed `PAYMENT-SIGNATURE` is rejected.

**Expiry.** Terms expire after `maxTimeoutSeconds`, currently 600 seconds. If your client takes longer to sign and retry, request fresh terms rather than reusing the old ones.

**Rate limits.** Challenge issuance is capped at 10 per minute per caller. An 11th unpaid request inside the same minute returns `429` with a `Retry-After` header instead of a fresh 402, so cache the terms you are handed rather than re-requesting them per retry. This limit applies to the unpaid first leg. Keyless requests cannot inherit an organization's custom QPS limit, so if you need sustained concurrency, [contact sales](https://you.com/support) about an enterprise agreement.

**No chargebacks.** Stablecoin transfers are final once settled, and there is no testnet to rehearse on.

---

## Data Retention

[Zero Data Retention](/docs/administration/zero-data-retention) is not available on x402 requests.

ZDR is an account-level configuration. It is added to an enterprise agreement and enforced against a specific organization's API keys. An x402 request presents no API key and no account, so there is no agreement to attach ZDR to and no identity to enforce it against. Keyless requests fall outside ZDR and are handled under You.com's general terms.

Two consequences to plan around:

* **There is no account-scoped deletion path.** Deletion and data subject requests are handled per organization. An x402 request has no organization, so there is no established route to scope such a request to your traffic.
* **Routing end-user queries through this path is a decision you own.** If you have a retention, residency, or compliance commitment to your own users, send those queries with an API key on an enterprise agreement that has ZDR enabled.

If ZDR is a requirement, use [API key authentication](/docs/administration/api-keys) and ask your account team about adding ZDR to your agreement. The index and the results are identical either way, so this is a change of credential rather than a change of product.

---

## Errors

| Status | Condition                                          | What to do                                                                                                                                                                                                 |
| ------ | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `402`  | No `PAYMENT-SIGNATURE` header                      | Expected on the first call. Read `accepts` and retry with payment.                                                                                                                                         |
| `402`  | Payment header present but not valid               | A malformed, expired, or unverifiable payment re-issues fresh terms rather than returning a distinct status. Decode the new 402, check your signature against the `accepts` entry you selected, and retry. |
| `401`  | Right endpoint, wrong verb                         | Web Search offers payment on GET, Finance Research on POST. Switch the method rather than the endpoint.                                                                                                    |
| `401`  | Invalid `X-API-Key` sent                           | The key path and the payment path are separate. Send a payment header and no key, or a valid key and no payment header.                                                                                    |
| `429`  | More than 10 unpaid challenge requests in a minute | Honor `Retry-After`. Reuse the terms you already hold instead of re-requesting a 402 per attempt.                                                                                                          |
| `5xx`  | Settlement or upstream failure                     | Retry with backoff using fresh terms. See the troubleshooting note below.                                                                                                                                  |

---

## Troubleshooting

**I sent `PAYMENT-SIGNATURE` and still got a 402.** Decode the `error` field in the new response body. The most common causes are signing against stale terms after the 600-second window, and signing for the wrong `asset` or `network` when multiple options are offered.

**My wallet has USDC but verification fails.** Confirm the balance is on the network in the terms you selected. USDC on Ethereum mainnet cannot satisfy an `eip155:8453` requirement, and USDC on Base cannot satisfy the Solana entry.

**I am getting 401 instead of 402.** Check the verb before anything else. Web Search offers payment terms on `GET /v1/search` and Finance Research on `POST /v1/finance_research`. The inverse of either returns `401` with no hint that the method is the problem. The Contents and Research APIs return `401` on every method, since they do not accept machine payments at all.

**Payment settled but the request returned a 5xx.** Each authorization is valid for exactly one request, so a retry needs fresh terms and settles a second payment. Keep the `PAYMENT-RESPONSE` header from the failed call and [contact support](https://you.com/support) with the settlement details rather than absorbing the double charge.

**Can I use an API key and x402 on the same endpoint?** Yes, on the same route, but not in the same request. Requests are routed by what they present. Send `X-API-Key` and the call bills to your credit balance. Send `PAYMENT-SIGNATURE` and it settles on-chain.

**Which protocol version do you support?** x402 V2. The V1 `X-PAYMENT` header is not accepted.

---

## Related

#### [MPP](/docs/administration/machine-payments/mpp)

The method-neutral alternative, settling in USDC on Tempo.

#### [Billing & Credits](/docs/administration/billing)

The standard credit model, for key-authenticated access.

---

## Questions & Support

For x402 questions, reach us in [Discord](https://you.com/discord) or contact [api@you.com](mailto:api@you.com).