All posts
x402August 7, 2026·9 min read

The Anatomy of an x402 Pay-Per-Call MCP Server Request

The Anatomy of an x402 Pay-Per-Call MCP Server Request

Your agent needs to call a tool on a stranger. The stranger wants money. Nobody wants to hold funds. Nobody wants to hand the other side authority over its treasury. So how does the call actually happen on the wire?

That's the question EVIDIQ's x402 pay-per-call MCP server was built to answer — a wire-level specification, not a vibes-based handshake. We've shipped this so that every verify_agent invocation is auditable on X Layer, signed by the payer, and settled without EVIDIQ ever touching a private key that controls funds. The rest of this post is the actual protocol, top to bottom.

If you've ever hit HTTP 402 from an MCP endpoint and wondered what the headers really meant, this walkthrough is for you.

The Wire Protocol, Byte by Byte

An x402 pay-per-call MCP server is an MCP endpoint that returns HTTP 402 Payment Required when a tool costs money, with a machine-readable accepts[] challenge describing exactly how to pay. EVIDIQ exposes its verify_agent tool through this flow on X Layer using USDT0, so every caller pays per verification and the server never holds funds or grants authority.

Here's the call sequence, exactly as it hits the wire:

  1. The client sends a normal MCP JSON-RPC request — tools/call with name: "verify_agent" — to POST https://evidiq.dev/mcp.
  2. Our server recognizes the tool is paid and returns HTTP 402 Payment Required with a JSON body containing an accepts[] array.
  3. The client parses accepts[], picks the matching payment rail (we only ship one for now), signs an EIP-3009 transferWithAuthorization message, and retries the same request.
  4. This time the client adds an X-PAYMENT header containing the base64-encoded payment payload.
  5. Our server verifies the signature, broadcasts the settlement transaction to X Layer, waits for inclusion, and only then returns the JSON-RPC result with the trust score.

Same request, same payload, same tool name. Only the header changes between step 2 and step 4. That's the whole dance. No session cookies, no OAuth, no API keys, no signup wall.

Worth noting: the retry is idempotent from the client's perspective — the JSON-RPC id is identical, so a successful retry returns the result and a failed retry returns the same JSON-RPC error envelope the unpaid call would have produced. There's no "payment succeeded but the tool didn't run" race condition in our flow, because we settle before the tool runs.

For a full description of the server surface and how it slots into Claude, Cursor, or any MCP-compatible host, see the EVIDIQ homepage or the EVIDIQ docs overview.

Reading an accepts[] Object

The 402 body is where most integrators stumble. It's a JSON document that looks like this:

{
  "x402Version": 2,
  "error": "X-PAYMENT header is required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "x-layer",
      "amount": "50000",
      "asset": "0x...USDT0",
      "payTo": "0x...evidiq-settler",
      "extra": {
        "name": "USDT0",
        "version": "1"
      }
    }
  ]
}

Each field is load-bearing. Here's the field-by-field contract:

  • scheme"exact" is the only scheme we accept today. It tells the client to pay a fixed amount, no negotiation, no streaming price discovery. If a client sends "scheme": "upto" we'll reject the request because our settler can't safely authorize an unbounded amount.
  • network"x-layer". The chain identifier has to match exactly. Some clients translate it to "eip155:196" for chain-id-aware signing libraries; either works, as long as the chain id 196 ends up in the EIP-712 domain.
  • amount — atomic units. "50000" is 0.05 USDT0 (USDT0 has 6 decimals). If you send the value in human-readable form you'll pay 50,000 USDT0 and probably lose the money — there's no refund flow on our side.
  • asset — the ERC-20 contract address. This must be the USDT0 contract on X Layer; we don't accept USDC, we don't accept bridged variants. A wrong asset means the settler reverts and the client gets a 402 again.
  • payTo — the recipient. Always the EVIDIQ settler address. Anything else is a phishing target; treat it as one.
  • extra.name / extra.version — required by EIP-3009 domain separators for USDT0. Forget these and the signature verifies against a non-existent EIP-712 domain and the call is rejected.

The failure mode we see most often: clients honor amount as a string but ignore extra.name, then wonder why their EIP-712 signature "looks right" but doesn't recover. It looks right because they signed against the wrong domain.

EVIDIQ blog illustration 1 array. No real brand logos.]

If you want the full reference of how the settler wallet is structured and how payouts reach the EVIDIQ treasury on success, the EVIDIQ Operator docs walk through the address flow step by step.

EIP-3009 Without the Cryptography Lecture

