> For the complete documentation index, see [llms.txt](https://docs.flowcp.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flowcp.ai/reference/agentic-payments.md).

# Agentic payments (x402)

This page describes how an **AI agent** pays for a monetized FlowCP tool. It is the consumer-side counterpart to the builder guide [Monetize your MCP server](/guides/monetize-your-mcp-server.md).

FlowCP implements the [x402](https://x402.org) protocol: a paid resource responds with the payment requirements, the client pays and retries with a signed proof, and the server settles the payment before serving the result. Because MCP tool calls ride JSON-RPC (not a plain HTTP GET), FlowCP carries the x402 exchange **inside the tool call** rather than as a raw HTTP 402.

## The flow

### 1. Discover the price

Call the built-in **`get_pricing`** tool. It returns everything the server charges in one read-only call, so you can budget a sequence of calls before committing to any of them:

```json
{
  "scheme": "x402",
  "network": "base-sepolia",
  "payTo": "0x…",
  "paidTools": [
    {
      "name": "create_invoice",
      "description": "Create an invoice",
      "category": "Billing",
      "price": "10000",
      "asset": "USDC",
      "priceUsd": "0.01"
    }
  ],
  "freeToolCount": 14,
  "truncated": false,
  "paymentField": "_payment",
  "requirementsMetaKey": "com.flowcp/x402"
}
```

`price` is in **atomic token units** (e.g. `10000` = 0.01 USDC at 6 decimals). `priceUsd` is a convenience rendering, and is `null` when the asset is not a USD-pegged stablecoin we recognize — in that case use `price` and `asset`.

Notes:

* **`get_pricing` exists only on a server that actually charges.** If the tool is absent, every tool on that server is free. It is itself always free to call.
* **Anything it does not list is free.** Free tools are reported as a `freeToolCount`, not enumerated — use `tools/list` for those.
* Pass `category` or `toolName` to narrow the result. If `truncated` is `true`, the list was capped and you should filter to see the rest.
* A server whose own API already has a tool named `get_pricing` keeps its own; the built-in is skipped rather than shadowing it. In that case fall back to the per-tool metadata below.

Each paid tool also advertises its own price in its MCP tool metadata under `com.flowcp/payment` — useful when your client surfaces `_meta`, and the fallback when `get_pricing` is unavailable:

```json
{
  "scheme": "x402",
  "price": "10000",
  "asset": "USDC",
  "network": "base-sepolia",
  "payTo": "0x…"
}
```

On a large server using **dynamic tool exposure**, tools are not registered until `search_tools` activates them — so they have no metadata to read yet. `search_tools` results carry `price` and `asset` for exactly this reason (`null` on a free tool), and `get_pricing` works regardless of exposure mode.

### 2. Call once, get the requirements

Call the tool normally. If you haven't attached a payment, the tool returns an **error result** whose `_meta` carries the full x402 requirements under `com.flowcp/x402`:

```json
{
  "x402Version": 1,
  "error": "Payment required to call 'create_invoice'.",
  "accepts": [
    {
      "scheme": "exact",
      "network": "base-sepolia",
      "maxAmountRequired": "10000",
      "resource": "mcp://your-server/tools/create_invoice",
      "payTo": "0x…",
      "asset": "USDC",
      "maxTimeoutSeconds": 120
    }
  ]
}
```

### 3. Pay and retry

Construct a signed payment that satisfies `accepts[0]` and call the tool **again** with the proof in the reserved `_payment` field:

```json
{
  "<your normal tool arguments>": "…",
  "_payment": {
    "nonce": "<unique per payment>",
    "amount": "10000",
    "asset": "USDC",
    "network": "base-sepolia",
    "payTo": "0x…",
    "signature": "<authorization the facilitator verifies>"
  }
}
```

FlowCP verifies the proof with its payment facilitator, settles it, and then runs the tool and returns the normal result.

## Rules to code against

* **Pay before you get the result.** The tool does not run until payment is verified and settled. Treat the first (unpaid) call as a price quote.
* **One nonce, one call.** Each `nonce` settles at most once. Re-sending the same proof is rejected (`PAYMENT_REQUIRED` — "payment proof already used"). Use a fresh payment for every call.
* **Cover the price.** `_payment.amount` must be ≥ `maxAmountRequired`, and the `asset`, `network`, and `payTo` must match the requirement, or the call is rejected.
* **Fail closed.** A missing/invalid proof, an underpayment, or a facilitator error all reject the call — nothing runs and nothing is charged.
* **Resource reads can charge too.** An *endpoint resource* is backed by a tool. If that tool is priced, reading the resource goes through the same payment gate as calling the tool, and fails the same way without a proof.

## Errors

All payment failures surface as a tool error with code `PAYMENT_REQUIRED` (HTTP 402 semantics). When the failure is "no payment yet", the result `_meta` includes the `com.flowcp/x402` requirements so you can pay and retry.

## Facilitator

FlowCP settles through an x402 **facilitator**. There are three modes:

* **Mock** (default) — a built-in in-process facilitator, no real funds. Used by development and self-host runtimes when nothing else is configured.
* **Generic HTTP** — set `X402_FACILITATOR_URL` (and `X402_FACILITATOR_API_KEY` for a bearer credential) to point at any x402 facilitator's `/verify` + `/settle`.
* **Coinbase CDP** — set `X402_FACILITATOR_PROVIDER=cdp` plus `CDP_API_KEY_ID` / `CDP_API_KEY_SECRET`. The runtime uses the official [Coinbase CDP facilitator](https://docs.cdp.coinbase.com/x402/core-concepts/facilitator) via the `@coinbase/x402` SDK (an optional dependency, lazily loaded). This is the real on-chain rail.

### Running a real CDP facilitator (testnet)

The CDP facilitator speaks **true x402**: the payment the agent presents must be a real signed x402 payload (an EIP-3009 authorization), not the simplified mock `_payment` shape. To bring the real rail up safely on `base-sepolia`:

1. Create CDP API keys at <https://portal.cdp.coinbase.com> and fund a testnet wallet from a [base-sepolia faucet](https://docs.base.org/tools/network-faucets).
2. Set `X402_FACILITATOR_PROVIDER=cdp`, `CDP_API_KEY_ID`, `CDP_API_KEY_SECRET`.
3. Capture a real x402 verify/settle request from an x402 client (the Coinbase x402 examples emit one) into a JSON file: `{ "paymentPayload": {…}, "paymentRequirements": {…} }`.
4. Run the verification script — it does exactly what the runtime's `CdpFacilitator` does and prints the on-chain settlement tx:

   ```bash
   CDP_API_KEY_ID=… CDP_API_KEY_SECRET=… pnpm verify:x402 ./payment-fixture.json
   # add --verify-only to check without settling
   ```

Once that prints a settlement tx, the runtime's CDP path is live. Note that FlowCP friendly network names (`base`, `base-sepolia`) are mapped to the CAIP-2 ids the SDK expects (`eip155:8453`, `eip155:84532`).

## Where the money goes

Payments **settle directly to the builder's payout address** — FlowCP never custodies funds. FlowCP's marketplace platform fee is **not** taken from the on-chain settlement; instead it is metered onto the builder's existing FlowCP subscription invoice (reported in whole USD cents to the `STRIPE_PLATFORM_FEE_METER_EVENT` meter, reconciled hourly). Each settled payment is recorded as a receipt showing the amount, the builder's share, and the platform fee — visible on the dashboard under **Monetization → Transactions**.
