Skip to content

Lanes

Agent lane

The Agent lane protects x402 and nanopayment calls with capped sessions and seller-signed receipts. A missing receipt means an automatic refund.

What the Agent lane covers

AI agents pay for API calls, data and compute in very small amounts, many times in a row. A dispute process built for people does not fit. An agent cannot write a complaint, and nobody will arbitrate a 0.02 USDC call.

The Agent lane replaces judgement with a rule that code can check:

  • The agent opens a protected session with a spending cap.
  • Each paid API response must carry a receipt signed by the seller.
  • A call that was paid but has a missing or late signed receipt is refunded automatically. There is no arbitration.

The seller side is the same as in the Commerce lane: one bond, one capacity, one fee.

x402 in brief

x402 is a payment flow built on the HTTP status code 402 Payment Required.

  1. The agent requests a resource.
  2. The server answers 402 and states the price, the asset and where to pay.
  3. The agent repeats the request with a payment attached.
  4. The server checks the payment and returns the response.

The agent pays per request. There are no accounts and no API keys. With UNDO, step 4 has one more requirement: the response carries the signed receipt, for example in a response header.

http
GET /v1/check?target=api.example.com HTTP/1.1
Host: monitor.example.com

HTTP/1.1 402 Payment Required
Content-Type: application/json

{ "accepts": [{ "scheme": "exact", "network": "arc", "asset": "USDC", "maxAmountRequired": "20000" }] }
http
GET /v1/check?target=api.example.com HTTP/1.1
Host: monitor.example.com
X-PAYMENT: <payment payload bound to the UNDO session>

HTTP/1.1 200 OK
Content-Type: application/json
X-UNDO-RECEIPT: <base64 of the Receipt fields and the seller signature>

{ "status": "up", "latencyMs": 41 }

The header name X-UNDO-RECEIPT is a draft. A receipt middleware for x402 servers is planned for phase 2 of the roadmap, so that sellers do not have to write the signing code themselves.

Protected sessions

open session · cap 5 USDC · window 10 min to 24hrequest + pay 0.02 (x402)response + signed receiptrequest + pay 0.02no receipt, or lateclaim → automatic refund of 0.02AgentSeller APIReceipts
No arbitrator is involved. A missing or late receipt is proof enough.

A session is the unit of protection in this lane.

Session parameterPlanned value
Spending capSet by the agent when it opens the session
WindowFrom 10 minutes to 24 hours
Price per callSet by the seller
Proof of deliveryOne signed receipt per paid call
AssetsUSDC and EURC

The lifecycle has four steps.

  1. Open session. The agent opens a session against a seller with a spending cap, for example 5 USDC. The cap is the most the agent can spend in that session.
  2. Paid call. The agent pays per request through x402 or a nanopayment. Each call has an index inside the session.
  3. Signed receipt. The seller returns the response with a receipt that binds the session, the call index, the request hash and the response hash.
  4. Claim. Before the window ends, the agent can claim a refund for every paid call that has no valid receipt.

Before opening a session, an agent can read the seller's public profile: protected volume, dispute rate, lost-dispute rate, bond and free capacity.

Signed receipts

A receipt is an EIP-712 typed message signed by the seller. It states that a specific response was served for a specific paid call.

Receipt struct

solidity
struct Receipt {
    bytes32 sessionId;    // protected session opened by the payer
    uint64  callIndex;    // position of the call inside the session
    bytes32 requestHash;  // keccak256 of the request the agent sent
    bytes32 responseHash; // keccak256 of the response body the seller returned
    uint256 amount;       // price of this call, in USDC base units
    uint64  servedAt;     // seller timestamp, must fall within the receipt deadline
}

EIP-712 domain

json
{
  "name": "UNDO Receipts",
  "version": "1",
  "chainId": 5042,
  "verifyingContract": "0x0000000000000000000000000000000000000000"
}

verifyingContract will be the Receipts contract. Its address is not published yet. The zero address above is a placeholder.

Verifying a receipt

The agent should verify each receipt as soon as the response arrives. This draft example uses viem.

ts
import { createPublicClient, http, keccak256, toHex } from "viem";

const client = createPublicClient({ transport: http(ARC_RPC_URL) });

const domain = {
  name: "UNDO Receipts",
  version: "1",
  chainId: 5042,
  verifyingContract: RECEIPTS_ADDRESS, // not published yet
} as const;

const types = {
  Receipt: [
    { name: "sessionId", type: "bytes32" },
    { name: "callIndex", type: "uint64" },
    { name: "requestHash", type: "bytes32" },
    { name: "responseHash", type: "bytes32" },
    { name: "amount", type: "uint256" },
    { name: "servedAt", type: "uint64" },
  ],
} as const;

async function isReceiptValid(receipt, signature, responseBody, sellerAddress) {
  // 1. The receipt must describe the response that was actually received.
  const hashMatches = receipt.responseHash === keccak256(toHex(responseBody));
  if (hashMatches === false) return false;

  // 2. The signature must come from the seller of the session.
  return client.verifyTypedData({
    address: sellerAddress,
    domain,
    types,
    primaryType: "Receipt",
    message: receipt,
    signature,
  });
}

If isReceiptValid returns false, the agent keeps the call in its list of claimable calls.

Smart-contract wallets

Sellers and agents can use smart-contract wallets. The Receipts contract is designed to accept EIP-1271 signatures, so a seller contract can approve a receipt through its isValidSignature function. In the example above, the public client's verifyTypedData action also checks contract signatures, so the same code covers both wallet types.

Automatic claims

A claim is a list of call indexes that were paid without a valid receipt. The Receipts contract checks each call against the session record.

CaseOutcome
Paid call, valid receipt on timeNo refund through this path
Paid call, no receiptAutomatic refund
Paid call, receipt after the receipt deadlineAutomatic refund
Valid receipt, but the agent's owner contests the contentStandard dispute: deposit, 48h seller response, arbitration

Automatic refunds follow the same refund waterfall as any other refund.

Worked example

A monitoring agent opens a 5 USDC session at 0.02 USDC per call. The cap covers up to 250 calls.

During the session the API goes down. The payments still settle, but 212 calls are paid without a signed receipt.

text
unreceipted calls   212
price per call      0.02 USDC
refund              212 x 0.02 = 4.24 USDC

The agent submits the claim. 4.24 USDC is refunded automatically, with no arbitration.

Keys and operations

The seller's receipt signing key is sensitive. Anyone who holds it can sign receipts for responses that were never served. Sellers should keep it separate from the key that controls the bond, and store it the way they would store any production secret. See Risks.