EIP-3009's transferWithAuthorization is the magic that lets a payer sign once, off-chain, without paying gas for the signature. The signature itself is an EIP-712 typed message authorizing a specific (from, to, value, validAfter, validBefore, nonce) tuple. The receiver — in our case EVIDIQ's settler contract — calls transferWithAuthorization with the signature, and the token contract moves the funds.

Three things make this clean:

  1. No gas from the payer. The payer signs in their own wallet, off-chain. The settler pays gas on X Layer to execute the transfer. This is what makes a pay-per-call flow feel like a REST call to the caller.
  2. Bounded exposure. validBefore is a Unix timestamp. If the signature isn't submitted before then, it just stops working. We set ours to roughly five minutes from issuance, so a stale retry can't be replayed tomorrow.
  3. Single-use nonces. Each nonce is a random 32-byte value; once it's spent, it can't be spent again. Our settler rejects any reuse at the contract level, not at our application level — so the safety lives in the token, not in our database.

When a call lands with a valid X-PAYMENT header, our server:

  • Recovers the signer from the EIP-712 signature.
  • Checks the signer matches the address that will fund the transfer (paying with someone else's authorization is a contract revert, not a server logic check).
  • Calls transferWithAuthorization on USDT0.
  • Waits for the transaction receipt on X Layer.

Only after the receipt is in does the MCP tool actually execute and the trust score is computed. The full evaluation pipeline — identity, capability, reputation, risk — is documented in the EVIDIQ Sentinel docs.

Honestly? The biggest design decision here was picking the chain. X Layer gives us sub-cent fees and 2-second finality, which means a verify_agent call costs roughly the same as a single Postgres read on a hosted database. If you're paying more than a cent for one of these calls, something is wrong upstream.

What Happens on a Bad Signature or Late Nonce

We test every failure path before we ship a release. Here's what each one looks like from the integrator's side, because "it didn't work" is the most common issue report we get.

  1. Expired validBefore — usually because a client cached the 402 challenge and retried 20 minutes later. Server returns HTTP 402 again with error: "X-PAYMENT authorization expired". Fix: do not cache the 402 body; refetch on every retry.
  2. Reused nonce — almost always a buggy retry loop. The token contract reverts with FiatTokenV2_2: nonce already used. Server surfaces this as 402 with error: "X-PAYMENT nonce already consumed". Fix: generate a fresh nonce for every retry, not every session.
  3. Wrong domain separator — typically missing extra.name/extra.version. Signature recovers to a different address than expected; settler reverts. Server returns 402 with error: "X-PAYMENT signature does not recover to a valid payer". Fix: include extra fields in your EIP-712 domain.
  4. Insufficient balance or allowance — the payer is trying to spend USDT0 they don't hold. Settler reverts with the standard ERC-20 insufficient balance. Server returns 402 with error: "X-PAYMENT transfer reverted: insufficient balance". Fix: top up the wallet.
  5. Wrong asset — the client constructed an EIP-3009 signature for USDC on X Layer instead of USDT0. The signature verifies, the call to transferWithAuthorization reverts because the contract address isn't USDT0. Server returns 402 with error: "X-PAYMENT asset mismatch". Fix: read the asset field and don't hardcode token addresses.

EVIDIQ blog illustration 2

Two of these — the wrong-domain and wrong-asset failures — are purely client bugs. We've shipped our reference client (in the EVIDIQ Notary docs) specifically to give integrators a known-good implementation to copy from.

For completeness: the resulting report — keccak256 hash, evidence on 0G Storage, AI risk analysis on 0G Compute, and an EIP-191 signature from the EVIDIQ key — is something any third party can re-fetch and verify themselves. The recommendation (proceed, proceed_with_escrow, caution, do_not_proceed) is auditable, not a black-box verdict. That's the whole point of running the trust computation through a deterministic formula rather than hiding it behind a model.

Frequently Asked Questions

The MCP server itself is open source under MIT and the install tools (how_to_install, get_evidiq_skill) are free. The actual verification — the verify_agent tool that produces a trust score — is paid per call, settled in USDT0 on X Layer via the x402 flow described above. There's no subscription and no API key; you only pay when you actually verify someone.

Give your agent the trust skill:

curl -s https://evidiq.dev/skill.md
E

EVIDIQ Team

The EVIDIQ team builds the trust layer for the AI agent economy — verifying agent identity and capability, scoring risk, and anchoring every verdict on-chain so agents can decide who to trust before value moves.

More from EVIDIQ Team
How EVIDIQ's x402 Pay-Per-Call MCP Server Works — EVIDIQ