At 4:52 on a Friday afternoon, an instruction lands at a corporate treasury service: pay this invoice. $48,000 in USDC to a vendor wallet, on behalf of a client called Meridian Labs. The sender is not Meridian's CFO. It is Meridian's procurement agent, a piece of software carrying a signed permission slip.
There is no human to call. The payment is irreversible the second it settles. And the one thing everyone has learned about AI agents this year is that some of them are compromised, confused, or running on authority that was revoked twenty minutes ago.
This post walks through how I answer that question with two API calls: what goes in, what comes back, why every answer is a signed boolean instead of a score, and how to verify the signatures yourself without trusting the API that produced them.
The two-party problem
The thing that makes agent payments different from checkout is that the actor and the owner are different parties. The agent spends; the money is Meridian's; whoever executes the payment sits in the middle carrying the liability if those two facts ever disagree.
So there are questions about two different wallets:
- The agent's wallet: is this a registered, identifiable agent, and does it hold currently-valid authority from its principal?
- The principal's wallet: is there a KYC-attested entity behind this, and can the treasury actually stand the payment?
An attestation evaluates one wallet, so this is two calls to POST /v1/attest. One receipt for the actor, one for the owner.
Call 1: may this agent act?
Two conditions against the agent's wallet, both answered from chain state on Base:
POST https://insumermodel.com/v1/attest
X-API-Key: <key>
{
"wallet": "0xA9b3...the agent's wallet",
"conditions": [
{
"type": "erc8004_agent",
"chainId": 8453,
"agentId": "412",
"label": "Registered ERC-8004 agent"
},
{
"type": "erc7710_delegation",
"chainId": 8453,
"delegationManager": "0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3",
"expectedDelegator": "0x51fA...Meridian's treasury",
"delegation": { "...the signed ERC-7710 delegation object..." },
"label": "Currently authorized by Meridian's treasury"
}
]
}
Response, abridged (illustrative values, exact real shape):
{
"pass": true,
"results": [
{
"label": "Registered ERC-8004 agent",
"met": true,
"matchedVia": "owner"
},
{
"label": "Currently authorized by Meridian's treasury",
"met": true,
"declaredLimits": [
{
"kind": "erc20_transfer_amount",
"token": "0x8335...USDC on Base",
"maxAmount": "75000000000"
}
]
}
],
"attestedAt": "2026-07-31T20:52:14.000Z",
"expiresAt": "2026-07-31T20:57:14.000Z",
"sig": "MEUCIQDrT...",
"kid": "insumer-attest-v2"
}
A few fields worth unpacking:
erc8004_agent is honest about what it proves. ERC-8004 registration is permissionless NFT minting, so met: true means exactly "registered in the Identity Registry at this agentId, and this wallet owns the agent NFT or is the registry's signature-verified agent wallet binding." matchedVia tells you which. No vetting, no reputation, no endorsement implied. An attestation that overclaims is worse than none.
erc7710_delegation checks the whole chain of facts. met: true only when the attested wallet is the delegate, the declared principal matches expectedDelegator, the EIP-712 signature verifies (EOA recovery, or ERC-1271 for smart-contract principals, and the result names which), the delegation is unrevoked as of the anchored block, every caveat uses a recognized enforcer, and any time window is currently open.
declaredLimits is a decode, not a verdict. The spending caveats the principal signed come back decoded, with amounts in base units. 75000000000 on a 6-decimal token is a $75,000 USDC cap, sitting above this $48,000 invoice. It is reported as what the principal signed rather than something the API simulated, and each entry carries the raw caveat terms hex it was decoded from, so you can re-derive the decode yourself from the enforcer's documented byte layout. If you plan to forward the attestation and would rather the cap not travel with it, send declaredLimits: "omit" in the request; met and the hashes stay byte-identical.
The expiry is 5 minutes, not the standard 30. Revocation is one transaction away, so a verdict about delegation is only fresh while it is fresh. The short window is the honest window.
Call 2: the owner, wherever the money lives
Corporate crypto treasuries are never on one chain. BTC in cold reserve, USDT on Tron because that is where payment liquidity is, RLUSD on the XRP Ledger, operating USDC on Base and Ethereum. The second call attests Meridian's treasury wallet, and each condition carries its own chainId:
{
"wallet": "0x51fA...Meridian's treasury",
"xrplWallet": "rN7n...",
"bitcoinWallet": "bc1q...",
"tronWallet": "TWdc...",
"conditions": [
{ "type": "eas_attestation", "template": "coinbase_verified_account",
"label": "KYC-attested entity" },
{ "type": "ratio_to_amount", "chainId": 8453,
"contractAddress": "0x8335...USDC on Base",
"multiple": "1.5", "amount": "48000",
"label": "Operating account covers 1.5x this payment" },
{ "type": "token_balance", "chainId": 1,
"contractAddress": "0xA0b8...USDC on Ethereum",
"threshold": "250000",
"label": "Mainnet float above policy floor" },
{ "type": "token_balance", "chainId": "xrpl",
"contractAddress": "rMxC...RLUSD issuer", "currency": "RLUSD",
"threshold": "100000",
"label": "RLUSD reserve above floor" },
{ "type": "token_balance", "chainId": "bitcoin",
"contractAddress": "native", "threshold": "5",
"label": "BTC cold reserve intact" },
{ "type": "token_balance", "chainId": "tron",
"contractAddress": "TR7N...USDT on Tron", "threshold": "150000",
"label": "USDT payment float above floor" }
]
}
Six booleans come back across five chains, each block-anchored (blockNumber on EVM chains, ledgerIndex on XRPL, block height on Bitcoin), all under one signature. One call, one credit.
Two details I want to highlight for developers:
ratio_to_amount is the payment check that never goes stale. A flat threshold tuned for $48,000 invoices is wrong for $480,000 invoices. With a ratio you pass the transaction amount and your risk multiple per request, and the signed boolean is always scaled to the payment in front of you: balance >= multiple * amount.
The caller never learns a balance. The service knows the operating account holds at least 1.5x this payment. It does not know if that is $72,001 or $40 million. That asymmetry is why a counterparty is willing to answer at all. (One documented trade-off: Merkle proof mode on a token_balance condition does reveal the raw balance to the caller, since the proof is of the balance storage slot itself. Standard mode never does.)
Verify the signature yourself
The response is ECDSA P-256 signed. kid tells you which scheme: insumer-attest-v2 signs a domain-separated canonical preimage of {v, id, pass, results, attestedAt} with keys sorted recursively. The public key is in a standard JWKS at:
https://insumermodel.com/.well-known/jwks.json
So verification is any JOSE library plus the documented preimage, or npm install insumer-verify if you want it done for you. Add "format": "jwt" to the request and you also get the whole attestation as an ES256 JWT that any standard JWT library can verify against the same JWKS, which makes the verdict portable: hand it to another service and they can check it without calling anyone.
And for the one clause that could change a block later, you do not have to take the API's word at all. Request the delegation check with proof: "merkle" and the response carries an EIP-1186 storage proof of the DelegationManager's revocation slot, verifiable against the block header from any source you trust. "Unrevoked as of block N" stops being an assertion and becomes arithmetic.
No API key? The agent can pay per call
The part I find most fitting: the machine this was built for does not need an account. Send the request with no credential headers and the API responds with an HTTP 402 quote. Sign an EIP-3009 USDC authorization on Base, retry with the X-PAYMENT header, and the attestation comes back. Five cents, gasless for the payer, settled on-chain. An agent can go from never having heard of the API to holding a signed delegation verdict in two HTTP requests.
The menu is bigger than this scenario
Everything above is one composition. The same endpoint takes up to ten conditions per call, mixed across 38 chains, from nine condition types: token balances (including native BTC, TRX, XLM, SUI), NFT ownership (34 of the 38 chains), EAS attestations by template or raw schema, Farcaster identity, arbitrary boolean view calls against your own contracts (hasAccess(address) style), ratio rules against an amount or against total supply, and the two agent-standing types shown here.
The shape of the answer never changes: wallet state, checked against conditions you wrote, at a block, signed. Not a score. Nobody's model weighed anything. The policy (the 1.5x multiple, the reserve floors, which attestation counts as KYC) stays in your request where an auditor can read it, and the facts come back signed where an auditor can verify them. Fourteen months later, when someone asks why your service let a bot move $48,000, you are not defending an opinion. You are handing over arithmetic.
Docs, if you want to try it: verification API reference, state attestation spec. Free tier is an email and 100 reads a day, or skip the key entirely and pay per call over x402.
Top comments (0)