Check the wallet that pays you, then decide

You sell to agents: an x402 endpoint, a paid MCP server, an A2A service, a marketplace listing, an API. Before you serve a request, you can check the paying wallet with one call and get back a signed yes or no. What happens next is up to you.

This page is for the seller. If you are building the agent that pays, read AI Agent Wallet Auth API instead.

The check

One POST /v1/attest on the paying wallet, before you serve. Send the wallet and up to 10 conditions, each with its own chainId, on any of 37 chains. The answer is a signed yes or no for each condition, plus pass for the whole set. It never returns a balance.

If you sell over x402, take the wallet from the signed payment payload rather than from a field the caller typed. The x402 seller example shows how.

Questions a seller usually asks

ConditionWhat it answersWhere
erc8004_agentIs this wallet registered as ERC-8004 agent N? Registration is open to anyone, so a yes means registered and nothing more.Base, chainId 8453, only
erc7710_delegationDoes this wallet hold a valid, unrevoked delegation from the principal it says it acts for, and what limits did that principal sign?Base, chainId 8453, only
ratio_to_amountDoes the wallet hold X times this payment? You send the multiple and the amount with each request, so one rule fits every price.EVM chains
account_codeIs the wallet a contract or a plain key?EVM chains

Also available: token_balance, nft_ownership, eas_attestation, farcaster_id. Request fields for each are in the developer docs and openapi.yaml.

You decide

InsumerAPI reads chain state and signs what it found. It does not decide anything about the payer. You read pass and each result's met, then choose:

  • Serve the request as priced.
  • Change the terms: a different price, a smaller scope, a shorter session.
  • Ask for more: another condition, a delegation, a second wallet.
  • Decline.

The rule is yours, and so is the decision.

Keep the answer

Every answer is signed twice: ES256 and a post-quantum ML-DSA-65 signature. The public keys are published as JWKS at /.well-known/jwks.json and GET /v1/jwks. Each result carries a conditionHash of the exact condition that was evaluated, so your record shows the question as well as the answer. Add proof: "merkle" to get a Merkle proof against the block (27 of the 31 EVM chains). Check any of it offline with insumer-verify, on npm and PyPI. No call back to the API.

An attestation is good for 30 minutes (5 when it includes a delegation). As a record of what you checked before you served, it is good for as long as you keep it.

Paying for the check

x402 moves the money. InsumerAPI checks the conditions.

x402, no key. Send the request with no key, take the 402 quote, pay it in USDC on Base, Polygon, Arbitrum, Arc, or Solana, and retry. A check costs $0.05 a call, or $0.10 with a Merkle proof, with no key and no signup. Here you are the payer. The payer is charged only for a successful answer, and the payer sees the answer only after the payment settled.

A key. Free (10 credits), Pro $29/mo (1,000 credits), or Enterprise $99/mo (5,000 credits). A check is 1 credit, or 2 with a Merkle proof. Send the key in the X-API-Key header. Details on pricing.

One call

The example below asks three things about the wallet that is paying you $5: is it registered as agent 1234, does it hold 10 times the payment, and is it a plain key rather than a contract. Swap in your own values.

POST /v1/attest
curl -X POST https://api.insumermodel.com/v1/attest \
  -H "X-API-Key: $INSUMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "wallet": "0xYOUR_PAYER_WALLET",
    "conditions": [
      {
        "type": "erc8004_agent",
        "chainId": 8453,
        "agentId": "1234",
        "label": "Registered agent 1234"
      },
      {
        "type": "ratio_to_amount",
        "chainId": 8453,
        "contractAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "multiple": "10",
        "amount": "5",
        "label": "Holds 10x the payment"
      },
      {
        "type": "account_code",
        "chainId": 8453,
        "expect": "none",
        "label": "Plain key account"
      }
    ]
  }'

No key? Drop the X-API-Key line. The first reply is the 402 quote; pay it and retry with the PAYMENT-SIGNATURE header.

Response shape (abridged):

Response
{
  "ok": true,
  "data": {
    "attestation": {
      "id": "ATST-A7C3E1B2D4F56789",
      "pass": true,
      "results": [
        { "condition": 0, "type": "erc8004_agent", "chainId": 8453, "met": true, "label": "Registered agent 1234", "conditionHash": "0x..." }
      ],
      "attestedAt": "...",
      "expiresAt": "..."
    },
    "sig": "...",
    "kid": "insumer-attest-v2",
    "pqSig": "...",
    "pqKid": "insumer-attest-pq1"
  },
  "meta": { "creditsCharged": 1 }
}

data.attestation.pass is true only when every condition is met. Each entry in results carries met, chainId, label and conditionHash. sig, kid, pqSig and pqKid are the two signatures and their key IDs.

Next

Need merchant screens (a dashboard, a scanner, passes)? Those are Skye Meta's, which builds on InsumerAPI.