---
title: "Create on-chain verification"
method: POST
path: "/v1/attest"
tags: ["Wallet Auth"]
---

# Create on-chain verification

`POST /v1/attest`

## Request

- Base URL: `https://api.insumermodel.com`
- URL: `https://api.insumermodel.com/v1/attest`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in header `Authorization`

Verify 1-10 on-chain conditions: token balances, NFT ownership, EAS attestations, Farcaster identity, arbitrary boolean view calls (evm_view_call), the dimensionless ratio rules (ratio_to_amount, ratio_to_supply), account code (account_code: is the wallet a plain key, an EIP-7702-delegated key, or a contract, optionally delegated to a named address), and agent standing (erc8004_agent, erc7710_delegation). Returns ECDSA-signed booleans, never raw balances or code. 1 credit standard, 2 with proof="merkle". EAS: use a compliance template or raw schemaId. Agent conditions, generally available on any API key: erc8004_agent (is this wallet a registered ERC-8004 agent — owner of or bound to agentId N in the Identity Registry on Base) and erc7710_delegation (is this signed ERC-7710 delegation from principal P to this agent wallet currently valid, and what limits does it declare). Both are Base (8453) only and cost 1 credit. erc8004_agent does not support Merkle proofs. erc7710_delegation does: proof="merkle" returns an EIP-1186 storage proof of the revocation slot (subject "delegation_revocation", 2 credits), on DelegationManagers whose storage layout has been verified on-chain — currently the v1.3.0 manager on Base. Both are also reachable with no API key at all via x402 pay-per-call: call with no credential headers, take the 402 quote, pay the quoted amount in USDC on Base, Polygon, Arbitrum, Arc, or Solana, and retry with the PAYMENT-SIGNATURE header — $0.05 at the standard per-call rate. Account code, generally available on any API key and on x402: account_code (what code sits at the wallet address itself at the anchored block: expect "none", "eip7702" or "contract", and with "eip7702" an optional delegate the designator must point at). Any EVM chain, 1 credit, answered as met only; the code and the delegation target are never returned. A trust profile reports the same two facts (contract code present, EIP-7702 delegation present) per chain in its account dimension without naming a target; this condition is where a caller asks about a named one. Attestations containing an erc7710_delegation condition expire in 5 minutes (not the standard 30) — revocation is one transaction away, so the verdict window stays tight. On a delegation, met is the verdict; declaredLimits is a separate signed decode of the caveat terms the caller submitted, each entry carrying the raw terms hex so the decode can be checked independently. Send declaredLimits: "omit" to leave that decode out of a forwarded attestation. Authentication: this endpoint accepts EITHER the X-API-Key header OR the Authorization: Wallet header (SIWE envelope from a wallet that holds the Insumer Access pass).

## Query parameters

- `proof` 'merkle'

## Request body

