The 32 core endpoints. Authentication, response format, rate limits, and every parameter documented. The full surface (46 operations across 42 paths, including key lifecycle and billing) is in the OpenAPI spec.
Building this in Claude Code? Install the wallet auth skill for guided integration: git clone https://github.com/insumerapi/insumer-skill.git ~/.claude/skills/insumer
See how the core endpoints connect → API Topology
Two methods. Use either one per request, not both.
Send an X-API-Key header. Keys use the format insr_live_ followed by 40 hex characters. Get a free key at /developers/quickstart/. Public endpoints (no key needed): JWKS, compliance templates, code validation, merchant directory, token registry, and discount check.
Alternative to X-API-Key on five endpoints: POST /v1/attest, POST /v1/trust, POST /v1/trust/batch, GET /v1/credits, and POST /v1/credits/buy. For agents whose key was purchased via POST /v1/keys/buy. Send Authorization: Wallet <base64(JSON({message, signature}))>, where message is a SIWE string with domain api.insumermodel.com and signature is an EIP-191 personal_sign. The signing wallet must be the wallet that bought the key and must hold the Insumer Access pass on Base. Single-use nonce; Issued At must be within the last 5 minutes. Other endpoints return 501 for this scheme. Wallet auth authenticates the caller only: every wallet evaluated by an attest or trust call comes from the request body, is independent of the signer, and is not required to match it. To bind a verdict to the presenting wallet, verify that wallet's own signature first, then attest the recovered address. Drop-in middleware: @skyemeta/access on npm.
https://api.insumermodel.com
All endpoints are relative to this base URL.
| Plan | Verification Credits | Requests / Day | Price |
|---|---|---|---|
| Free | 10 (one-time) | 100 | $0 |
| Pro | 1,000/mo | 10,000 | $29/mo |
| Enterprise | 5,000/mo | 100,000 | $99/mo |
Reads (GET requests) use the daily limit and are free. Credits live on the API key and are consumed by attest, trust, and batch trust endpoints. A store has no balance of its own: a discount code (verify, ACP, UCP) or NFC tap that carries a discount uses one credit from the API key that owns the store, and a 0% result is free; every in-store scan uses one credit from that key. A caller using another key is not charged; if you call with the owner key, your key pays. See full pricing, per-call costs, and volume discounts →
{
"ok": true,
"data": { /* endpoint-specific */ },
"meta": {
"version": "1.0",
"timestamp": "2026-02-27T12:00:00Z"
}
}
{
"ok": false,
"error": {
"code": 401,
"message": "Invalid or missing API key."
},
"meta": {
"version": "1.0",
"timestamp": "2026-02-27T12:00:00Z"
}
}
{
"ok": false,
"error": {
"code": 402,
"message": "Insufficient credits (0 available, 3 required). Buy more via POST /v1/credits/buy."
}
}
# Two different 402s exist on /v1/attest, /v1/trust and /v1/trust/batch.
# THIS one means a valid key ran dry: top up at POST /v1/credits/buy.
# The other is the x402 pay-per-call quote, returned when a request arrives
# with NO credential headers at all, and it carries an accepts[] array.
# Branch on the presence of accepts[], not on the status code.
{
"ok": false,
"error": {
"code": 429,
"message": "Daily rate limit exceeded. Resets in 42 minutes."
}
}
# The free tier allows 100 requests a day. Credits and the daily limit are
# separate ceilings: you can hold credits and still be rate limited.
{
"ok": false,
"error": {
"code": "rpc_failure",
"message": "Unable to verify all conditions — data source unavailable after retries",
"failedConditions": [
{ "source": "balance_read", "chainId": 1, "message": "data source unreachable" }
]
},
"meta": { "version": "1.0", "timestamp": "..." }
}
Returned when an upstream data source is unavailable after retries. No attestation signed, no JWT, no credits charged. Retry after 2–5 seconds. Applies to: /v1/attest, /v1/trust, /v1/verify, /v1/acp/discount, /v1/ucp/discount, /v1/discount/check. /v1/trust/batch returns 200 instead, with an error entry in the results array for any wallet whose reads failed.
| Method | Endpoint | Description |
|---|---|---|
| Verification | ||
| POST | /v1/attest | Boolean attestation across 37 chains |
| GET | /v1/jwks | JWKS public key for signature verification |
| GET | /v1/compliance/templates | List available compliance templates |
| Trust | ||
| POST | /v1/trust | Wallet trust profile (155–176 checks) |
| POST | /v1/trust/batch | Batch trust profiles (up to 10) |
| Commerce | ||
| POST | /v1/acp/discount | Generate ACP-format discount |
| POST | /v1/ucp/discount | Generate UCP-format discount |
| GET | /v1/codes/{code} | Validate discount code (public) |
| POST | /v1/verify | Verify wallet and get discount |
| POST | /v1/payment/confirm | Confirm code redemption |
| GET | /v1/discount/check | Check discount eligibility |
| Merchants | ||
| GET | /v1/merchants | List published merchants |
| GET | /v1/merchants/{id} | Get merchant details |
| GET | /v1/tokens | List supported tokens |
| Onboarding | ||
| POST | /v1/merchants | Create merchant programmatically |
| POST | /v1/merchants/{id}/domain-verification | Request domain verification token |
| PUT | /v1/merchants/{id}/domain-verification | Trigger domain verification check |
| PUT | /v1/merchants/{id}/verification | Partner asserts domain (partner keys only) |
| PUT | /v1/merchants/{id}/tokens | Update accepted tokens |
| PUT | /v1/merchants/{id}/nfts | Update accepted NFTs |
| PUT | /v1/merchants/{id}/settings | Update merchant settings |
| POST | /v1/merchants/{id}/credits | Buy credits for the owner key (compatibility) |
| POST | /v1/merchants/{id}/directory | Publish to / unpublish from directory |
| GET | /v1/merchants/{id}/status | Get merchant setup status |
| POST | /v1/registry/submit | Submit a token/NFT to the registry (pending) |
| White-Label Scanner | ||
| POST | /v1/merchants/{id}/scanners | Add or remove a scanner PIN |
| GET | /v1/merchants/{id}/scanners | List a merchant's scanners |
| POST | /v1/scanner/session | Validate a scanner PIN, return config |
| POST | /v1/pass/verify | Verify a scanned pass, return discount |
| Account | ||
| POST | /v1/keys/buy | Buy API key with USDC, USDT, or BTC (no auth) |
| GET | /v1/credits | Check credit balance |
| POST | /v1/credits/buy | Buy credits with USDC, USDT, or BTC |
Boolean attestation. Checks token balances, NFT ownership, EAS attestations, Farcaster identity, arbitrary boolean view calls, dimensionless ratio rules, account code, and agent standing across 37 chains. Returns ECDSA P-256 signed result with a post-quantum signature (pqSig/pqKid). Up to 10 conditions per request. Full docs →
| Parameter | Type | Description |
|---|---|---|
| wallet | string required* | EVM wallet address (0x + 40 hex). Required unless a non-EVM wallet field is provided |
| solanaWallet | string optional | Solana wallet address (raw base58; .sol domain resolution not supported). Required if any condition uses chainId "solana" |
| xrplWallet | string optional | XRPL wallet address (r-address). Required if any condition uses chainId "xrpl" |
| bitcoinWallet | string optional | Bitcoin address (P2PKH, P2SH, bech32, or Taproot). Required if any condition uses chainId "bitcoin" |
| tronWallet | string optional | Tron wallet address (T-prefixed, base58, 34 chars). Required if any condition uses chainId "tron". Supports native TRX and TRC-20 tokens (e.g. USDT-TRC20) |
| stellarWallet | string optional | Stellar wallet address (G-prefixed StrKey, 56 chars). Required if any condition uses chainId "stellar". Supports native XLM and classic trustline assets (USDC, BENJI). Soroban contract balances not visible |
| suiWallet | string optional | Sui wallet address (0x + 64 hex chars). Required if any condition uses chainId "sui". Supports native SUI and Sui-native tokens (e.g. USDC) |
| conditions | array required | Array of condition objects (max 10). Each has: type, contractAddress, chainId, threshold, decimals (plus assetCode for Stellar trustlines, currency for XRPL trustlines, multiple/amount for ratio_to_amount, minFraction for ratio_to_supply). decimals is optional: the token's own decimals are always read from the chain and are the scale, and a value you send is a cross-check (a value that differs from the token's own is a 400 that names the token's own value; a value that is not an integer from 0 to 100 is a 400). On Sui, contractAddress must be a coin type (address::module::Name); anything else is a 400. Types: token_balance, nft_ownership, eas_attestation, farcaster_id, evm_view_call (arbitrary bool-returning view function, requires selector in the form "functionName(address)", EVM chains only), ratio_to_amount (balance ≥ multiple × amount, EVM chains only), ratio_to_supply (balance / totalSupply ≥ minFraction, EVM chains and ERC-20 tokens only), erc8004_agent (ERC-8004 agent registration; requires agentId as a uint256 decimal string; Base only), erc7710_delegation (ERC-7710 delegation validity; requires delegationManager, expectedDelegator, and the signed delegation object; Base only; max 3 per request; attestations containing one expire in 5 minutes). Both agent types are generally available on any API key, and reachable with no key at all via x402 pay-per-call ($0.05 standard rate). erc8004_agent does not support Merkle proofs; erc7710_delegation does. With proof: "merkle" it returns an EIP-1186 revocation proof (subject: "delegation_revocation") on DelegationManagers whose storage layout has been verified on-chain. account_code (the code state of the wallet address itself at the anchored block; requires expect: "none" for a plain key account, "eip7702" for the EIP-7702 delegation designator, or "contract" for any other code, the three exclusive on a chain; optional delegate with "eip7702" only, an EVM address the designator must point at, a 400 with any other expect; any EVM chain, a non-EVM chainId is a 400; the result is the boolean met, the code and the delegation target are never returned; 1 credit, x402 at the standard rate; with proof: "merkle" an account proof whose codeHash is the proven value, subject: "account_code"). Full docs → chainId accepts EVM integers (Ethereum=1, Base=8453, XDC=50, Robinhood Chain=4663, Arc=5042, etc.) or strings "solana", "xrpl", "bitcoin", "tron", "stellar", "sui". On v2 keys (every newly created key), threshold and the ratio fields multiple / amount / minFraction are decimal strings (e.g. "100", "0.005"), not JSON numbers, and a number returns 400. v1 keys accept either; a string is valid on both. All of these are token/display units, not base units or wei: "100" means 100 whole USDC and "0.001" means 0.001 ETH. Decimals are auto-detected, so a base-unit value is not rejected: it is a valid request for a much larger amount and returns met: false |
| proof | string optional | Set to "merkle" for EIP-1186 proofs. 2 credits instead of 1, refunded whenever no proof is delivered. Storage proofs on 27 of 31 EVM chains; contractAddress "native" returns an account proof (subject "account_balance"), and an account_code condition returns an account proof with codeHash as the proven value (subject "account_code") |
| format | string optional | Set to "jwt" to include a Wallet Auth by InsumerAPI token (ES256-signed JWT), verifiable by any standard JWT library using JWKS. The jwt is unchanged by the post-quantum signature, and a pqJwt is returned beside it: a compact JWS with alg: "ML-DSA-65", signed under the post-quantum key. A verifier that checks the post-quantum signature binds it to the jwt by the whole claim set, comparing parsed JSON and never bytes, and reports any difference as refuted (see specification Section 12, Check 6). No additional cost |
| declaredLimits | string optional | Default "include". Set to "omit" to leave the decoded caveat limits out of erc7710_delegation results, which then carry declaredLimitsOmitted: true. Use it when the attestation will be forwarded to third parties and the principal's spending ceiling should not travel with it. met, delegationHash and conditionHash are byte-identical either way. No additional cost |
Returns the JWKS (JSON Web Key Set) containing the ECDSA P-256 public key used to sign attestation and trust responses and the ML-DSA-65 post-quantum key as RFC 9964 AKP entries appended after the EC entries. 24-hour cache. Also available as a static file at /.well-known/jwks.json.
No parameters. Returns { keys: [{ kty: "EC", crv, x, y, kid, alg, use }, ..., { kty: "AKP", alg: "ML-DSA-65", pub, kid, use }] }
Responses sign under one of three key IDs over the same P-256 key: insumer-attest-v1 (legacy keys), insumer-attest-v2 (new keys, domain-separated), and insumer-trust-v2 (trust profiles). Select the key by the kid on the response; never hardcode one. The two AKP entries that follow, insumer-attest-pq1 and insumer-trust-pq1, hold the ML-DSA-65 key for the post-quantum signature (pqSig/pqKid); resolve them by the pqKid on the response. See the signing spec.
Lists all available compliance templates with their condition configurations. Full docs →
No parameters. Returns data.templates, keyed by name, each with provider, description, chainId and chainName: coinbase_verified_account, coinbase_verified_country, coinbase_one (Base), gitcoin_passport_score, gitcoin_passport_active (Optimism).
Generates an ECDSA-signed wallet trust profile with curated presence checks across up to 14 dimensions: stablecoins (52), governance (8), nfts (3), staking (5), institutional_stablecoins (8), tokenized_treasuries (16), stablecoin_deposits (39), wrapped_bitcoin (12), names (2), account (10: contract code and EIP-7702 delegation present, on Ethereum, Base, Arbitrum, Optimism and Polygon), 155 base checks across 27 chains, plus optional solana (14), xrpl (3), bitcoin (1) and tron (3) dimensions. Up to 176 checks across 29 chains. Dimensions come back in a fixed order, the same for every wallet. conditionSetVersion is "2026-10-08" on every key version and names the check list that was run. 3 credits per call. Full docs →
| Parameter | Type | Description |
|---|---|---|
| wallet | string required | EVM wallet address (0x + 40 hex) |
| solanaWallet | string optional | Solana wallet address. Adds the 14-check solana dimension (USDC, OUSD, PYUSD, USDG, USD1, USDS, EURC, BUIDL, USDY, cbBTC, WBTC, tBTC, jitoSOL, mSOL) and evaluates the Solana institutional_stablecoins checks |
| xrplWallet | string optional | XRPL wallet address (r-address). Adds the xrpl dimension (RLUSD, USDC, OUSG) and evaluates EURCV on XRPL |
| bitcoinWallet | string optional | Bitcoin address. Adds the bitcoin dimension (native BTC presence check) |
| tronWallet | string optional | Tron T-address. Adds the tron dimension (USDT, USD1, WBTC) |
| stellarWallet | string optional | Stellar G-address. Evaluates the institutional_stablecoins checks for USDC and BENJI on Stellar (classic trustlines) |
| suiWallet | string optional | Sui 0x + 64 hex address. Evaluates USDC on Sui (institutional_stablecoins) and USDY on Sui (tokenized_treasuries) |
| proof | string optional | Set to "merkle" for storage proofs. EVM token rows carry a storage proof when the token's balance slot can be discovered; rows whose balance is computed rather than stored (Aave aTokens, BUIDL) and tokens with non-standard storage layouts are declined with a stated reason; NFT, non-EVM and account rows are declined (account rows with a reason pointing at /v1/attest); a check that was not evaluated carries no proof key at all; the premium is refunded whenever no proof is delivered. 6 credits instead of 3 |
Batch trust profiles for up to 10 wallets in a single request, each profile signed separately. 3 credits per wallet. Partial success supported.
| Parameter | Type | Description |
|---|---|---|
| wallets | array required | Array of objects (max 10). Each has: wallet (required), and optional solanaWallet, xrplWallet, bitcoinWallet, tronWallet, stellarWallet, suiWallet |
| proof | string optional | Set to "merkle" for storage proofs. 6 credits per wallet |
Check wallet state against the store's conditions and generate a discount code in OpenAI/Stripe ACP format. Cost, errors and the hourly limit are the same as /v1/verify. Full docs →
| Parameter | Type | Description |
|---|---|---|
| merchantId | string required | Merchant ID from the registry |
| wallet | string required* | EVM wallet address (0x...) |
| solanaWallet | string optional | Solana wallet address |
| xrplWallet | string optional | XRPL wallet address (r-address). The checksum is verified; an address that fails it returns 400 |
| walletProof | object optional | Proof that the caller controls wallet: { message, signature }, an EIP-4361 message signed by that EVM wallet, with domain api.insumermodel.com or the store’s own website, URI https://api.insumermodel.com/v1/merchants/{merchantId}, Issued At within the last 5 minutes and an unused nonce. A store can give unproven wallets a lower discount or a daily limit; a proven wallet gets the full discount. A proof that fails is refused (401, or 400 when it is not a { message, signature } object) and uses no credit. Send it with wallet only |
| items | array optional | Cart items with path and amount (minor units). Supply items or subtotal to receive an applied discount |
| subtotal | number optional | Order-level base in minor units (a fraction is truncated), for callers that do not send line items. Ignored when items is supplied |
Check wallet state against the store's conditions and generate a discount code in Google UCP format. Cost, errors and the hourly limit are the same as /v1/verify.
| Parameter | Type | Description |
|---|---|---|
| merchantId | string required | Merchant ID from the registry |
| wallet | string required* | EVM wallet address (0x...) |
| solanaWallet | string optional | Solana wallet address |
| xrplWallet | string optional | XRPL wallet address (r-address). The checksum is verified; an address that fails it returns 400 |
| walletProof | object optional | Proof that the caller controls wallet: { message, signature }, an EIP-4361 message signed by that EVM wallet, with domain api.insumermodel.com or the store’s own website, URI https://api.insumermodel.com/v1/merchants/{merchantId}, Issued At within the last 5 minutes and an unused nonce. A store can give unproven wallets a lower discount or a daily limit; a proven wallet gets the full discount. A proof that fails is refused (401, or 400 when it is not a { message, signature } object) and uses no credit. Send it with wallet only |
| items | array optional | Cart items with path and amount (minor units). Supply items or subtotal to receive an applied discount |
| subtotal | number optional | Order-level base in minor units (a fraction is truncated), for callers that do not send line items. Ignored when items is supplied |
Validate a discount code. Public endpoint, no API key required. Returns code status, merchant, discount percentage, and expiry.
| Parameter | Type | Description |
|---|---|---|
| code | string required | Path parameter. The discount code to validate |
Invalid codes return reason: "not_found" | "expired" | "already_used"
Verify wallet token/NFT holdings against a merchant's configured requirements and return a discount code if eligible. A code that carries a discount costs one credit from the API key that owns the store; a 0% result is free, and a caller using another key is not charged. 402 when the owner key has no credits left (only for a code that carries a discount); 403 when the store has no active owner API key; Paid discount codes requested with a key other than the store's owner are subject to an hourly limit (429; the message says when to try again). The result is signed first; the credit is taken and the code is stored together after that, and a coupon is created only once the code exists. A result that cannot be signed, or a code that cannot be stored, answers 503 in the standard error envelope with no credit used and no code created. A read that does not complete answers 503 rpc_failure. Both are safe to retry.
| Parameter | Type | Description |
|---|---|---|
| merchantId | string required | Merchant ID from the registry |
| wallet | string required* | EVM wallet address (0x...) |
| solanaWallet | string optional | Solana wallet address |
| xrplWallet | string optional | XRPL wallet address (r-address). The checksum is verified; an address that fails it returns 400 |
| walletProof | object optional | Proof that the caller controls wallet: { message, signature }, an EIP-4361 message signed by that EVM wallet, with domain api.insumermodel.com or the store’s own website, URI https://api.insumermodel.com/v1/merchants/{merchantId}, Issued At within the last 5 minutes and an unused nonce. A store can give unproven wallets a lower discount or a daily limit; a proven wallet gets the full discount. A proof that fails is refused (401, or 400 when it is not a { message, signature } object) and uses no credit. Send it with wallet only |
Verify an on-chain USDC payment and mark a discount code as used. Confirms the transaction on-chain before accepting.
| Parameter | Type | Description |
|---|---|---|
| code | string required | The discount code to confirm (INSR-XXXXX) |
| txHash | string required | On-chain USDC transaction hash |
| chainId | number|"solana" required | Chain ID of the payment (e.g. 1, 8453, "solana") |
| amount | number|string required | USDC amount paid |
Check if a wallet is eligible for a discount at a specific merchant without generating a code. Answers 503 rpc_failure when a read does not complete: nothing is concluded about the wallet, so retry. A frozen XRPL trust line earns no tier.
| Parameter | Type | Description |
|---|---|---|
| merchant | string required | Query parameter. Merchant ID |
| wallet | string optional | Query parameter. EVM wallet address |
| solanaWallet | string optional | Query parameter. Solana wallet address |
| xrplWallet | string optional | Query parameter. XRPL wallet address (r-address). The checksum is verified; an address that fails it returns 400 |
List all published merchants in the directory. Returns merchant name, ID, location, accepted tokens, and discount tiers.
| Parameter | Type | Description |
|---|---|---|
| token | string query | Filter by token symbol |
| verified | string query | Filter by domain verification status ("true" or "false") |
| limit | integer query | Results per page (default 50, max 200) |
| offset | integer query | Pagination offset |
Get full details for a specific merchant including accepted tokens, NFTs, discount configuration, and business info.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant document ID |
List all tokens supported across the platform with contract addresses, chain IDs, decimals, and logos.
| Parameter | Type | Description |
|---|---|---|
| chain | integer|string query | Filter by chain ID |
| symbol | string query | Filter by token symbol |
| type | string query | Filter by "token" or "nft" |
Create a new merchant programmatically. The API key that creates it owns it and pays one credit for each code or tap at the store that carries a discount (a 0% result is free) and for every in-store scan; the store has no balance of its own. A key can create a limited number of merchants (429 past it). Full docs →
| Parameter | Type | Description |
|---|---|---|
| companyName | string required | Display name (max 100 chars) |
| companyId | string required | Unique ID. Alphanumeric, dash, underscore (2-50 chars) |
| location | string optional | City or region (max 200 chars) |
Generate a verification token for proving domain ownership. Supports DNS TXT record, HTML meta tag, or verification file. Each POST regenerates the token.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| domain | string required | Domain to verify (e.g. example.com). No protocol prefix. |
Check all three verification methods (DNS TXT, meta tag, file) for the previously requested domain. Rate limited per merchant (429 says when to retry).
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
Configure which tokens the merchant accepts and the minimum balance required for discounts.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| ownToken | object|null optional | Merchant's own token config (symbol, chainId, contractAddress, decimals, tiers; currency for an XRPL trust line token). Send null or {"enabled": false} to switch it off; any other non-boolean enabled returns 400. A tier discount is a whole number from 1 to 50: a value with a fraction returns 400. A Solana mint, an XRPL issuer address and an XRPL currency code are validated, and a value that fails returns 400. decimals is required but not used when a discount is evaluated |
| partnerTokens | array optional | Array of partner token configs, same structure as ownToken |
Configure which NFT collections the merchant accepts for discounts.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| nftCollections | array required | Array of NFT objects with contractAddress, chainId, name, discount. Max 4. discount is a whole number from 1 to 50: a value with a fraction returns 400. A Solana mint, an XRPL issuer address and an XRPL taxon (integer 0 to 4294967295) are validated, and a value that fails returns 400 |
Update discount stacking mode, cap, the store’s terms for wallets sent without a walletProof, and USDC payment settings. All fields optional.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| discountMode | string optional | "highest" (best single discount), "stack" (sum all) or "capped" (sum all, then cap at discountCap) |
| discountCap | integer optional | Maximum total discount percentage, a whole number from 1 to 100. A value with a fraction returns 400 |
| maxDiscountsPerWalletPerDay | integer|null optional | The store’s limit on discount codes per UTC day for a wallet sent without a walletProof, a whole number from 1 to 100; null removes it. Past the limit, /v1/verify, /v1/acp/discount and /v1/ucp/discount return 429 with no credit used |
| maxUnprovenDiscount | integer|null optional | The most a wallet sent without a walletProof can get, a whole number from 0 to 100 (0 = no discount); null gives it the same discount as a proven wallet |
| usdcPayment | object|null optional | USDC payment config (enabled, evmAddress, solanaAddress, preferredChainId) or null to disable |
| paused | boolean optional | true pauses the store’s recognition, false resumes it. While paused, discount codes for the store are refused with 409 (“This store’s recognition is paused.”; no credit used, no code created), /v1/pass/verify answers recognized: false with paused: true, and the store is left out of GET /v1/merchants. Resuming restores everything |
Kept for compatibility. Buys credits with USDC, USDT or BTC into the regular balance of the API key that owns the merchant, the same balance that pays for the store's codes, scans and taps. Flat $0.04 per credit (25 credits per $1) at every purchase size. POST /v1/credits/buy is the normal way to top up and carries the volume tiers. See wallet addresses →
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| txHash | string required | USDC transfer transaction hash |
| chainId | integer|string required | Chain where USDC was sent |
| amount | number required | USDC amount sent (min 5, human-readable units) |
| updateWallet | boolean optional | Set to true to change the registered sender wallet. Default false |
Sender verification: The first purchase registers the sender wallet to the API key. Subsequent purchases must come from the same sender. To change the registered wallet, include "updateWallet": true; the verified transfer proves ownership.
Publish (or refresh) the merchant's listing in the public directory. No request body needed to publish. Send { "listed": false } to unpublish (delist). Partner-provisioned merchants (created with an externalId) must pass domain verification before they can publish.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| listed | boolean optional | Set false to unpublish. Omit to publish/refresh |
Get the setup completion status for a merchant. Shows which steps are done: domain verified, tokens configured, published, etc.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
Record that a managing white-label partner verified an org's domain in its own branded flow, so the org can publish to the directory without seeing an Insumer-branded challenge. Sets verification.status=verified with method=partner. Restricted to designated white-label partner keys: self-serve keys get 403 and must use the domain-verification challenge flow above.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| domain | string required | Domain the partner verified (no protocol prefix) |
Submit a token or NFT collection to the public registry as pending for human approval. API key required (free: no credits charged). Idempotent per chain + address. A submission is held as pending until approved; some are added at once (the response says which: pending, active). Returns a flat envelope (no data wrapper).
| Parameter | Type | Description |
|---|---|---|
| name | string required | Display name |
| assetType | string optional | "token" or "nft". If omitted, inferred from standard, defaulting to "nft" |
| symbol | string required for tokens | Ticker symbol. A token submission without one returns 400 |
| contractAddress | string required* | EVM contract address (or mintAddress for Solana), or "native" for the chain's own asset |
| chainId | number or string required | Positive integer for EVM, or "solana" |
| chainName, image, standard, website, description | string optional | Listing metadata |
| source | string optional | Provenance tag shown in the admin review queue |
Lets a partner run its own branded scanner against merchants it manages, with no dashboard account required. The partner builds only UI; InsumerAPI does all the cryptographic verification. There is deliberately no pass “sign” endpoint: signing is the InsumerAPI primitive and is never exposed as an API call. Scanners only verify passes that InsumerAPI itself issued.
Add a scanner PIN ({ name?, pin }, 4–8 digits; a merchant can hold a limited number of scanners) or remove one ({ remove: scannerId }). Owner key only. PINs are stored salted + hashed and never returned.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
| pin | string optional* | 4–8 digits (to add a scanner) |
| name | string optional | Scanner label (default “Register”) |
| remove | string optional* | Scanner id to remove |
List a merchant's scanners (id and name only; PINs are never exposed). Owner key only.
| Parameter | Type | Description |
|---|---|---|
| id | string required | Path parameter. Merchant ID |
Validate a scanner PIN and return the merchant config for a login-less branded scanner. Owner key only. Repeated failed PIN attempts are limited per merchant (429).
| Parameter | Type | Description |
|---|---|---|
| merchantId | string required | Merchant ID |
| pin | string required | 4–8 digit scanner PIN |
Verify a scanned pass and compute the discount. InsumerAPI verifies the ECDSA signature on the scanned QR, enforces 65-second freshness, then computes the discount against the merchant config. A bad signature is rejected with no discount. Metered on the partner key.
| Parameter | Type | Description |
|---|---|---|
| merchantId | string required | Merchant ID |
| qr | object required | The scanned pass object including its sig (signed bytes are the object with sig removed) |
Check your current credit balance and plan tier.
No parameters. Returns apiKeyCredits, tier, and dailyLimit.
Buy a new API key with USDC, USDT, or BTC. Agent-friendly: no email or prior authentication needed. The sender wallet from the transaction becomes the key's identity. See wallet addresses and volume discounts →
| Parameter | Type | Description |
|---|---|---|
| txHash | string required | Transfer transaction hash |
| chainId | integer|string required | Chain where payment was sent. Supported: ETH (1), Base (8453), Polygon (137), Arbitrum (42161), Optimism (10), BNB (56), Avalanche (43114), Solana ("solana"), Bitcoin ("bitcoin"), Tron ("tron", USDT-TRC20) |
| amount | number required for stablecoins | USDC/USDT amount sent (min 5). Not required for BTC (USD value derived from on-chain amount at market rate) |
| appName | string required | Name for the API key (e.g. your agent or app name, max 100 chars) |
| keyDelivery | string optional | Credential shape: "wallet" | "apiKey" | "both", default "wallet", case-insensitive. Default suppresses the API key string in the response when the Insumer Access pass mints to the sender wallet on EVM: the wallet + pass is the credential. Pass "apiKey" or "both" to receive a key string in addition |
How it works: Send USDC, USDT, or BTC to the platform wallet on any supported chain, then call this endpoint with the transaction hash. The on-chain transfer is verified (BTC requires 1 confirmation), a new API key is created, and credits are added at volume-discount rates. USDC and USDT are accepted at face value; BTC is converted to USD at the market rate. One key per wallet. Use POST /v1/credits/buy to top up an existing key.
Response fields: On EVM purchases an Insumer Access pass (non-transferable ERC-721 on Base) is minted to the sender wallet; details are in the passMint block. The response also carries authMethod ("wallet" | "apiKey" | "both") indicating which credentials were delivered, and on the wallet path a human-readable authHint. The key field is conditionally present: omitted by default when the pass mints, returned when keyDelivery is "apiKey"/"both", and returned regardless on non-EVM purchases (Solana, BTC, Tron) or when the pass mint defers, so no buyer is left without a usable credential.
Purchase additional verification credits using USDC, USDT, or BTC on supported chains. See wallet addresses and volume discounts →
| Parameter | Type | Description |
|---|---|---|
| txHash | string required | Transfer transaction hash |
| chainId | integer|string required | Chain where payment was sent. Supported: ETH (1), Base (8453), Polygon (137), Arbitrum (42161), Optimism (10), BNB (56), Avalanche (43114), Solana ("solana"), Bitcoin ("bitcoin"), Tron ("tron", USDT-TRC20) |
| amount | number required for stablecoins | USDC/USDT amount sent. Not required for BTC |
| updateWallet | boolean optional | Set to true to change the registered sender wallet. Default false. Ignored for wallet-auth callers (see Sender verification below) |
Auth: Accepts X-API-Key or Authorization: Wallet (SIWE envelope from a wallet that holds the Insumer Access pass). Wallet-auth callers let an SBT-holding agent top up without ever handling an API key. See Authentication →
Sender verification: The first purchase registers the sender wallet to the API key. Subsequent purchases must come from the same sender. To change the registered wallet, include "updateWallet": true; the verified transfer proves ownership. Wallet-auth callers: updateWallet is ignored. The SIWE signer is already bound to the registered wallet and the soulbound Insumer Access pass cannot follow a rotation, so honouring the rewrite would silently lock the caller out on the next sign-in. To rotate, use X-API-Key auth.