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:
- The client sends a normal MCP JSON-RPC request —
tools/callwithname: "verify_agent"— toPOST https://evidiq.dev/mcp. - Our server recognizes the tool is paid and returns HTTP 402 Payment Required with a JSON body containing an
accepts[]array. - The client parses
accepts[], picks the matching payment rail (we only ship one for now), signs an EIP-3009transferWithAuthorizationmessage, and retries the same request. - This time the client adds an
X-PAYMENTheader containing the base64-encoded payment payload. - 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.
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:
- 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.
- Bounded exposure.
validBeforeis 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. - Single-use nonces. Each
nonceis 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
transferWithAuthorizationon 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.
- Expired
validBefore— usually because a client cached the 402 challenge and retried 20 minutes later. Server returns HTTP 402 again witherror: "X-PAYMENT authorization expired". Fix: do not cache the 402 body; refetch on every retry. - Reused
nonce— almost always a buggy retry loop. The token contract reverts withFiatTokenV2_2: nonce already used. Server surfaces this as 402 witherror: "X-PAYMENT nonce already consumed". Fix: generate a fresh nonce for every retry, not every session. - Wrong domain separator — typically missing
extra.name/extra.version. Signature recovers to a different address than expected; settler reverts. Server returns 402 witherror: "X-PAYMENT signature does not recover to a valid payer". Fix: includeextrafields in your EIP-712 domain. - 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 witherror: "X-PAYMENT transfer reverted: insufficient balance". Fix: top up the wallet. - Wrong asset — the client constructed an EIP-3009 signature for USDC on X Layer instead of USDT0. The signature verifies, the call to
transferWithAuthorizationreverts because the contract address isn't USDT0. Server returns 402 witherror: "X-PAYMENT asset mismatch". Fix: read theassetfield and don't hardcode token addresses.

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.