- object
  - `wallet` string: EVM wallet address (0x...)
  - `solanaWallet` string: Solana wallet address (base58, 32-44 chars). Required if any condition uses chainId "solana".
  - `xrplWallet` string: XRPL wallet address (classic r-address). The base58 checksum is verified; an address that fails it returns 400 rather than a signed not-met result.
  - `bitcoinWallet` string: Bitcoin address (P2PKH, P2SH, bech32, or Taproot). Required if any condition uses chainId "bitcoin".
  - `tronWallet` string: Tron address (T-prefix, base58, 34 chars). Required if any condition uses chainId "tron". Tron supports TRC-20 (e.g. USDT) and native TRX via contractAddress "native".
  - `stellarWallet` string: Stellar address (G-prefix StrKey, 56 chars; the checksum is verified). Required if any condition uses chainId "stellar". Stellar checks measure classic-account balances (trustlines + native XLM); Soroban contract-held balances are out of scope. Trustline conditions require both contractAddress (G-issuer) and assetCode.
  - `suiWallet` string: Sui address (0x + 64 hex chars, 32-byte). Required if any condition uses chainId "sui". Coin type goes in contractAddress (e.g., "0x2::sui::SUI" for native, or "<package>::<module>::<TYPE>" for any other coin). Response envelope surfaces checkpointSequence as the temporal anchor.
  - `proof` 'merkle': Set to "merkle" to include EIP-1186 Merkle storage proofs in results. Proofs are attempted for token_balance and ratio_to_amount conditions on all 31 EVM chains (a ratio_to_amount proof proves the same ERC-20 balance slot), and returned for erc7710_delegation conditions on DelegationManagers whose storage layout has been verified on-chain (currently the v1.3.0 manager on Base). A delegation proof carries subject: "delegation_revocation" and proves the value of disabledDelegations[delegationHash] against the anchored block's state root — so "not revoked as of block N" becomes checkable rather than taken on the API's word. Where a chain cannot serve a proof, or the token's storage slot cannot be discovered (a zero ERC-20 balance whose slot is not yet known, or a non-standard storage layout), the result carries proof.available: false with a reason instead. In practice 27 of the 31 EVM chains serve proofs today; ZKsync Era (324), Sei (1329), Viction (88) and XDC Network (50) do not. Always unavailable: nft_ownership, eas_attestation, farcaster_id, ratio_to_supply, and erc8004_agent conditions; conditions on Solana, XRPL, Bitcoin, Tron, Stellar, and Sui; and delegations against a manager whose layout has not been verified (an inferred slot would yield a proof of the wrong location that still verifies against the header, which is worse than no proof). Costs 2 credits instead of 1; whenever no proof is delivered the premium is refunded and the request costs 1, whatever the reason: a read that did not complete, a chain or token that cannot carry a proof, or a condition type that has none. A condition with contractAddress "native" carries an ACCOUNT proof (subject "account_balance") instead of a storage proof. An account_code condition carries an account proof too (subject "account_code"): its codeHash field is the proven value, which a verifier compares with the hash the expected state implies (keccak256 of empty code for "none", keccak256 of 0xef0100 followed by the delegate the verifier supplies for "eip7702", anything else for "contract"); an account absent from the state trie may report codeHash as all zeros, which also means no code. Note: in proof mode the account record's fields (balance, nonce, storageHash, codeHash) reach the caller; on a token_balance condition that is the raw on-chain balance (standard mode never returns it).
  - `format` 'jwt': Set to "jwt" to include a Wallet Auth by InsumerAPI token (ES256-signed JWT) in the response. The JWT contains the attestation data as standard claims (iss, sub, jti, iat, exp) plus pass, results, conditionHash, blockNumber, and blockTimestamp. sub is the wallet a condition in the request evaluated. A wallet field that no condition reads is ignored and never named. When conditions span chain families, sub names the first evaluated family in the order EVM, Solana, XRPL, Bitcoin, Tron, Stellar, Sui; the other families' wallets are evaluated but not named by sub. format "jwt" needs at least one condition that evaluates a wallet. The exp claim matches the attestation's expiresAt: iat + 1800 (30 minutes), or iat + 300 (5 minutes) when the request contains an erc7710_delegation condition, so a JWT never outlives the attestation it carries. Verifiable by any standard JWT library using the JWKS at https://insumermodel.com/.well-known/jwks.json. No additional cost.
  - `declaredLimits` 'include' | 'omit': Controls whether decoded caveat limits ride along with erc7710_delegation results. Default (field absent, or "include"): declaredLimits are returned inside the signed results, and therefore also travel inside the portable JWT when format: "jwt" is used. Set to "omit" and the decoded limits are left out; the result carries declaredLimitsOmitted: true instead. Use "omit" when the attestation will be FORWARDED to third parties and the principal's spending ceiling should not travel with it — a delegation attestation in JWT form is portable, so by default the declared limits reach anyone it is passed to. That is usually what you want (a relying party needs the limits to act), but not always. The caller loses nothing by omitting: it submitted the caveats and already holds them. Critically, met, delegationHash, and conditionHash are byte-identical either way — a forwarded token still commits to exactly which delegation was checked, and a holder can verify a limit shown to them out-of-band without ever learning one from the token. No effect on any other condition type. No additional cost.
  - `conditions` Condition[], required
    - `type` 'token_balance' | 'nft_ownership' | 'eas_attestation' | 'farcaster_id' | 'evm_view_call' | 'ratio_to_amount' | 'ratio_to_supply' | 'erc8004_agent' | 'erc7710_delegation' | 'account_code', required
    - `expect` 'none' | 'eip7702' | 'contract': Required for account_code. The code state the wallet address itself must be in at the anchored block: "none" (no code: a plain key account), "eip7702" (the EIP-7702 delegation designator: a key that has delegated execution to a contract), or "contract" (any other code: a smart-contract wallet, a protocol, a token). The three are exclusive on a chain. The result is the boolean met; the code and the delegation target are never returned. EVM chains only (a non-EVM chainId is a 400). 1 credit. Proof mode returns an EIP-1186 account proof whose codeHash field is the proven value (subject "account_code").
    - `delegate` string: Optional, account_code with expect "eip7702" only (a 400 with any other expect). An EVM address: the condition is met iff the wallet's designator points at this address. A caller who cares which contract names it here and still receives only yes or no; when supplied it is echoed inside the signed evaluatedCondition so the hash binds the question asked.
    - `contractAddress` string: Token or NFT contract address (required for token_balance, nft_ownership, ratio_to_amount, ratio_to_supply, and evm_view_call; use "native" for the chain's native asset on token_balance and ratio_to_amount; nft_ownership requires the NFT contract, ratio_to_supply an ERC-20 contract and evm_view_call a real contract, and "native" on any of those three is a 400. To ask whether a wallet holds the native coin, use token_balance with "native"). For Solana: "native" for SOL, or the mint address (base58, 32 to 44 characters); anything else is a 400. For XRPL: use "native" for XRP, or the issuer r-address for trust line tokens and NFTs; the base58 checksum is verified, so a mistyped issuer is a 400. For Tron: "native" for TRX, or a TRC-20 contract address (starts with T; the checksum is verified, so a mistyped address is a 400). For Stellar: "native" for XLM, or the asset issuer's G-address (StrKey, 56 chars; the checksum is verified, so a mistyped issuer is a 400). For Bitcoin: must be "native". For Sui: must be a coin type (address::module::Name, optionally with type parameters); the short form (0x2::sui::SUI) and the 64-hex long form of an address name the same coin, and anything that is not a coin type is a 400. On two chains the native asset is ALSO exposed as an ERC-20 at a mirror contract, so "native" and that address are one balance read two ways: Celo 42220 (0x471EcE3750Da237f93B8E339c536989b8978a438) and Arc 5042 (USDC predeploy 0x3600000000000000000000000000000000000000, which is Arc's gas asset). TWO token_balance conditions requiring BOTH in one call count the same holding twice, so that pair is refused with a 400 naming both condition indexes before any credit is charged — use one or the other. The guard covers token_balance pairs only; a ratio_to_amount rule is not summed against a token_balance threshold, so that combination is redundant rather than refused.
    - `selector` string: Required for evm_view_call. The canonical signature of a view function returning bool, in the form "functionName(address)" (e.g. "hasAccess(address)"). v1 supports single-address-argument view functions only; the 4-byte selector is derived from this signature. EVM chains only.
    - `chainId` union: EVM chain ID (integer), or one of "solana", "xrpl", "bitcoin", "tron", "stellar", "sui" (string). Supported chains: Ethereum (1), BNB Chain (56), Base (8453), Avalanche (43114), Polygon (137), Arbitrum (42161), Optimism (10), Chiliz (88888), Soneium (1868), Plume (98866), Sonic (146), Gnosis (100), Mantle (5000), Scroll (534352), Linea (59144), zkSync Era (324), Blast (81457), Taiko (167000), Ronin (2020), Celo (42220), Viction (88), opBNB (204), World Chain (480), Unichain (130), Ink (57073), Sei (1329), Berachain (80094), ApeChain (33139), XDC Network (50), Robinhood Chain (4663), Arc (5042), Solana ("solana"), XRP Ledger ("xrpl"), Bitcoin ("bitcoin"), Tron ("tron"), Stellar ("stellar"), Sui ("sui"). Bitcoin only supports token_balance with contractAddress "native". Tron, Stellar, and Sui support token_balance only. Moonbeam (1284) and Moonriver (1285) were retired on 2026-09-20 after both networks stopped producing blocks. GLMR and MOVR now live on Base (chainId 8453) as ERC-20s and are read with an ordinary token_balance condition; a request naming either retired chain returns 400.
      - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
      - 'solana' | 'xrpl' | 'bitcoin' | 'tron' | 'stellar' | 'sui'
    - `threshold` union: Minimum balance required (token_balance type), in token/display units — e.g. "100" for 100 USDC or "0.001" for 0.001 ETH, NOT base units/wei. The token's own decimals are read from the chain (a decimals value in the request is a cross-check, never an override) and the raw balance is scaled before comparison, so a base-unit threshold such as "1000000" for 1 USDC is a valid request for one million USDC and simply returns met: false. v1 keys take a JSON number (e.g. 100). v2 keys — which is every newly created key — require a decimal STRING (e.g. "100"); a JSON number is rejected with 400. v2 carries the threshold as an exact canonical decimal so an agent can specify full-precision thresholds that a JSON float would silently round. Must be > 0 (use "0.000001" / 0.000001 for prove-any-balance). A decimal string is at most 400 characters.
      - number
      - string
    - `multiple` union: Required for ratio_to_amount. The collateralization multiple — the condition is met iff balance >= multiple * amount (e.g. 10 for "hold >= 10x the transaction amount"). v1 keys take a JSON number; v2 keys — every newly created key — require a decimal STRING (e.g. "10") and reject a JSON number with 400. Must be > 0. A decimal string is at most 400 characters.
      - number
      - string
    - `amount` union: Required for ratio_to_amount. The per-request reference amount (e.g. the transaction size the agent intends to make), in token/display units — e.g. 100 for 100 USDC, NOT base units/wei. v1: JSON number; v2: decimal STRING (e.g. "100"). Must be > 0. An amount with more decimal places than the token has is a 400. ratio_to_amount is supported on EVM chains only. A decimal string is at most 400 characters.
      - number
      - string
    - `minFraction` union: Required for ratio_to_supply. The required share of the token's on-chain total supply, as a fraction in (0, 1] — e.g. 0.005 for 0.5% of supply. The condition is met iff balance / totalSupply() >= minFraction. v1: JSON number; v2: decimal STRING (e.g. "0.005"). Use for project/governance tokens where share-of-supply is meaningful (not stablecoins). Supported on EVM chains, ERC-20 contracts only. A decimal string is at most 400 characters.
      - number
      - string
    - `decimals` union: Optional, for token_balance and ratio_to_amount. The token's own decimals are always read from the chain: decimals() on EVM and Tron at the anchored block, the coin metadata on Sui; native coins are fixed by definition. A scale is never taken from the request and never assumed. When sent, decimals is a cross-check. It must be an integer from 0 to 100 (a JSON number, or its digits as a string); anything else is a 400. If it equals the token's own value nothing changes; if it differs the API returns 400 and the message names the token's own value. A token that states no decimals on chain: a zero balance is signed as met: false (zero is zero at any scale); any other balance is a 400 on every key, because no scale exists for the threshold to be read at and none is ever taken from the request. If the token's decimals cannot be read (an upstream failure) the API returns the documented 503 rpc_failure, never a 400. Why: a threshold is in display units, so the verdict depends on the scale, and the relying party must be able to trust that the scale is the token's own.
      - integer
      - string
    - `currency` string: XRPL currency code (required for XRPL trust line tokens, ignored for other chains). One of: a 3-character standard code (e.g. "USD"; letters, digits and ?!@#$%^&*<>(){}[]| only), a token name of 1 to 20 printable ASCII characters (e.g. "RLUSD", hex-encoded to a 40-character code), or a 40-character hex currency code. Anything else, including a non-string, is a 400. Currency codes are case-sensitive on the XRP Ledger: send the code exactly as the issuer created it. `USD` and `usd` are different currencies, and a token name is encoded in the letter case sent. `XRP` is the native coin, not a trust line currency: on a trust line condition it is a 400, as are its 40-character hex spellings. To check XRP, use contractAddress "native". The 40-character hex spelling of a 3-character code is that code, and is returned in the 3-character form. The code is carried inside the signed evaluatedCondition, so it can only ever be well-formed Unicode.
    - `assetCode` string: Stellar trustline asset code (e.g. "USDC"): 1 to 12 characters from a-z, A-Z, 0-9. Required for Stellar trustline token_balance conditions (contractAddress is the G-issuer); not used for native XLM. Anything outside that alphabet, or a non-string, is a 400. The code is carried inside the signed evaluatedCondition, so it can only ever be well-formed Unicode.
    - `taxon` integer: XRPL NFToken taxon filter (optional, for XRPL conditions): an integer from 0 to 4294967295, as a JSON number or its digits as a string; anything else (a fraction, a negative, text) is a 400, and so is null on nft_ownership. On nft_ownership it filters NFTs by issuer + taxon; on any XRPL condition a supplied taxon is carried into the signed evaluatedCondition as a JSON number.
    - `label` string: Human-readable label for this condition. It is carried inside the signed result. A longer label is cut to 100 UTF-16 code units rather than rejected, and the cut never splits a surrogate pair: the signed label is always well-formed Unicode (an unpaired surrogate is replaced with U+FFFD), so the signed bytes can be rebuilt in any language.
    - `schemaId` string: EAS schema ID (bytes32 hex string). Required for eas_attestation unless template is provided.
    - `attester` string: Expected attester address (optional, for eas_attestation). If provided, the attestation's attester must match this address (case-insensitive). Recipient is not a request-side field — it auto-binds to the wallet being verified, and the attestation's recipient field must equal that wallet for the condition to pass.
    - `indexer` string: EAS indexer contract address (0x + 40 hex chars; format-validated when present: a malformed value returns 400, as does a malformed attester). Required for raw (non-template) eas_attestation conditions: a raw condition without it returns 400, because without an indexer there is no way to resolve an attestation UID and nothing could be evaluated. Templates supply their own. The API resolves the attestation UID by calling `getAttestationUid(address recipient, bytes32 schema) returns (bytes32)` (selector 0xab2717dd) on this contract, then fetches and verifies the resolved attestation against the EAS contract on the target chain. Custom EAS issuers must deploy or co-list in such an indexer; see /developers/compliance/#custom-eas-issuers.
    - `template` 'coinbase_verified_account' | 'coinbase_verified_country' | 'coinbase_one' | 'gitcoin_passport_score' | 'gitcoin_passport_active': Pre-configured compliance template name. Use instead of raw schemaId/attester/indexer — the template fills in all three. See GET /v1/compliance/templates for available templates.
    - `agentId` string: Required for erc8004_agent (generally available on any API key, and on x402 pay-per-call with no key). The ERC-8004 agent ID as a uint256 decimal string. Must be supplied by the caller — the deployed Identity Registry has no wallet-to-agentId reverse lookup. The condition is met iff the attested wallet owns the agent NFT (ownerOf) or is the registry's on-chain signature-verified agentWallet binding (getAgentWallet). Registry: ERC-8004 Identity Registry 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 on Base; chainId 8453 only. tokenURI JSON is never trusted. Note the honest semantics: ERC-8004 registration is permissionless NFT minting — the signed statement is exactly "registered in registry R at agentId N, owned by / bound to this wallet" and implies no vetting, no reputation, no endorsement. Merkle proofs are not available for this type.
    - `delegationManager` string: Required for erc7710_delegation (generally available on any API key, and on x402 pay-per-call with no key). The DelegationManager contract address the delegation was signed against. Must be one of the three recognized MetaMask Delegation Framework managers on Base (framework versions 1.0.0 / 1.1.0 / 1.3.0; current default 0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3). chainId 8453 only. Max 3 erc7710_delegation conditions per request. Merkle proofs ARE available for this type: with proof: "merkle" the result carries an EIP-1186 storage proof of the revocation slot (subject "delegation_revocation"), for managers whose storage layout has been verified on-chain — currently the v1.3.0 manager 0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3 on Base. Other recognized managers return proof.available: false with a reason naming the unverified layout, because an inferred slot would produce a proof of the wrong location that still verifies against the block header.
    - `expectedDelegator` string: Required for erc7710_delegation. The principal address the caller asserts authorized this agent. The condition fails unless the delegation's declared delegator matches this address — without it a self-delegation would read as authority, so there is no structural-only mode.
    - `delegation` object: Required for erc7710_delegation. The signed ERC-7710 delegation to evaluate. The condition is met iff ALL of: the attested wallet is the delegate; the declared delegator is expectedDelegator; the EIP-712 signature verifies (EOA recovery, or ERC-1271 for contract principals); the delegation is not revoked on-chain as of the anchored block; every caveat uses a recognized enforcer (an unknown enforcer fails the condition, no override); and any time-window caveat is currently satisfied. Recognized caveat enforcers (5 kinds): timestamp (time window — evaluated now), erc20_transfer_amount, native_transfer_amount, allowed_targets, limited_calls. Recognition is per manager: native_transfer_amount is recognized on the 1.1.0 and 1.3.0 managers only, not on 1.0.0 (a 1.0.0 delegation carrying it fails as an unknown enforcer). The last four are REPORTED as declared limits — on-chain redemption enforces them; the attestation states what the principal signed, it does not simulate enforcement. Keep the two apart: `met` is the verdict — the boolean listed above, and nothing more. `declaredLimits` is NOT an input to that boolean; it is a signed DECODE of the caveat terms the caller itself submitted, riding alongside the verdict inside the signed results — on true and false verdicts alike, once the signature and revocation checks pass. Each decoded entry carries the exact `terms` hex it was decoded from, so the decode is a checkable claim rather than an assertion: re-run the enforcer contract's public getTermsInfo byte layout against `terms` and compare, and recompute `delegationHash` (in evaluatedCondition — the EIP-712 struct hash committing to every caveat's enforcer and terms) from the delegation object you hold. Set the top-level `declaredLimits` request modifier to "omit" to leave the decode out of the signed results entirely. Attestations containing a delegation condition expire in 5 minutes (not the standard 30) — revocation is one transaction away, so the verdict window stays tight; the verdict states "not revoked as of block N".
      - `delegator` string, required: Principal address that signed the delegation. Must equal expectedDelegator.
      - `delegate` string, required: Agent wallet the delegation authorizes. Must equal the attested wallet.
      - `authority` string, required: Root authority only (0xffff…ffff, 32 bytes of 0xff). Delegation chains are unsupported in v1.
      - `caveats` object[], required: Caveats the principal signed (max 16). Every enforcer must be recognized or the condition fails.
        - `enforcer` string, required: Caveat enforcer contract address
        - `terms` string, required: ABI-encoded caveat terms (hex)
      - `salt` string, required: Delegation salt (decimal string)
      - `signature` string, required: EIP-712 signature over the delegation (hex). EOA recovery, or ERC-1271 for smart-contract principals.

## Response `200`

Verification created

- object
  - `ok` true
  - `data` object
    - `attestation` Attestation
      - `id` string: Format: ATST- followed by 16 uppercase hex characters
      - `pass` boolean: true only when ALL conditions are met
      - `results` AttestationResult[]
        - `condition` integer: Index of the condition in the request array
        - `label` string
        - `type` 'token_balance' | 'nft_ownership' | 'eas_attestation' | 'farcaster_id' | 'evm_view_call' | 'ratio_to_amount' | 'ratio_to_supply' | 'erc8004_agent' | 'erc7710_delegation' | 'account_code'
        - `chainId` union: EVM chain ID (integer), or one of "solana", "xrpl", "bitcoin", "tron", "stellar", "sui" (string). Supported chains: Ethereum (1), BNB Chain (56), Base (8453), Avalanche (43114), Polygon (137), Arbitrum (42161), Optimism (10), Chiliz (88888), Soneium (1868), Plume (98866), Sonic (146), Gnosis (100), Mantle (5000), Scroll (534352), Linea (59144), zkSync Era (324), Blast (81457), Taiko (167000), Ronin (2020), Celo (42220), Viction (88), opBNB (204), World Chain (480), Unichain (130), Ink (57073), Sei (1329), Berachain (80094), ApeChain (33139), XDC Network (50), Robinhood Chain (4663), Arc (5042), Solana ("solana"), XRP Ledger ("xrpl"), Bitcoin ("bitcoin"), Tron ("tron"), Stellar ("stellar"), Sui ("sui"). Bitcoin only supports token_balance with contractAddress "native". Tron, Stellar, and Sui support token_balance only. Moonbeam (1284) and Moonriver (1285) were retired on 2026-09-20 after both networks stopped producing blocks. GLMR and MOVR now live on Base (chainId 8453) as ERC-20s and are read with an ordinary token_balance condition; a request naming either retired chain returns 400.
          - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
          - 'solana' | 'xrpl' | 'bitcoin' | 'tron' | 'stellar' | 'sui'
        - `met` boolean
        - `evaluatedCondition` EvaluatedCondition: The exact condition logic that was evaluated, included for tamper-evidence. Callers can recompute conditionHash from this object to verify integrity.
          - `type` 'token_balance' | 'nft_ownership' | 'eas_attestation' | 'farcaster_id' | 'evm_view_call' | 'ratio_to_amount' | 'ratio_to_supply' | 'erc8004_agent' | 'erc7710_delegation' | 'account_code'
          - `chainId` union: EVM chain ID (integer), or one of "solana", "xrpl", "bitcoin", "tron", "stellar", "sui" (string). Supported chains: Ethereum (1), BNB Chain (56), Base (8453), Avalanche (43114), Polygon (137), Arbitrum (42161), Optimism (10), Chiliz (88888), Soneium (1868), Plume (98866), Sonic (146), Gnosis (100), Mantle (5000), Scroll (534352), Linea (59144), zkSync Era (324), Blast (81457), Taiko (167000), Ronin (2020), Celo (42220), Viction (88), opBNB (204), World Chain (480), Unichain (130), Ink (57073), Sei (1329), Berachain (80094), ApeChain (33139), XDC Network (50), Robinhood Chain (4663), Arc (5042), Solana ("solana"), XRP Ledger ("xrpl"), Bitcoin ("bitcoin"), Tron ("tron"), Stellar ("stellar"), Sui ("sui"). Bitcoin only supports token_balance with contractAddress "native". Tron, Stellar, and Sui support token_balance only. Moonbeam (1284) and Moonriver (1285) were retired on 2026-09-20 after both networks stopped producing blocks. GLMR and MOVR now live on Base (chainId 8453) as ERC-20s and are read with an ordinary token_balance condition; a request naming either retired chain returns 400.
            - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
            - 'solana' | 'xrpl' | 'bitcoin' | 'tron' | 'stellar' | 'sui'
          - `expect` 'none' | 'eip7702' | 'contract': The code state the condition asked for (present only for account_code conditions). With operator code_state the result is met iff the code at the wallet address at blockNumber is in this state; nothing read from the chain is echoed here.
          - `contractAddress` string: Contract address that was queried (token_balance, nft_ownership, ratio_to_amount, and ratio_to_supply). For XRPL: "native" or issuer r-address. For evm_view_call: the contract whose view function was called.
          - `operator` 'gte' | 'gt' | 'valid' | 'decoder' | 'registered' | 'view_call_true' | 'gte_fraction' | 'owner_or_bound_wallet' | 'authorized_by_principal' | 'code_state': Comparison operator used: gte (>=) for token_balance and ratio_to_amount, gte_fraction (balance/totalSupply >=) for ratio_to_supply, gt (>) for nft_ownership, valid for eas_attestation, decoder for Gitcoin Passport, registered for farcaster_id, view_call_true for evm_view_call, owner_or_bound_wallet for erc8004_agent, authorized_by_principal for erc7710_delegation, code_state for account_code (the code at the wallet address is in the state named by expect)
          - `selector` string: The view function signature that was called (present only for evm_view_call conditions)
          - `threshold` union: Threshold value used in comparison (human-readable units for token_balance, 0 for nft_ownership). For ratio_to_amount this is the authoritative derived value (= multiple * amount) that balance was compared against. Not present for eas_attestation or ratio_to_supply. v1 keys return a JSON number; v2 keys — every newly created key — return a canonical decimal string (nft_ownership stays the number 0 on both).
            - number
            - string
          - `multiple` union: Collateralization multiple (present only for ratio_to_amount). Echoed for provenance; threshold (= multiple * amount) is the authoritative comparison value. v1: JSON number; v2: canonical decimal string.
            - number
            - string
          - `amount` union: Reference amount in token/display units (present only for ratio_to_amount). Echoed for provenance; the operative comparison is balance >= threshold. v1: JSON number; v2: canonical decimal string.
            - number
            - string
          - `minFraction` union: Required share of total supply as a fraction in (0, 1] (present only for ratio_to_supply). The condition (balance / totalSupply >= minFraction) is fully described by this plus contractAddress/chainId; the totalSupply read and computed fraction are returned on the result object (siblings of evaluatedCondition), not here, so conditionHash stays a pure rule fingerprint. v1: JSON number; v2: canonical decimal string.
            - number
            - string
          - `decimals` integer, nullable: Token decimals (present only for token_balance and ratio_to_amount conditions). v1 attest responses only. On the 31 EVM chains it is the token's own decimals, as read from the chain. On the other chain families it repeats the value sent in the request, or is null when none was sent. Trust profiles always return a non-null value. v2 attest omits this field entirely: the canonical decimal threshold is self-describing.
          - `currency` string: XRPL currency code the condition was evaluated against: a 3-character code, or the 40-character hex form of a token name or hex code. Present when a currency was sent on an XRPL condition; a trust line condition always carries it.
          - `assetCode` string: Stellar trustline asset code. Present only for Stellar trustline token_balance conditions.
          - `taxon` integer: XRPL NFToken taxon filter. Present when a taxon was sent on an XRPL condition.
          - `schemaId` string: EAS schema ID (present only for eas_attestation conditions)
          - `attester` string: Expected attester address (present only for eas_attestation conditions when attester was specified)
          - `decoder` string: Decoder contract address (present only for decoder-based eas_attestation conditions like Gitcoin Passport)
          - `decoderMethod` 'isHuman' | 'getScore': The decoder method that decided the verdict (present only for decoder-based eas_attestation conditions). isHuman: met when the Passport decoder reports the wallet as human (score of at least 20; template gitcoin_passport_score). getScore: met when the score is above zero (template gitcoin_passport_active). Signed, so a verifier can tell the two templates apart; match it as well as decoder.
          - `registry` string: ERC-8004 Identity Registry contract address that was queried, in lower case as signed (present only for erc8004_agent conditions)
          - `agentId` string: Agent ID evaluated, uint256 decimal string (present only for erc8004_agent conditions)
          - `wallet` string: The attested wallet the condition was evaluated against (present only for erc8004_agent and erc7710_delegation conditions)
          - `delegationManager` string: DelegationManager contract address the delegation was verified against (present only for erc7710_delegation conditions)
          - `domainVersion` string: EIP-712 domain version used for signature verification (present only for erc7710_delegation conditions)
          - `frameworkVersion` string: MetaMask Delegation Framework version of the recognized manager: 1.0.0, 1.1.0, or 1.3.0 (present only for erc7710_delegation conditions)
          - `delegationHash` string: Hash of the evaluated delegation (present only for erc7710_delegation conditions)
          - `delegator` string: Declared delegator (principal) from the delegation (present only for erc7710_delegation conditions)
          - `delegate` string: On erc7710_delegation: the declared delegate (agent wallet) from the delegation. On account_code: the address the caller named, present only when one was supplied; met then also requires the wallet's EIP-7702 designator to point at it. Absent on every other type.
          - `authority` string: Always "root" — delegation chains are unsupported in v1 (present only for erc7710_delegation conditions)
          - `expectedDelegator` string: The principal the caller asserted (present only for erc7710_delegation conditions)
          - `signatureType` 'eoa' | 'erc1271' | 'none': How the delegation signature verified (present only for erc7710_delegation conditions). "eoa" means an EOA principal signed the delegation; "erc1271" means a smart-contract principal asserts the delegation is valid — that is a different claim, and both appear distinctly in the signed bytes.
          - `caveatCoverage` 'full' | 'partial': Whether every caveat was evaluated/decoded (present only for erc7710_delegation conditions)
          - `caveatCount` string: Number of caveats in the delegation, as a decimal string inside the signed bytes (present only for erc7710_delegation conditions)
          - `unevaluatedCaveats` string: Number of caveats reported as declared limits rather than evaluated, as a decimal string inside the signed bytes (present only for erc7710_delegation conditions)
        - `conditionHash` string: SHA-256 hash of the canonical (sorted-key) JSON of evaluatedCondition, prefixed with 0x. Callers can recompute this to verify the condition was not tampered with.
        - `totalSupply` string: Raw on-chain totalSupply() read at blockNumber (integer as a string), present only for ratio_to_supply. A reproducibility reference: re-read totalSupply at blockNumber to confirm. Inside the signed results payload but outside conditionHash.
        - `fraction` number: Computed balance / totalSupply at blockNumber (present only for ratio_to_supply, and only on v1 keys; v2 responses omit this field so no float enters the canonical signed bytes). Display/transparency value; verifiers should re-derive met from the raw on-chain reads rather than this float. Can exceed 1.0 for pathological tokens where balanceOf > totalSupply.
        - `agentExists` boolean: Whether the agent NFT exists in the Identity Registry (present only for erc8004_agent conditions)
        - `matchedVia` 'owner' | 'agent_wallet' | 'none': How the attested wallet matched the agent: "owner" (holds the agent NFT via ownerOf), "agent_wallet" (the registry's on-chain signature-verified agentWallet binding via getAgentWallet), or "none". Present only for erc8004_agent conditions. The registry clears the agentWallet binding automatically when the agent NFT transfers — a block-anchored verdict reflects binding truth at that block.
        - `declaredLimits` object[]: Decoded caveat limits the principal signed, with decimal-string amounts in base units (present only for erc7710_delegation conditions, and only when the request did not set declaredLimits: "omit"). These are REPORTED as declared — on-chain redemption enforces them; the attestation states what the principal signed, it does not simulate enforcement. Not part of the met verdict: this is a signed decode of caveat terms the caller itself submitted, a sibling of evaluatedCondition — inside the signed results payload but outside conditionHash. The decode is independently verifiable: each entry carries the exact terms hex it came from, so re-run the enforcer contract's public getTermsInfo byte layout against terms and compare to the decoded values. No external lookup is needed, since the caller supplied those bytes in its own request. Present on both true and false verdicts: the decode is computed once the signature and revocation checks pass, so a delegation failing on unknown_caveat_enforcer (recognized subset only, with unrecognizedEnforcers naming the rest) or outside_time_window still carries it. Failures at or before the signature and revocation checks carry no decode.
          - `kind` 'timestamp' | 'erc20_transfer_amount' | 'native_transfer_amount' | 'allowed_targets' | 'limited_calls': Which recognized caveat enforcer this entry decodes. Field set per kind: timestamp → timestampAfter, timestampBefore; erc20_transfer_amount → token, maxAmount; native_transfer_amount → maxAmount; allowed_targets → targets (array); limited_calls → maxCalls.
          - `enforcer` string: Caveat enforcer contract address the entry was decoded for
          - `terms` string: The exact hex bytes this entry was decoded from — the caveat terms as submitted in the request. Re-run the enforcer's public getTermsInfo byte layout against this value to check the decode yourself. The signed evaluatedCondition also carries delegationHash, the EIP-712 struct hash committing to every caveat's enforcer and terms, so a verifier can recompute that hash from the delegation object it holds and confirm it matches.
          - `token` string: Token contract the limit applies to (erc20_transfer_amount only)
          - `maxAmount` string: Ceiling as a decimal string in base units (erc20_transfer_amount, native_transfer_amount)
          - `targets` string[]: Addresses the delegation may call (allowed_targets only)
          - `maxCalls` string: Maximum number of redemptions, decimal string (limited_calls only)
          - `timestampAfter` string: Start of the signed time window, decimal string (timestamp only)
          - `timestampBefore` string: End of the signed time window, decimal string (timestamp only)
        - `declaredLimitsOmitted` boolean: Present and true when the request set declaredLimits: "omit" (erc7710_delegation conditions only). The decoded limits were left out so a forwarded attestation does not carry the principal's spending ceiling. met, delegationHash, and conditionHash are byte-identical to the include case, so the attestation still commits to exactly which delegation was checked.
        - `unrecognizedEnforcers` string[]: Enforcer addresses that were not recognized, when the condition fails on unknown caveats (present only for erc7710_delegation conditions)
        - `failReason` 'delegate_mismatch' | 'principal_mismatch' | 'invalid_signature' | 'delegator_not_deployed' | 'revoked' | 'unknown_caveat_enforcer' | 'outside_time_window': Why the delegation condition failed (present only for failing erc7710_delegation conditions)
        - `blockNumber` string: Hex block number at which the condition was evaluated. Present on all 31 EVM chains. Every other chain family carries its own anchor instead: slot (Solana), ledgerIndex (XRPL, Stellar), blockHeight (Bitcoin, Tron), checkpointSequence (Sui). The API refuses to sign any attestation whose anchor could not be captured or whose chain state could not be read, returning 503 instead: a failed read is never reported as met: false.
        - `blockTimestamp` string, date-time: ISO 8601 timestamp of the block at which the condition was evaluated. Present on all 31 EVM chains and co-required with blockNumber.
        - `ledgerIndex` integer: Validated ledger index the result is anchored to. Present only for XRPL and Stellar conditions. On XRPL every read behind the result is pinned to this one validated ledger, so it names the state that was read. On Stellar it is the latest ledger, captured alongside the read: a freshness anchor.
        - `ledgerHash` string: Hash of the ledger named by ledgerIndex. Present only for XRPL and Stellar conditions.
        - `trustLineState` object: Trust line state flags for XRPL trust line token conditions. Present only for non-native XRPL token_balance conditions.
          - `frozen` boolean: Whether the trust line is frozen: a freeze set on the line by either side, or an issuer that has frozen everything it issued. A frozen line means the balance is not spendable.
        - `slot` integer: Solana slot the result is anchored to. Present only for Solana conditions. It is a floor: the wallet state was observed at this slot or later (across a paged read it is the lowest slot any page reported). Verifiers can reproduce the read by querying wallet state at this slot or later.
        - `blockHeight` integer: Chain tip block height at the time of wallet state observation. Present only for Bitcoin and Tron conditions. Evidence-of-freshness anchor: the height binds the observation to a recent tip rather than to a specific block's state (Bitcoin's UTXO model does not permit reproducible balance-at-block queries).
        - `blockHash` string: Chain tip block hash at the time of wallet state observation (64-character lowercase hex on Bitcoin). Present only for Bitcoin and Tron conditions. Co-reported with blockHeight.
        - `checkpointSequence` integer: Sui checkpoint sequence number, captured alongside the read. A freshness anchor: it binds the observation to a recent checkpoint rather than naming the exact state that was read. Present only for Sui conditions.
        - `proof` union: Present only when proof: "merkle" is requested
          - MerkleProof: EIP-1186 Merkle proof for trustless verification against block headers. Four kinds of proof exist today (three carry a subject; the ERC-20 balance-slot proof carries none): a token_balance or ratio_to_amount condition against an ERC-20 proves the balance slot (no subject field; a ratio_to_amount proof proves the same slot a token_balance proof does); the same condition with contractAddress "native" proves the account itself (subject: "account_balance"): a native balance is a field of the account rather than a mapping entry, so it carries an ACCOUNT proof with no storageProof, mappingSlot or storageKey, and its balance field is the value evaluated; an account_code condition proves the same account record with codeHash as the evaluated field (subject: "account_code"); and an erc7710_delegation condition proves the revocation slot (subject: "delegation_revocation").
            - `available` true
            - `type` 'merkle'
            - `balance` string: Hex-quantity native balance proven by the account branch. Present on subjects "account_balance" and "account_code" (the record has four fields and a verifier rebuilds all of them). On "account_balance" it equals the value the condition was evaluated against at blockNumber, and is served only when the two agree.
            - `nonce` string: Hex-quantity account nonce from the same branch. Present on subjects "account_balance" and "account_code".
            - `codeHash` string: Account code hash from the same branch. Present on subjects "account_balance" and "account_code". On "account_code" it is the evaluated field: keccak256 of empty code (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) means no code, keccak256 of 0xef0100 followed by the 20-byte target means an EIP-7702 delegation to that target, anything else means contract code; an account absent from the state trie may report it as all zeros, which also means no code. Served only when it agrees with the code the condition was evaluated against.
            - `subject` 'account_balance' | 'account_code' | 'delegation_revocation': What the proof is about. Three values today. "account_balance" on a token_balance or ratio_to_amount condition whose contractAddress is "native": the proof is the account's own branch of the state trie and its balance field is the value evaluated. "account_code" on an account_code condition: the same account branch, with codeHash as the value evaluated. "delegation_revocation" on an erc7710_delegation condition: the proof covers disabledDelegations[delegationHash] in the DelegationManager's storage. All are against the anchored block's state root. An ERC-20 balance-slot proof carries no subject field, so the field's ABSENCE is what identifies that variant; do not read a missing subject as a delegation proof, or a present one as anything other than the three values above.
            - `blockNumber` string: Hex block number at which the proof was generated
            - `contractAddress` string: The contract whose storage was proven. Present on erc7710_delegation proofs, where it is the DelegationManager the proof is against.
            - `mappingSlot` integer: Storage slot of the proven mapping: the ERC-20 balanceOf mapping for a token_balance or ratio_to_amount proof (both prove the same balance slot), or the disabledDelegations mapping for an erc7710_delegation proof. Never inferred — for delegation proofs the layout is verified on-chain first, and managers without a verified layout return no proof at all.
            - `storageKey` string: keccak256(abi.encode(key, uint256(mappingSlot))) storage key. The key is the wallet address for a token_balance or ratio_to_amount proof, or delegationHash for an erc7710_delegation proof. A verifier SHOULD recompute it from the delegationHash carried in the signed evaluatedCondition and confirm it matches the returned value — that recomputation is what binds the proof to this specific delegation, since a proof of some other slot would still verify against the block header.
            - `accountProof` string[]: Merkle proof nodes from state root to account
            - `storageProof` object[]: Merkle proof nodes from storage root to the proven slot
              - …
            - `storageHash` string: Storage root hash of the contract account
          - MerkleProofUnavailable: Returned when Merkle proof is not available for a condition
            - `type` 'merkle': Optional on this variant: some unavailable results (e.g. slot-discovery failures) omit the type field and carry only available and reason.
            - `available` false
            - `transient` boolean: Present when the proof was not produced because of the read rather than a property of the condition. true means a read did not complete and the same request may succeed later. false means the outcome is settled: see unsupportedChain. Absent when the condition itself cannot carry a proof (EAS, Farcaster, erc8004_agent, a zero ERC-20 balance whose storage slot has not yet been discovered, or an unverified DelegationManager). A zero native balance is always provable: its account proof has no storage slot to discover.
            - `unsupportedChain` boolean: Present and true when the chain does not support Merkle storage proofs, so no proof can be produced there and retrying will not change the outcome. Applies to ZKsync Era (324), Sei (1329), Viction (88) and XDC Network (50). The attestation itself is signed and block-anchored as usual, and the proof premium is not charged.
            - `reason` string: Why the proof is unavailable (e.g. a chain that does not support Merkle storage proofs, Solana, nft_ownership, erc8004_agent, a zero ERC-20 balance whose storage slot has not yet been discovered, or an erc7710_delegation whose DelegationManager storage layout has not been verified on-chain)
      - `passCount` integer
      - `failCount` integer
      - `attestedAt` string, date-time
      - `expiresAt` string, date-time: Attestation expires after 30 minutes. Attestations containing an erc7710_delegation condition expire after 5 minutes instead (see POST /v1/attest).
    - `sig` string: ECDSA P-256 signature (base64, P1363). Branch on `kid` to reconstruct the signed bytes: `insumer-attest-v1` → ES256 over JSON.stringify({id, pass, results, attestedAt}); `insumer-attest-v2` → ES256 over the domain-separated, canonical preimage "insumer.attestation.v2\n" + recursive sorted-key canonical JSON of {v:2, id, pass, results, attestedAt} (keys sorted at every level, no whitespace: this is the RFC 8785 / JCS canonical form, so any RFC 8785 serializer reproduces the bytes; all quantities are decimal strings and the only JSON numbers are bounded small integers, so the bytes never depend on a language's floating-point formatting), where the v2 `results[].evaluatedCondition.threshold` is a canonical decimal string and carries no `decimals` field. v1 stays byte-frozen. Verify with `npm install insumer-verify` or `pip install insumer-verify`.
    - `kid` string: Which key + scheme signed this response. insumer-attest-v1 (v1 attest) or insumer-attest-v2 (v2 attest). Resolve the public key from GET /v1/jwks or https://insumermodel.com/.well-known/jwks.json (all EC kids share one key; post-quantum AKP entries are appended after them).
    - `pqSig` string: OPTIONAL post-quantum signature: base64 ML-DSA-65 (FIPS 204) over the post-quantum domain tag plus the exact classical preimage this response's kid selects. A kid a verifier does not recognise selects no preimage, so the post-quantum signature is then unverifiable, never refuted, and no other era's preimage may be substituted for it. Additive; sig and kid are unchanged. See the state attestation spec, Section 12 Check 6.
    - `pqKid` string: OPTIONAL post-quantum key identifier (insumer-attest-pq1 or insumer-trust-pq1), resolved in the JWKS as an RFC 9964 AKP / ML-DSA-65 key.
    - `jwt` string: Wallet Auth by InsumerAPI token — ES256 JWT (only present when format: "jwt" is requested). Verifiable with any standard JWT library using the JWKS endpoint.
    - `pqJwt` string: OPTIONAL sibling of `jwt` when format is `jwt`: a compact JWS with alg ML-DSA-65 (RFC 9964), signed under the post-quantum key insumer-attest-pq1. Additive; `jwt` is unchanged. Verifier contract: after verifying the JWS over its own header.payload bytes, confirm that its payload and the ES256 `jwt` payload carry the identical claim set: the same member names, and for every member a deeply equal JSON value (objects compared without regard to member order, arrays in order, numbers by value). Any difference, whether a changed value, a missing member or an extra member on either side, makes the post-quantum signature `refuted`. Compare PARSED JSON, never bytes: byte-identical payload segments satisfy this trivially, but a verifier MUST NOT require byte identity, since two serializers may order members differently. Checking only `jti`, `exp` and `pass` is not sufficient: it leaves `results` and `conditionHash` unbound. See the state attestation spec, Section 12 Check 6, and test vectors 24 and 25 (the refused cases).
  - `meta` object
    - `creditsRemaining` integer, nullable: Credits left on the key after this call. null on x402-paid calls (creditsCharged is 0 there; the call was paid at the transport layer, not from stored credits).
    - `creditsCharged` integer: 1 for standard, 2 for proof: merkle. 0 on x402-paid calls.
    - `version` string
    - `timestamp` string, date-time

## Other responses

- `400`: Validation error. Beyond the usual per-field checks, one case is easy to hit by writing a reasonable-looking rule: on a chain whose native asset is also an ERC-20 at a mirror contract (Celo, Arc — see contractAddress), two token_balance conditions requiring both "native" and that address read one balance twice, and are refused naming both condition indexes before any credit is charged. Scale and coin type are checked too: a decimals value that differs from the token's own (the message names the token's own value), a decimals value that is not an integer from 0 to 100, a ratio_to_amount amount with more decimal places than the token has, a non-zero balance of a token that states no usable decimals on chain, and a Sui contractAddress that is not a coin type are each a 400. A token whose decimals cannot be read is the 503 rpc_failure instead, never a 400.
- `401`: Invalid or missing API key
- `402`: Payment required. For API-key callers: insufficient verification credits (standard error envelope). For credential-less callers this is the x402 pay-per-call quote (X402Quote body): the v2 payment payload is in the JSON body and, base64-encoded, in the payment-required response header. Pay the quoted amount in USDC on any listed network (Base, Polygon, Arbitrum, Arc, or Solana) and retry with the PAYMENT-SIGNATURE header (X-PAYMENT is still accepted).
- `413`: Body exceeds the pay-per-call size cap. Returned on x402-paid requests whose JSON body is larger than the cap; API-key and wallet-auth calls are not subject to it.
- `429`: Rate limit exceeded. API-key requests count against the key's daily limit; every authenticated response carries X-RateLimit-Limit and X-RateLimit-Remaining headers, and a 429 additionally carries Retry-After (seconds until the window resets).
- `500`: Unexpected server error. Safe to retry; no credits are charged on a 500. Router endpoints return the standard error envelope; standalone endpoints (the ones whose 200 is a flat object) return a flat {"error": "..."} object.
- `503`: Data source unavailable after retries (RpcFailureEnvelope; no attestation signed, no credits charged, retryable after a short delay). Wallet-auth and x402-paid calls can also return 503 as a standard error envelope for transient service conditions (for example the wallet-auth nonce store or payment verification being temporarily unavailable); those are equally retryable. On an Arc (eip155:5042) pay-per-call payment, a 503 can also mean the settlement was submitted but had not confirmed by the server's deadline, or the payment facilitator did not answer. That payment is UNRESOLVED, not refused: the transfer may still land. Retry the exact same request (same body) with the SAME payment header; it resolves to the same payment and cannot charge twice. Do not sign a new authorization. If the payment ultimately failed, the retry returns 402 with a fresh quote and nothing was charged.

---

[API](https://skmtc.dev/insumermodel/apis/insumerapi.md) · [All operations](https://skmtc.dev/insumermodel/apis/insumerapi/llms.txt) · [OpenAPI document](https://skmtc.dev/insumermodel/apis/insumerapi/revisions/91f56fe9e3d8?raw)
