# InsumerAPI — Condition-Based Access Infrastructure (Full API Reference) version: 1.0 > InsumerAPI is condition-based access infrastructure for blockchain state. It reads wallet state, evaluates operator-defined conditions, and returns ECDSA-signed booleans across 33 chains. No secrets. No identity. No static credentials. No balances exposed. Production-tested: used by AsterPay KYA Hook (ERC-8183 agentic commerce), Revettr (counterparty risk scoring), SettlementWitness (SAR pre-transaction verification), and adopted into the Knowledge Context Protocol standard (KCP RFC-0004). ## What Is InsumerAPI? InsumerAPI is the API for condition-based access — an access control model where decisions come from evaluating wallet state against conditions, not from shared secrets, identity lookups, or static credentials. Used by developers, AI agents, and platforms alike. It is read-first: it reads canonical on-chain state, evaluates conditions, and returns signed decision artifacts. It does not write to any blockchain. The core endpoint (`POST /v1/attest`) evaluates up to 10 conditions per request across 33 chains and returns cryptographically signed true/false results. Condition types: `token_balance`, `nft_ownership`, `eas_attestation` (on-chain attestations via Ethereum Attestation Service), and `farcaster_id` (social identity via Farcaster IdRegistry on Optimism). No raw balances. No RPC management. No chain-specific code. **Why agents use this:** If your system needs to answer "does this wallet meet condition X?" across any combination of chains, InsumerAPI replaces building per-chain RPC connections, managing contract ABIs, and handling chain-specific edge cases. One endpoint, one signature, privacy by default. **What this really is:** Verifiable attestation infrastructure for blockchain state. Every response is ECDSA P-256 signed with a discoverable public key (JWKS, RFC 7517). Optionally returns EIP-1186 Merkle storage proofs anchored to block headers for trustless verification. Block number and timestamp included for freshness verification. The result is infrastructure: a signed, timestamped, optionally provable attestation about on-chain state that any system can verify independently. **What this is not:** Not a loyalty program. Not a reputation network. Not an identity system. Not a DeFi protocol. Not a payments processor. Not an oracle network. It is verifiable attestation infrastructure designed to be consumed by those systems. **Autonomous agent loop:** Agents buy their own API key with USDC, USDT, or BTC (`POST /v1/keys/buy` — no email, no human approval), operate, and refuel credits (`POST /v1/credits/buy`) when they run low. Discover → acquire access → operate → refuel → repeat. The closed loop is what makes this autonomous infrastructure, not just an API. ### Use Cases - **AI agent wallet trust verification**: Verify wallet holdings as trust signals for agent identity (returns a fact profile, not a score) - **Token-gated access**: Gate APIs, content, SaaS features, or rate limits behind token ownership - **Agent-to-agent trust**: One agent verifies on-chain holdings, passes the ECDSA signature to another agent for offline verification - **DAO eligibility**: Confirm governance token holdings for voting without exposing portfolio composition - **Compliance gating**: Verify Coinbase Verifications (KYC), Gitcoin Passport (Sybil resistance), Farcaster identity (social), or other EAS attestations on Base, Ethereum, Optimism, Arbitrum, Polygon, Avalanche. Pre-configured compliance templates for instant setup. - **Compliance signals**: Prove minimum balance or staking thresholds with a signed audit trail. Optional Merkle proofs for independently verifiable evidence. - **NFT verification**: Verify collection ownership for bots, platforms, or community gating - **Holder rewards and commerce**: Verify holdings to assign reward tiers or real-world merchant discounts via QR/NFC at point of sale - **Regulated commerce**: Chain trust screening → compliance attestation → condition-based discount in a single multi-step flow (trust → compliance → commerce) - **Agent trust handshake**: Agent verifies counterparty wallet trust profile before delegating tasks or accepting transactions (used by Revettr for x402 counterparty risk) ## Base URL ``` https://api.insumermodel.com ``` All endpoints are prefixed with `/v1/`. ## Authentication Most `/v1/` endpoints require an API key via the `X-API-Key` header. Public endpoints (no key needed): GET /v1/jwks, GET /v1/compliance/templates, GET /v1/codes/{code}, GET /v1/merchants, GET /v1/merchants/{id}, GET /v1/tokens, GET /v1/discount/check. **Key format:** `insr_live_` + 40 hex characters (50 characters total). **Getting a key:** Free tier (instant, 10 verification credits): ``` POST https://api.insumermodel.com/v1/keys/create Content-Type: application/json { "email": "you@example.com", "appName": "My Agent", "tier": "free" } ``` Paid tiers (crypto purchase, 30-day validity): ``` POST https://api.insumermodel.com/v1/keys/purchase Content-Type: application/json { "txHash": "0x...", "chainId": 8453, "tier": "pro", "email": "you@example.com", "appName": "My Agent" } ``` ## Rate Limits & Pricing | Tier | Daily Reads | API Credits | Price | |------|-------------|----------------|-------| | Free | 100/day | 10 (one-time) | $0 | | Pro | 10,000/day | 1,000/mo | $29/mo | | Enterprise | 100,000/day | 5,000/mo | $99/mo | **Reads** (GET requests) use the daily limit and are free. **Two credit pools:** - **API credits** (belong to your API key): consumed by attest (1), trust (3), batch trust (3/wallet). Merkle proofs double the cost. Buy more: POST /v1/credits/buy. - **Merchant credits** (belong to each merchant): consumed by verify, codes, ACP discount, UCP discount (1 each). Buy more: POST /v1/merchants/{id}/credits. **Crypto volume discounts (buy credits on-chain with USDC, USDT, or BTC):** | Deposit | Rate | Credits per $1 | |---------|------|----------------| | $5–$99 | $0.04/call | 25 | | $100–$499 | $0.03/call (25% off) | 33 | | $500+ | $0.02/call (50% off) | 50 | Supported payment chains: Ethereum, Base, Polygon, Arbitrum, Optimism, BNB Chain, Avalanche, Solana (USDC/USDT auto-detected), Bitcoin (BTC converted to USD at market rate, 1 confirmation required). Platform wallets: EVM `0xAd982CB19aCCa2923Df8F687C0614a7700255a23` · Solana `6a1mLjefhvSJX1sEX8PTnionbE9DqoYjU6F6bNkT4Ydr` · Bitcoin `bc1qg7qnerdhlmdn899zemtez5tcx2a2snc0dt9dt0` Crypto sent on unsupported chains cannot be recovered. All credit purchases are final and non-refundable. Rate limit headers on every response: - `X-RateLimit-Limit` — daily read cap - `X-RateLimit-Remaining` — remaining reads today - `Retry-After` — seconds until reset (only on 429) ## Response Envelope **Success:** ```json { "ok": true, "data": { ... }, "meta": { "version": "1.0", "timestamp": "2026-02-22T12:00:00.000Z" } } ``` **Error:** ```json { "ok": false, "error": { "code": 401, "message": "Invalid or missing API key." }, "meta": { "version": "1.0", "timestamp": "..." } } ``` ## Error Codes | Code | Meaning | |------|---------| | 400 | Bad request / validation error | | 401 | Invalid or missing API key | | 402 | Insufficient credits | | 403 | Forbidden (merchant not opted in, or key doesn't own merchant) | | 404 | Resource not found | | 409 | Conflict (duplicate ID, tx already used) | | 410 | Gone (expired code) | | 422 | On-chain verification failed | | 429 | Rate limit exceeded | | 500 | Internal server error | | 503 | Data source unavailable (RPC failure) — retryable | ### RPC Failure (503) When upstream data sources are unreachable after retries, endpoints that produce signed results (`/v1/attest`, `/v1/trust`, `/v1/trust/batch`, `/v1/verify`, `/v1/acp/discount`, `/v1/ucp/discount`) return HTTP 503 with `error.code: "rpc_failure"`. **No attestation signed, no JWT issued, no credits charged.** This is a retryable error — wait 2-5 seconds and retry. ```json { "ok": false, "error": { "code": "rpc_failure", "message": "Unable to verify all conditions — data source unavailable after retries", "failedConditions": [ { "chainId": "43114", "message": "Timeout" } ] }, "meta": { "version": "1.0", "timestamp": "..." } } ``` **Important:** `rpc_failure` is NOT a verification failure. Do not treat it as `pass: false`. The API refused to sign because it could not verify — the wallet may well hold the tokens. ## Supported Chains (33) ### EVM Chains (30) | Chain | ID | Notes | |-------|----|-------| | Ethereum | 1 | | | BNB Chain | 56 | USDC has 18 decimals on this chain | | 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 | | | Moonbeam | 1284 | | | Moonriver | 1285 | | | Viction | 88 | | | opBNB | 204 | | | World Chain | 480 | | | Unichain | 130 | | | Ink | 57073 | | | Sei | 1329 | | | Berachain | 80094 | | | ApeChain | 33139 | | ### Solana Use `chainId: "solana"` (string, not integer). ### XRP Ledger Use `chainId: "xrpl"` (string, not integer). Supports native XRP balance verification, trust line token verification (RLUSD, RWA tokens, any issued token), and NFT ownership verification. For token_balance: use `contractAddress: "native"` for XRP, or the issuer r-address + `currency` field for trust line tokens. Currency codes: 3-char standard (e.g. "USD") or token name (e.g. "RLUSD", auto hex-encoded). No Merkle proofs. Response includes `ledgerIndex` (XRPL equivalent of block number), `ledgerHash` (validated ledger hash for independent snapshot verification), and `trustLineState` (trust line flags — frozen lines fail attestation). **Known XRPL tokens:** | Token | Issuer Address | Currency Code | |-------|---------------|---------------| | RLUSD | rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De | RLUSD | | USDC | rGm7WCVp9gb4jZHWTEtGUr4dd74z2XuWhE | USDC | ### Bitcoin Use `chainId: "bitcoin"` (string, not integer) with the `bitcoinWallet` parameter. Supports native BTC balance verification only (no BRC-20, Ordinals, or Runes). Use `contractAddress: "native"`. All address formats supported: P2PKH (1...), P2SH (3...), bech32/SegWit (bc1q...), and Taproot/bech32m (bc1p...). Confirmed balance only (no unconfirmed transactions). No Merkle proofs. Response includes `blockHeight` (integer) + `blockHash` (64-char hex) — the Bitcoin chain tip at observation time, attached as an evidence-of-freshness anchor. Bitcoin's UTXO model does not permit balance-at-block queries, so the anchor binds the observation to a recent tip rather than to a specific block's state. The API refuses to sign any attestation where the tip lookup fails, returning 503. ### Payment Chains USDC and USDT are auto-detected from EVM and Solana transactions. BTC accepted on Bitcoin. | Chain | chainId | Accepted Tokens | |-------|---------|-----------------| | Ethereum | 1 | USDC, USDT | | Base | 8453 | USDC, USDT | | Polygon | 137 | USDC, USDT | | Arbitrum | 42161 | USDC, USDT | | Optimism | 10 | USDC, USDT | | BNB Chain | 56 | USDC, USDT | | Avalanche | 43114 | USDC, USDT | | Solana | "solana" | USDC, USDT | | Bitcoin | "bitcoin" | BTC (converted to USD at market rate, 1 confirmation required) | **Platform wallets:** - EVM (USDC/USDT): `0xAd982CB19aCCa2923Df8F687C0614a7700255a23` (same on all chains) - Solana (USDC/USDT): `6a1mLjefhvSJX1sEX8PTnionbE9DqoYjU6F6bNkT4Ydr` - Bitcoin (BTC): `bc1qg7qnerdhlmdn899zemtez5tcx2a2snc0dt9dt0` --- # Endpoints ## 0. GET /v1/jwks **Get JWKS (public signing key).** Returns the JSON Web Key Set containing InsumerAPI's ECDSA P-256 public key used to sign attestations and discount codes. No authentication required. Also available as a static file at `https://insumermodel.com/.well-known/jwks.json`. **Response:** ```json { "keys": [ { "kty": "EC", "crv": "P-256", "x": "JtHPhDPnv8AfP0JSlGutxbOlxreV2Chey27Z76q3V2c", "y": "kn34HaxVSJfn8NxwNEBjjLkcrM_GDw1lgnqyADGuc4c", "use": "sig", "alg": "ES256", "kid": "insumer-attest-v1" } ] } ``` The `kid` (key ID) matches the `kid` field in attestation responses. Use `kid` to select the correct key when multiple keys exist (future key rotation). --- ## 1. GET /v1/compliance/templates **List compliance templates.** Returns pre-configured templates for EAS attestation verification. No authentication or credits required. **Response:** ```json { "ok": true, "data": { "templates": { "coinbase_verified_account": { "provider": "Coinbase", "description": "Coinbase Verified Account", "chainId": 8453, "chainName": "Base" }, "coinbase_verified_country": { "provider": "Coinbase", "description": "Coinbase Verified Country", "chainId": 8453, "chainName": "Base" }, "coinbase_one": { "provider": "Coinbase", "description": "Coinbase One Member", "chainId": 8453, "chainName": "Base" }, "gitcoin_passport_score": { "provider": "Gitcoin", "description": "Gitcoin Passport Score (≥20)", "chainId": 10, "chainName": "Optimism" }, "gitcoin_passport_active": { "provider": "Gitcoin", "description": "Gitcoin Passport Active", "chainId": 10, "chainName": "Optimism" } } }, "meta": { "version": "1.0", "timestamp": "..." } } ``` Use a template name in POST /v1/attest conditions instead of specifying raw `schemaId`, `attester`, and `indexer`. The template pre-fills all EAS parameters for the provider. **Custom EAS issuers (raw conditions).** When verifying attestations from a custom EAS schema (no template), three things must be in place: 1. **`schemaId`** (bytes32 hex) — your EAS schema on the target chain. 2. **`attester`** (optional) — if specified, the attestation's attester address must match this value. 3. **`indexer`** (required for raw conditions) — an indexer contract on the target chain that exposes `getAttestationUid(address recipient, bytes32 schema) returns (bytes32)` (selector `0xab2717dd`). The verifier calls this to resolve attestation UID by (recipient, schema), then fetches the attestation from the EAS contract and verifies it. **Recipient binding.** The recipient field is not request-side. The verifier auto-binds it to the wallet being attested and enforces `attestation.recipient == wallet` — an attestation issued to a different recipient will fail the condition regardless of schema or attester match. Custom issuers typically fork Coinbase's open-source EAS Verifications indexer, deploy on the target chain, and wire issuance to write each new (recipient, schema) → UID mapping to the indexer contract. Pass that contract address as the `indexer` field. --- ## 2. POST /v1/attest **Create on-chain verification.** Verify 1-10 conditions and get a signed true/false result. Privacy-preserving: never exposes actual balances. Consumes 1 verification credit (standard) or 2 credits (with `proof: "merkle"`). **Request:** ```json { "wallet": "0x1234...5678", "solanaWallet": "ABC...xyz", "xrplWallet": "rN7n3473SaZBCG4dFL83w7p1W9cgZw6iAF", "proof": "merkle", "conditions": [ { "type": "token_balance", "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "threshold": 1000, "decimals": 6, "label": "USDC >= 1000" }, { "type": "nft_ownership", "contractAddress": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", "chainId": 1, "label": "Bored Ape holder" }, { "type": "eas_attestation", "template": "coinbase_verified_account", "label": "Coinbase KYC verified" }, { "type": "eas_attestation", "template": "gitcoin_passport_score", "label": "Gitcoin Passport verified human" }, { "type": "farcaster_id", "label": "Farcaster registered" }, { "type": "token_balance", "contractAddress": "native", "chainId": "xrpl", "threshold": 100, "label": "XRP >= 100" }, { "type": "token_balance", "contractAddress": "rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De", "currency": "RLUSD", "chainId": "xrpl", "threshold": 50, "label": "RLUSD >= 50" } ] } ``` **Request fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | wallet | string | For EVM conditions | EVM wallet address (0x...) | | solanaWallet | string | For Solana conditions | Solana wallet address (base58) | | xrplWallet | string | For XRPL conditions | XRPL wallet address (r...) | | bitcoinWallet | string | For Bitcoin conditions | Bitcoin address (P2PKH, P2SH, bech32, or Taproot) | | proof | string | No | Set to `"merkle"` for EIP-1186 storage proofs (2 credits) | | format | string | No | Set to `"jwt"` to include a Wallet Auth by InsumerAPI token (ES256-signed JWT) in the response. Verifiable by any standard JWT library using JWKS at `/.well-known/jwks.json`. No additional cost | | conditions | array | Yes | 1-10 condition objects | **Condition fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | type | string | Yes | `"token_balance"`, `"nft_ownership"`, `"eas_attestation"`, or `"farcaster_id"` | | contractAddress | string | For token_balance/nft_ownership | Token/NFT contract address. For XRPL: `"native"` for XRP, or the issuer r-address for trust line tokens | | chainId | int, "solana", or "xrpl" | Yes | Chain identifier (farcaster_id always uses Optimism/10) | | threshold | number | For token_balance | Minimum balance required. Must be > 0 when proof is merkle (use 0.000001 for prove-any-balance) | | decimals | int | No | Token decimals. Auto-detected from contract if omitted. Ignored for XRPL (balances are human-readable) | | currency | string | For XRPL trust line tokens | XRPL currency code: 3-char standard (e.g. `"USD"`) or token name (e.g. `"RLUSD"`, auto hex-encoded). Required when contractAddress is an XRPL issuer address | | taxon | integer | For XRPL NFT ownership | XRPL NFT taxon filter. Optional — if omitted, matches any NFT from the issuer | | label | string | No | Human-readable label (max 100 chars) | | template | string | For eas_attestation | Compliance template name (e.g. `"coinbase_verified_account"`, `"gitcoin_passport_score"`) | | schemaId | string | For eas_attestation (if no template) | EAS schema ID (bytes32 hex) | | attester | string | No | Expected attester address (for eas_attestation) | | indexer | string | No | EAS indexer contract (for eas_attestation) | **Response (standard, without proof):** ```json { "ok": true, "data": { "attestation": { "id": "ATST-A7C3E1B2D4F56789", "pass": false, "results": [ { "condition": 0, "label": "USDC >= 1000", "type": "token_balance", "chainId": 1, "met": true, "evaluatedCondition": { "type": "token_balance", "chainId": 1, "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "operator": "gte", "threshold": 1000, "decimals": 6 }, "conditionHash": "0x3a7f...", "blockNumber": "0x12f4a80", "blockTimestamp": "2026-02-26T12:34:56.000Z" }, { "condition": 1, "label": "Bored Ape holder", "type": "nft_ownership", "chainId": 1, "met": false, "evaluatedCondition": { "type": "nft_ownership", "chainId": 1, "contractAddress": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", "operator": "gt", "threshold": 0 }, "conditionHash": "0x8b2e...", "blockNumber": "0x12f4a80", "blockTimestamp": "2026-02-26T12:34:56.000Z" } ], "passCount": 1, "failCount": 1, "attestedAt": "2026-02-26T12:34:57.000Z", "expiresAt": "2026-02-26T13:04:57.000Z" }, "sig": "base64-ecdsa-p256-signature...", "kid": "insumer-attest-v1" }, "meta": { "creditsRemaining": 42, "creditsCharged": 1, "version": "1.0", "timestamp": "..." } } ``` **Response (with `proof: "merkle"`):** ```json { "ok": true, "data": { "attestation": { "id": "ATST-A7C3E1B2D4F56789", "pass": true, "results": [ { "condition": 0, "label": "USDC >= 1000", "type": "token_balance", "chainId": 1, "met": true, "evaluatedCondition": { "type": "token_balance", "chainId": 1, "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "operator": "gte", "threshold": 1000, "decimals": 6 }, "conditionHash": "0x3a7f...", "blockNumber": "0x12a05f200", "blockTimestamp": "2026-02-26T12:34:56.000Z", "proof": { "available": true, "type": "merkle", "blockNumber": "0x12a05f200", "storageKey": "0xabc...def", "accountProof": ["0x...", "0x..."], "storageProof": [{ "key": "0x...", "value": "0x3b9aca00", "proof": ["0x..."] }], "storageHash": "0x..." } }, { "condition": 1, "label": "Bored Ape holder", "type": "nft_ownership", "chainId": 1, "met": false, "evaluatedCondition": { "type": "nft_ownership", "chainId": 1, "contractAddress": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", "operator": "gt", "threshold": 0 }, "conditionHash": "0x8b2e...", "blockNumber": "0x12a05f200", "blockTimestamp": "2026-02-26T12:34:56.000Z", "proof": { "type": "merkle", "available": false, "reason": "Merkle proofs only available for token_balance conditions on RPC chains." } } ], "passCount": 1, "failCount": 1, "attestedAt": "2026-02-26T12:34:57.000Z", "expiresAt": "2026-02-26T13:04:57.000Z" }, "sig": "base64-ecdsa-p256-signature...", "kid": "insumer-attest-v1" }, "meta": { "creditsRemaining": 40, "creditsCharged": 2, "version": "1.0", "timestamp": "..." } } ``` ### Merkle Proof Details When `proof: "merkle"` is set, each result includes a `proof` object: - **Available proof** (`proof.available: true`): Contains EIP-1186 Merkle storage proof data. The `storageProof[0].value` is the raw on-chain balance (hex BigInt, before decimal division). Callers can verify this against public block headers without trusting InsumerAPI. - **Unavailable proof** (`proof.available: false`): Includes a `reason` string. Proofs are unavailable for Solana conditions, XRPL conditions, certain EVM chains (Ronin, Moonriver, Viction), nft_ownership conditions, and certain zero-balance edge cases. **EVM chains supporting Merkle proofs (27 of 30):** Ethereum (1), BNB Chain (56), Base (8453), Avalanche (43114), Polygon (137), Arbitrum (42161), Optimism (10), Chiliz (88888), Soneium (1868), Plume (98866), World Chain (480), Sonic (146), Gnosis (100), Mantle (5000), Scroll (534352), Linea (59144), ZKsync (324), Blast (81457), Taiko (167000), Celo (42220), Moonbeam (1284), opBNB (204), Unichain (130), Ink (57073), Sei (1329), Berachain (80094), ApeChain (33139). Not available on Ronin (2020), Moonriver (1285), Viction (88), Solana, or XRPL. **Important:** Proof mode reveals the raw on-chain balance to the caller. Standard mode never exposes balances. - `pass` is `true` only when ALL conditions are met. - `sig` is ECDSA P-256/SHA-256 over `{id, pass, results, attestedAt}`, base64 P1363 format (88 chars). `kid` identifies which key signed the response. Fetch the public key from `GET /v1/jwks` or `https://insumermodel.com/.well-known/jwks.json`. Each result in `results` includes `evaluatedCondition` (the exact condition logic) and `conditionHash` (SHA-256 of canonical JSON), making the signature tamper-evident over the evaluation logic itself. Use `npm install insumer-verify` to independently verify signatures, condition hashes, freshness, and expiry. - `blockNumber` and `blockTimestamp` are present on all 30 EVM chains. If a block anchor cannot be captured, the API returns 503 instead of signing a partial result. For XRPL conditions, `ledgerIndex` and `ledgerHash` are returned instead (XRPL equivalent of block number/hash). For Solana conditions, `slot` is returned (the Solana ledger slot at which the wallet state was read). Each of these anchors identifies the exact point-in-time chain state at which the condition was evaluated, allowing callers to verify result freshness and independently reproduce the snapshot. XRPL trust line token conditions also include `trustLineState: { frozen: bool }` — a frozen trust line causes `met: false` even if the balance exceeds the threshold. - Attestation expires in 30 minutes. - Errors: 400 (validation), 401 (bad key), 402 (no credits), 503 (rpc_failure — retryable, no credits charged). ### Wallet Auth by InsumerAPI Pass `"format": "jwt"` to receive a Wallet Auth token (ES256-signed JWT) alongside the standard response. The token is verifiable by any standard JWT library (Kong, Nginx, Cloudflare Access, AWS API Gateway) using the JWKS at `https://insumermodel.com/.well-known/jwks.json` — no Insumer SDK required. **curl example:** ```bash curl -X POST https://api.insumermodel.com/v1/attest \ -H "X-API-Key: insr_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "wallet": "0x1234567890abcdef1234567890abcdef12345678", "format": "jwt", "conditions": [ { "type": "token_balance", "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "threshold": 1000, "decimals": 6, "label": "USDC >= 1000" } ] }' ``` **Response (with `format: "jwt"`):** ```json { "ok": true, "data": { "attestation": { "id": "ATST-A7C3E1B2D4F56789", "pass": true, "results": [ { "condition": 0, "label": "USDC >= 1000", "type": "token_balance", "chainId": 1, "met": true, "evaluatedCondition": { "type": "token_balance", "chainId": 1, "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "operator": "gte", "threshold": 1000, "decimals": 6 }, "conditionHash": "0x3a7f...", "blockNumber": "0x12f4a80", "blockTimestamp": "2026-03-04T12:34:56.000Z" } ], "passCount": 1, "failCount": 0, "attestedAt": "2026-03-04T12:34:57.000Z", "expiresAt": "2026-03-04T13:04:57.000Z" }, "sig": "base64-ecdsa-p256-signature...", "kid": "insumer-attest-v1", "jwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imluc3VtZXItYXR0ZXN0LXYxIn0..." }, "meta": { "creditsRemaining": 42, "creditsCharged": 1, "version": "1.0", "timestamp": "..." } } ``` **JWT payload (decoded):** ```json { "iss": "https://api.insumermodel.com", "sub": "0x1234567890abcdef1234567890abcdef12345678", "jti": "ATST-A7C3E1B2D4F56789", "iat": 1741088097, "exp": 1741089897, "pass": true, "conditionHash": ["0x3a7f..."], "blockNumber": "0x12f4a80", "blockTimestamp": "2026-03-04T12:34:56.000Z", "results": [...] } ``` The `jwt` field is only present when `format: "jwt"` is requested. All other response fields remain unchanged. --- ## 3. POST /v1/trust **Wallet trust fact profile.** Generate a structured, ECDSA-signed on-chain fact profile for any EVM wallet. Checks 36 curated conditions across 21 chains organized by dimension (stablecoins — USDC and USDT, governance, NFTs, staking), plus Solana USDC if `solanaWallet` is provided, RLUSD + USDC on XRPL if `xrplWallet` is provided, and BTC if `bitcoinWallet` is provided (up to 40 checks total). Returns per-check booleans, per-dimension pass/fail counts, and an overall summary. No score, no opinion — just cryptographically verifiable evidence. Designed for AI agent-to-agent trust decisions. Costs 3 credits ($0.12) standard or 6 credits ($0.24) with `proof: "merkle"`. **Request:** ```json { "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "solanaWallet": "5v9CXTpN3WHbM2jAYty88qDGz7P4yuMv8fnuPRXBPmiB", "xrplWallet": "rN7n3473SaZBCG4dFL83w7p1W9cgZw6iAF", "proof": "merkle" } ``` **Request fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | wallet | string | Yes | EVM wallet address (0x...) to profile | | solanaWallet | string | No | Solana wallet address (base58). If provided, adds Solana USDC check | | xrplWallet | string | No | XRPL wallet address (r...). If provided, adds XRPL stablecoin checks (RLUSD + USDC) | | bitcoinWallet | string | No | Bitcoin address. If provided, adds Bitcoin Holdings dimension (native BTC balance check) | | proof | string | No | Set to `"merkle"` for EIP-1186 storage proofs (6 credits) | **Curated condition set (v1):** | Dimension | Checks | Details | |-----------|--------|---------| | stablecoins | 7 | USDC on Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, BNB Chain | | governance | 4 | UNI on Ethereum, AAVE on Ethereum, ARB on Arbitrum, OP on Optimism | | nfts | 3 | BAYC, Pudgy Penguins, Wrapped CryptoPunks on Ethereum | | staking | 3 | stETH (Lido), rETH (Rocket Pool), cbETH (Coinbase) on Ethereum | | solana | 1 | USDC on Solana (only if `solanaWallet` provided) | | xrpl | 2 | RLUSD + USDC on XRP Ledger (only if `xrplWallet` provided) | | bitcoin | 1 | Native BTC (only if `bitcoinWallet` provided) | All checks use `balance > 0` (presence detection). The question is "does this wallet have X?" — not "how much?" **Response:** ```json { "ok": true, "data": { "trust": { "id": "TRST-A1B2C", "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "conditionSetVersion": "v1", "dimensions": { "stablecoins": { "checks": [ { "label": "USDC on Ethereum", "chainId": 1, "met": true, "evaluatedCondition": { "type": "token_balance", "chainId": 1, "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "operator": "gte", "threshold": 0, "decimals": 6 }, "conditionHash": "0x3a7f...", "blockNumber": "0x12f4a80", "blockTimestamp": "2026-02-26T12:34:56.000Z" } ], "passCount": 3, "failCount": 4, "total": 7 }, "governance": { "checks": [...], "passCount": 2, "failCount": 2, "total": 4 }, "nfts": { "checks": [...], "passCount": 0, "failCount": 3, "total": 3 }, "staking": { "checks": [...], "passCount": 1, "failCount": 2, "total": 3 }, "xrpl": { "checks": [...], "passCount": 1, "failCount": 1, "total": 2 } }, "summary": { "totalChecks": 20, "totalPassed": 7, "totalFailed": 13, "dimensionsWithActivity": 4, "dimensionsChecked": 6 }, "profiledAt": "2026-02-26T12:34:57.000Z", "expiresAt": "2026-02-26T13:04:57.000Z" }, "sig": "base64-ecdsa-p256-signature...", "kid": "insumer-attest-v1" }, "meta": { "creditsRemaining": 47, "creditsCharged": 3, "version": "1.0", "timestamp": "..." } } ``` - `sig` is ECDSA P-256/SHA-256 over the entire `trust` object. - Each check includes `evaluatedCondition` and `conditionHash` for tamper-evidence. - Profile expires in 30 minutes. - When `proof: "merkle"` is set, stablecoin and governance checks include Merkle storage proofs (NFTs excluded). - Errors: 400 (missing wallet), 401 (bad key), 402 (insufficient credits), 429 (rate limit), 503 (rpc_failure — retryable, no credits charged). --- ## 4. POST /v1/trust/batch **Batch wallet trust profiles.** Generate ECDSA-signed wallet trust fact profiles for up to 10 wallets in a single request. Block numbers are fetched once and shared across all wallets, making this 5-8x faster than sequential `POST /v1/trust` calls. Each wallet gets an independently signed profile with its own `TRST-XXXXX` ID. Supports partial success — failed wallets get error entries while successful ones return full profiles. Credits only charged for successful profiles. Costs 3 credits per successful wallet ($0.12) standard or 6 credits per wallet ($0.24) with `proof: "merkle"`. **Request:** ```json { "wallets": [ { "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }, { "wallet": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", "solanaWallet": "5v9CXTpN3WHbM2jAYty88qDGz7P4yuMv8fnuPRXBPmiB", "xrplWallet": "rN7n3473SaZBCG4dFL83w7p1W9cgZw6iAF" } ], "proof": "merkle" } ``` **Request fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | wallets | array | Yes | 1-10 wallet entry objects | | wallets[].wallet | string | Yes | EVM wallet address (0x + 40 hex chars) | | wallets[].solanaWallet | string | No | Solana wallet address (base58). Adds Solana USDC check for this wallet | | wallets[].xrplWallet | string | No | XRPL wallet address (r...). Adds XRPL stablecoin checks (RLUSD + USDC) for this wallet | | wallets[].bitcoinWallet | string | No | Bitcoin address. Adds Bitcoin Holdings dimension for this wallet | | proof | string | No | Set to `"merkle"` for EIP-1186 storage proofs (6 credits/wallet) | **Response:** ```json { "ok": true, "data": { "results": [ { "trust": { "id": "TRST-A1B2C", "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "conditionSetVersion": "v1", "dimensions": { "stablecoins": { "checks": [...], "passCount": 3, "failCount": 4, "total": 7 }, "governance": { "checks": [...], "passCount": 2, "failCount": 2, "total": 4 }, "nfts": { "checks": [...], "passCount": 0, "failCount": 3, "total": 3 }, "staking": { "checks": [...], "passCount": 1, "failCount": 2, "total": 3 } }, "summary": { "totalChecks": 26, "totalPassed": 6, "totalFailed": 20, "dimensionsWithActivity": 3, "dimensionsChecked": 4 }, "profiledAt": "2026-02-26T12:34:57.000Z", "expiresAt": "2026-02-26T13:04:57.000Z" }, "sig": "MEYCIQDx...base64...", "kid": "insumer-attest-v1" }, { "trust": { "id": "TRST-D4E5F", "wallet": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", "conditionSetVersion": "v1", "dimensions": { "stablecoins": { "checks": [...], "passCount": 1, "failCount": 6, "total": 7 }, "governance": { "checks": [...], "passCount": 0, "failCount": 4, "total": 4 }, "nfts": { "checks": [...], "passCount": 0, "failCount": 3, "total": 3 }, "staking": { "checks": [...], "passCount": 0, "failCount": 3, "total": 3 }, "solana": { "checks": [...], "passCount": 1, "failCount": 0, "total": 1 }, "xrpl": { "checks": [...], "passCount": 1, "failCount": 1, "total": 2 } }, "summary": { "totalChecks": 29, "totalPassed": 3, "totalFailed": 26, "dimensionsWithActivity": 3, "dimensionsChecked": 6 } }, "sig": "MEUCIQC...base64...", "kid": "insumer-attest-v1" } ], "summary": { "requested": 2, "succeeded": 2, "failed": 0 } }, "meta": { "creditsCharged": 6, "creditsRemaining": 44, "version": "1.0", "timestamp": "..." } } ``` **Response fields:** | Field | Type | Description | |-------|------|-------------| | results | array | One entry per wallet, same order as input. Each is either `{trust, sig, kid}` (success) or `{error: {wallet, message}}` (failure) | | summary.requested | integer | Number of wallets in the request | | summary.succeeded | integer | Number of successful profiles | | summary.failed | integer | Number of failed wallets | | meta.creditsCharged | integer | Total credits charged (`succeeded × creditsPerWallet`) | - Each successful profile has its own ECDSA signature — independently verifiable with `insumer-verify`. - Block numbers are fetched once and reused across all wallets in the batch. - Credits are only deducted for successful profiles. If 3 of 5 wallets succeed, only 9 credits are charged (not 15). - Counts as 1 request toward the daily rate limit regardless of batch size. - Errors: 400 (invalid wallets array), 401 (bad key), 402 (insufficient credits for entire batch), 429 (rate limit). Individual wallets may fail with rpc_failure (shown as error entries in results array). --- ## 5. GET /v1/credits **Check verification credit balance.** **Response:** ```json { "ok": true, "data": { "apiKeyCredits": 42, "tier": "pro", "dailyLimit": 10000 } } ``` --- ## 6. POST /v1/keys/buy **Buy a new API key with USDC, USDT, or BTC (no auth required).** Agent-friendly: no email or prior API key needed. Send crypto to the platform wallet, then call this endpoint with the transaction hash. The sender wallet becomes the key's identity. One key per wallet — use POST /v1/credits/buy to top up an existing key. Volume discounts: $5–$99 = 25 credits/$1 ($0.04/call), $100–$499 = 33/$1 ($0.03), $500+ = 50/$1 ($0.02). USDC/USDT auto-detected from EVM and Solana transactions. BTC converted to USD at market rate (1 confirmation required). **Request:** ```json { "txHash": "0xabc123...", "chainId": 8453, "amount": 10, "appName": "My Agent" } ``` | Param | Type | Required | Description | |-------|------|----------|-------------| | txHash | string | yes | Transaction hash of the crypto transfer | | chainId | int or string | yes | Chain ID where the transfer was sent. EVM: 1, 8453, 137, 42161, 10, 56, 43114. Also: "solana", "bitcoin" | | amount | number | stablecoins only | Stablecoin amount sent (minimum 5). Not required for BTC | | appName | string | yes | Name for the API key (max 100 chars) | **Response:** ```json { "ok": true, "data": { "success": true, "key": "insr_live_...", "name": "My Agent", "tier": "paid", "dailyLimit": 10000, "creditsAdded": 250, "totalCredits": 250, "usdcPaid": "10.00", "effectiveRate": "$0.0400/credit", "chainName": "Base", "registeredWallet": "0x..." } } ``` Errors: 400, 409 (key already exists for wallet, or tx already used), 422 (on-chain verification failed). --- ## 7. POST /v1/credits/buy **Buy verification credits with USDC, USDT, or BTC.** Volume discounts: $5–$99 = 25 credits/$1 ($0.04/call), $100–$499 = 33/$1 ($0.03), $500+ = 50/$1 ($0.02). USDC/USDT auto-detected on EVM and Solana. BTC on Bitcoin (converted to USD at market rate, 1 confirmation required). Crypto sent on unsupported chains cannot be recovered. Non-refundable. **Request:** ```json { "txHash": "0xabc123...", "chainId": 8453, "amount": 10, "updateWallet": false } ``` | Param | Type | Required | Description | |-------|------|----------|-------------| | txHash | string | yes | Transaction hash of the crypto transfer | | chainId | int or string | yes | Chain ID where the transfer was sent. Also: "solana", "bitcoin" | | amount | number | stablecoins only | Stablecoin amount sent. Not required for BTC | | updateWallet | boolean | no | Set `true` to change the registered sender wallet for this API key | **Sender wallet verification:** The first successful purchase registers the transaction's sender wallet to your API key. All subsequent purchases must come from the same sender wallet. To change the registered wallet, include `"updateWallet": true` — the on-chain transfer proves ownership of the new wallet. **Response:** ```json { "ok": true, "data": { "creditsAdded": 250, "totalCredits": 292, "usdcPaid": "10.00", "chainName": "Base" } } ``` Errors: 400, 409 (tx already used), 422 (on-chain verification failed). --- ## 8. GET /v1/merchants **List merchants in the public directory.** No authentication required. **Query parameters:** | Param | Type | Description | |-------|------|-------------| | token | string | Filter by accepted token symbol (e.g. `UNI`) | | verified | string | `"true"` or `"false"` | | limit | int | Results per page (default 50, max 200) | | offset | int | Pagination offset (default 0) | **Response:** ```json { "ok": true, "data": [ { "id": "abc123", "companyName": "Coffee House", "website": "", "location": "New York, NY", "verified": true, "tokens": [{ "symbol": "UNI", "maxDiscount": 15 }], "nftCollections": [{ "name": "...", "discount": 10 }], "discountMode": "stack", "discountCap": 100 } ], "meta": { "total": 1, "limit": 50, "offset": 0 } } ``` --- ## 9. GET /v1/merchants/{id} **Get full public merchant profile.** No authentication required. **Response:** ```json { "ok": true, "data": { "id": "abc123", "companyName": "Coffee House", "website": "", "location": "", "verified": true, "verifiedDomain": "", "discountMode": "stack", "discountCap": 25, "tokens": [...], "ownToken": { "symbol": "COFFEE", "chainId": 1, "contractAddress": "0x...", "tiers": [ { "name": "Bronze", "threshold": 100, "discount": 5 }, { "name": "Silver", "threshold": 1000, "discount": 10 } ] }, "partnerTokens": [...], "nftCollections": [...], "acceptsUsdc": true } } ``` Errors: 400 (invalid ID), 404 (not found). --- ## 10. GET /v1/tokens **List registered tokens and NFTs.** No authentication required. **Query parameters:** | Param | Type | Description | |-------|------|-------------| | chain | int/string | Filter by chain ID | | symbol | string | Filter by token symbol | | type | string | `"token"` or `"nft"` | **Response:** ```json { "ok": true, "data": { "tokens": [ { "id": "...", "symbol": "UNI", "name": "Uniswap", "chainId": 1, "chainName": "Ethereum", "contractAddress": "0x1f9840...", "decimals": 18, "logo": "" } ], "nfts": [ { "id": "...", "name": "Pudgy Penguins", "contractAddress": "0xBd3531...", "chainId": 1, "chainName": "Ethereum", "image": "", "standard": "" } ] }, "meta": { "tokenCount": 42, "nftCount": 8 } } ``` --- ## 11. GET /v1/discount/check **Calculate discount for a wallet at a merchant.** No authentication required. Checks on-chain balances server-side. Free — does not consume credits. Returns tier and discount per token, never raw balance amounts. **Query parameters:** | Param | Type | Required | Description | |-------|------|----------|-------------| | wallet | string | Yes (unless solanaWallet or xrplWallet) | EVM address (0x...) | | solanaWallet | string | Optional | Solana address | | xrplWallet | string | Optional | XRPL r-address | | merchant | string | Yes | Merchant ID | **Response:** ```json { "ok": true, "data": { "eligible": true, "totalDiscount": 15, "discountMode": "stack", "breakdown": [ { "symbol": "UNI", "tier": "Gold", "discount": 10, "chain": "Ethereum" }, { "symbol": "COFFEE", "tier": "Bronze", "discount": 5, "chain": "Base" } ], "merchantId": "abc123", "merchantName": "Coffee House", "chainsChecked": ["Ethereum", "Base"] } } ``` Discount modes: `"highest"` (best single), `"stack"` (sum all), `"capped"` (sum with cap). --- ## 12. POST /v1/verify **Create a signed discount code.** Format: `INSR-XXXXX`, valid 30 minutes. Consumes 1 merchant credit. Auto-creates Stripe coupon if Stripe Connect is active. **Request:** ```json { "merchantId": "abc123", "wallet": "0x...", "solanaWallet": "...", "xrplWallet": "r..." } ``` **Response:** ```json { "ok": true, "data": { "verified": true, "totalDiscount": 15, "code": "INSR-A7K3M", "expiresAt": "2026-02-22T12:30:00.000Z", "breakdown": [{ "symbol": "UNI", "tier": "Gold", "discount": 10 }], "stripeCodeCreated": true, "cloverDiscountName": null, "merchantName": "Coffee House", "sig": "MEYCIQDx...base64...", "usdcPayment": { "evmAddress": "0xABC...def", "preferredChainId": 8453, "preferredChainName": "Base", "usdcContract": "0x833589fC...", "solanaAddress": null, "supportedChains": [ { "chainId": 1, "name": "Ethereum", "usdcContract": "0xA0b86991..." }, { "chainId": 8453, "name": "Base", "usdcContract": "0x833589fC..." } ] } } } ``` `usdcPayment` is only present when the merchant has stablecoin payments enabled. Errors: 400, 402 (no credits), 403 (API access not enabled), 404, 503 (rpc_failure — retryable, no credits charged). --- ## 13. POST /v1/payment/confirm **Verify stablecoin payment for a discount code.** Checks the on-chain transaction receipt. **Request:** ```json { "code": "INSR-A7K3M", "txHash": "0xabc123...", "chainId": 8453, "amount": "49.99" } ``` **Response:** ```json { "ok": true, "data": { "confirmed": true, "code": "INSR-A7K3M", "txHash": "0xabc123...", "chainId": 8453, "chainName": "Base", "amountVerified": "49.99", "confirmedAt": "2026-02-22T12:31:00.000Z" } } ``` Errors: 400, 403, 404, 409 (already confirmed), 410 (expired), 422 (on-chain failed). --- ## 14. POST /v1/merchants **Create a new merchant.** Receives 100 free verification credits. Max 10 merchants per API key. **Request:** ```json { "companyName": "Acme Coffee", "companyId": "ACME-COFFEE", "location": "New York, NY" } ``` **Fields:** | Field | Type | Required | Constraints | |-------|------|----------|-------------| | companyName | string | Yes | Max 100 chars | | companyId | string | Yes | 2-50 chars, `[a-zA-Z0-9_-]` | | location | string | No | Max 200 chars | **Response (201):** ```json { "ok": true, "data": { "id": "ACME-COFFEE", "companyName": "Acme Coffee", "credits": 100, "apiAccessEnabled": true } } ``` Errors: 400, 409 (ID exists), 429 (max 10 merchants). --- ## 15. PUT /v1/merchants/{id}/tokens **Configure token tiers.** Max 8 tokens total (own + partner). The API key that created the merchant must call this. **Request:** ```json { "ownToken": { "symbol": "ACME", "chainId": 8453, "contractAddress": "0x...", "decimals": 18, "tiers": [ { "name": "Bronze", "threshold": 100, "discount": 5 }, { "name": "Silver", "threshold": 1000, "discount": 10 }, { "name": "Gold", "threshold": 10000, "discount": 15 } ] }, "partnerTokens": [] } ``` **Tier validation:** 1-4 tiers per token, `name` max 30 chars, `threshold` positive and ascending, `discount` 1-50, `decimals` 0-18, `symbol` max 10 chars. **Response:** ```json { "ok": true, "data": { "ownToken": { "symbol": "ACME", "tiersConfigured": 3 }, "partnerTokens": [], "totalTokens": 1, "maxTokens": 8 } } ``` Errors: 400, 403 (not owner), 404. --- ## 16. PUT /v1/merchants/{id}/nfts **Configure NFT collections.** Max 4 collections. **Request:** ```json { "nftCollections": [ { "name": "Acme Founders", "contractAddress": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", "chainId": 1, "discount": 15 } ] } ``` **Validation:** `name` max 50 chars, `discount` 1-50. **Response:** ```json { "ok": true, "data": { "nftCollections": [{ "name": "Acme Founders", "discount": 15, "chainId": 1 }], "totalCollections": 1, "maxCollections": 4 } } ``` Errors: 400, 403, 404. --- ## 17. PUT /v1/merchants/{id}/settings **Update discount mode, cap, and stablecoin payments.** All fields optional. **Request:** ```json { "discountMode": "stack", "discountCap": 30, "usdcPayment": { "enabled": true, "evmAddress": "0x...", "solanaAddress": null, "preferredChainId": 8453 } } ``` **Fields:** | Field | Type | Description | |-------|------|-------------| | discountMode | string | `"highest"`, `"stack"`, or `"capped"` | | discountCap | int | 1-100 | | usdcPayment | object or null | Requires at least one of evmAddress or solanaAddress. Null disables. | **Response:** ```json { "ok": true, "data": { "discountMode": "stack", "discountCap": 30, "usdcPayment": { "enabled": true } } } ``` Errors: 400 (validation or no fields), 403, 404. --- ## 18. POST /v1/merchants/{id}/credits **Buy merchant verification credits with USDC, USDT, or BTC.** Volume discounts: $5–$99 = 25 credits/$1 ($0.04/call), $100–$499 = 33/$1 ($0.03), $500+ = 50/$1 ($0.02). USDC/USDT on EVM and Solana, BTC on Bitcoin. Non-refundable. **Request:** ```json { "txHash": "0x...", "chainId": 8453, "amount": 10 } ``` **Response:** ```json { "ok": true, "data": { "creditsAdded": 250, "totalCredits": 350, "usdcPaid": "10.00", "chainName": "Base" } } ``` Errors: 400, 403, 404, 409 (tx reused), 422 (on-chain failed). --- ## 19. POST /v1/merchants/{id}/directory **Publish merchant to the public directory.** No request body. Call again to refresh listing. **Response:** ```json { "ok": true, "data": { "id": "ACME-COFFEE", "published": true, "tokensListed": 1, "nftCollectionsListed": 0 } } ``` Errors: 403, 404. --- ## 20. GET /v1/merchants/{id}/status **Full private merchant details.** Only accessible by the owning API key. Includes domain verification status (but never the token). **Response:** ```json { "ok": true, "data": { "id": "ACME-COFFEE", "companyName": "Acme Coffee", "location": "", "credits": 350, "apiAccessEnabled": true, "discountMode": "stack", "discountCap": 30, "listedInDirectory": true, "ownToken": { "symbol": "ACME", "chainId": 8453, "contractAddress": "0x...", "decimals": 18, "tiers": [{ "name": "Bronze", "threshold": 100, "discount": 5 }] }, "partnerTokens": [], "nftCollections": [], "usdcPayment": { "enabled": true, "evmAddress": "0x...", "solanaAddress": null }, "verification": { "status": "verified", "domain": "acme-coffee.com", "method": "dns", "verifiedAt": "2026-02-22T12:00:00.000Z" }, "createdAt": "..." } } ``` `verification.status` is `"unverified"` (no verification attempted), `"pending"` (token issued but not yet verified), or `"verified"`. Errors: 403, 404. --- ## 21. POST /v1/merchants/{id}/domain-verification **Request a domain verification token.** Generates a token that must be placed on the domain via DNS TXT record, HTML meta tag, or a verification file. Each POST regenerates the token, invalidating any previous one. Only the owning API key can call this. **Request:** ```json { "domain": "acme-coffee.com" } ``` **Response:** ```json { "ok": true, "data": { "domain": "acme-coffee.com", "token": "insumer-a1b2c3d4e5f67890", "methods": { "dns": { "type": "TXT", "host": "acme-coffee.com", "value": "insumer-a1b2c3d4e5f67890", "instructions": "Add a TXT record to your domain's DNS with the value above." }, "meta": { "tag": "", "instructions": "Add this meta tag inside the of your homepage." }, "file": { "path": "/insumer-verify.txt", "content": "insumer-a1b2c3d4e5f67890", "instructions": "Create a file at https://acme-coffee.com/insumer-verify.txt containing the token above." } } } } ``` Errors: 400 (invalid domain), 403 (not owner), 404. --- ## 22. PUT /v1/merchants/{id}/domain-verification **Trigger domain verification check.** Checks all three methods (DNS TXT, meta tag, file) for the domain from the previous POST. Rate limited to 5 attempts per hour. If already verified, returns the existing result. **Response (success):** ```json { "ok": true, "data": { "verified": true, "domain": "acme-coffee.com", "method": "dns" } } ``` **Response (not yet verified):** ```json { "ok": true, "data": { "verified": false, "domain": "acme-coffee.com", "message": "Verification token not found. Make sure you have added the DNS record, meta tag, or verification file.", "attemptsRemaining": 4 } } ``` Errors: 400 (no pending verification), 403 (not owner), 404, 429 (rate limit — 5/hour). --- ## 23. POST /v1/acp/discount **ACP (OpenAI/Stripe Agentic Commerce Protocol) format discount eligibility check.** Runs the same on-chain verification as POST /v1/verify but wraps the result in ACP-compatible format with coupon objects, applied/rejected arrays, and per-item allocations. Consumes 1 merchant credit. Source tagged as "acp" in analytics. **Request:** ```json { "merchantId": "acme-store", "wallet": "0x1234567890abcdef1234567890abcdef12345678", "items": [ { "path": "$.line_items[0]", "amount": 2500 }, { "path": "$.line_items[1]", "amount": 1500 } ] } ``` **Request fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | merchantId | string | Yes | Merchant identifier | | wallet | string | Conditional | EVM wallet address (0x...). At least one wallet required | | solanaWallet | string | Conditional | Solana wallet address | | xrplWallet | string | Conditional | XRPL wallet address (r-address) | | items | array | No | Line items for per-item cent-amount allocations. Each has `path` (JSONPath) and `amount` (cents) | **Response (eligible):** ```json { "ok": true, "data": { "protocol": "acp", "version": "2026-01-30", "discounts": { "codes": ["INSR-A7K3M"], "applied": [{ "id": "INSR-A7K3M", "code": "INSR-A7K3M", "coupon": { "id": "insumer-insr-a7k3m", "name": "Token Holder Discount (15% off)", "percent_off": 15 }, "amount": 600, "automatic": false, "method": "across", "priority": 10, "allocations": [ { "path": "$.line_items[0]", "amount": 375 }, { "path": "$.line_items[1]", "amount": 225 } ], "start": "2026-02-27T12:00:00Z", "end": "2026-02-27T12:30:00Z" }], "rejected": [] }, "verification": { "code": "INSR-A7K3M", "expiresAt": "2026-02-27T12:30:00Z", "breakdown": [{ "symbol": "UNI", "tier": "Gold", "discount": 15 }], "sig": "base64-ecdsa-signature...", "kid": "insumer-attest-v1" } }, "meta": { "creditsCharged": 1, "creditsRemaining": 99, "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" } } ``` When wallet has no qualifying tokens: `applied: []`, `rejected: [{ code: "INSUMER_CHECK", reason: "user_ineligible" }]`. When no `items` provided: `amount: null`, `allocations` omitted — agent uses `percent_off` directly. Errors: 400 (validation), 401 (bad API key), 402 (no credits), 403 (API access disabled), 404 (merchant not found), 503 (rpc_failure — retryable). --- ## 24. POST /v1/ucp/discount **UCP (Google Universal Commerce Protocol) format discount eligibility check.** Same on-chain verification as POST /v1/verify wrapped in UCP format. Uses `title` instead of `coupon` object, includes `extension` field, omits `start`/`end` dates. Consumes 1 merchant credit. Source tagged as "ucp" in analytics. **Request:** ```json { "merchantId": "acme-store", "wallet": "0x1234567890abcdef1234567890abcdef12345678", "items": [ { "path": "$.line_items[0]", "amount": 2500 }, { "path": "$.line_items[1]", "amount": 1500 } ] } ``` **Request fields:** Same as POST /v1/acp/discount. **Response (eligible):** ```json { "ok": true, "data": { "protocol": "ucp", "version": "2026-01-11", "extension": "dev.ucp.shopping.discount", "discounts": { "codes": ["INSR-A7K3M"], "applied": [{ "code": "INSR-A7K3M", "title": "Token Holder Discount — 15% Off", "amount": 600, "automatic": false, "method": "across", "priority": 10, "allocations": [ { "path": "$.line_items[0]", "amount": 375 }, { "path": "$.line_items[1]", "amount": 225 } ] }] }, "verification": { "code": "INSR-A7K3M", "expiresAt": "2026-02-27T12:30:00Z", "sig": "base64-ecdsa-signature...", "kid": "insumer-attest-v1" } }, "meta": { "creditsCharged": 1, "creditsRemaining": 99, "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" } } ``` When ineligible: `applied: []`, `codes: []`. UCP differences from ACP: `title` replaces `coupon` object, `extension` field present, no `start`/`end` on individual discounts. Errors: 400, 401, 402, 403, 404, 503 (same as ACP endpoint). --- ## 25. GET /v1/codes/{code} **Validate an INSR-XXXXX discount code (public, no auth required).** For merchant backends during ACP/UCP checkout flows to confirm a code is valid before applying the discount. Does not expose wallet address, token breakdown, or analytics data. **Request:** ``` GET /v1/codes/INSR-A7K3M ``` No request body. No API key required. **Response (valid code):** ```json { "ok": true, "data": { "valid": true, "code": "INSR-A7K3M", "merchantId": "acme-store", "discountPercent": 15, "expiresAt": "2026-02-27T12:30:00Z", "createdAt": "2026-02-27T12:00:00Z" }, "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:05.000Z" } } ``` **Response (invalid code):** ```json { "ok": true, "data": { "valid": false, "code": "INSR-XXXXX", "reason": "expired" }, "meta": { "version": "1.0", "timestamp": "2026-02-27T12:35:00.000Z" } } ``` Possible `reason` values: `"expired"`, `"already_used"`, `"not_found"`. Errors: 400 (invalid code format). --- ## Quick Start for AI Agents ### Step 1: Get an API Key ```bash curl -X POST https://api.insumermodel.com/v1/keys/create \ -H "Content-Type: application/json" \ -d '{"email":"agent@example.com","appName":"My Agent","tier":"free"}' ``` ### Step 2: Verify a Token Balance ```bash curl -X POST https://api.insumermodel.com/v1/attest \ -H "Content-Type: application/json" \ -H "X-API-Key: insr_live_YOUR_KEY_HERE" \ -d '{ "wallet": "0x1234567890abcdef1234567890abcdef12345678", "conditions": [{ "type": "token_balance", "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "threshold": 100, "decimals": 6, "label": "Has at least 100 USDC" }] }' ``` ### Step 3: Set Up a Merchant ```bash # Create merchant curl -X POST https://api.insumermodel.com/v1/merchants \ -H "X-API-Key: insr_live_..." \ -d '{"companyName":"My Store","companyId":"my-store"}' # Verify domain ownership curl -X POST https://api.insumermodel.com/v1/merchants/my-store/domain-verification \ -H "X-API-Key: insr_live_..." \ -d '{"domain":"mystore.com"}' # → Place the token via DNS TXT, meta tag, or file, then: curl -X PUT https://api.insumermodel.com/v1/merchants/my-store/domain-verification \ -H "X-API-Key: insr_live_..." # Configure token tiers curl -X PUT https://api.insumermodel.com/v1/merchants/my-store/tokens \ -H "X-API-Key: insr_live_..." \ -d '{"ownToken":{"symbol":"UNI","chainId":1,"contractAddress":"0x1f9840...","decimals":18,"tiers":[{"name":"Holder","threshold":1,"discount":10}]}}' # Publish to directory curl -X POST https://api.insumermodel.com/v1/merchants/my-store/directory \ -H "X-API-Key: insr_live_..." ``` --- ## Key Constants | Constant | Value | |----------|-------| | Credit rate | Volume: $5–$99 = 25 credits/$1 ($0.04/call), $100–$499 = 33/$1 ($0.03), $500+ = 50/$1 ($0.02). Merkle 2x, trust 3x, trust+merkle 6x | | Min crypto purchase | $5 (USDC/USDT) or equivalent in BTC | | Payment chains | Ethereum, Base, Polygon, Arbitrum, Optimism, BNB Chain, Avalanche, Solana (USDC/USDT), Bitcoin (BTC) | | Verification code format | INSR-XXXXX (5 alphanumeric chars) | | Verification ID format | ATST- + 16 uppercase hex chars | | Trust profile ID format | TRST-XXXXX (5 hex chars) | | Code/verification expiry | 30 minutes | | ECDSA signature | P-256/SHA-256, base64 P1363 (88 chars) | | Max merchants per key | 10 | | Max tokens per merchant | 8 | | Max NFTs per merchant | 4 | | Max tiers per token | 4 | | Max conditions per verification | 10 | ## Production Integrations **AsterPay KYA Hook** (ERC-8183 agentic commerce) uses InsumerAPI for automated agent trust scoring in `beforeAction` hooks. A single `POST /v1/attest` call with 4 conditions — Base USDC balance (`token_balance`, threshold 100, chainId 8453), `coinbase_verified_account` (KYC), `coinbase_verified_country` (jurisdiction), and `gitcoin_passport_score` (humanity, resolves on Optimism) — feeds 4 of 7 trust score components: Operator KYB (15 pts), Identity (20 pts), Reputation (4 pts), and Trust Bond (5 pts). Uses `format: "jwt"` for ES256-signed JWT attestations, verified client-side with `insumer-verify` v1.3.6. An agent with all four conditions met plus ERC-8004 registration can reach Enterprise tier (85/100) from purely automated, cryptographically verifiable signals. First IACPHook with third-party attestation integration. Case study: https://insumermodel.com/blog/asterpay-kya-erc8183-attestation-integration.html **Revettr** (revettr.com) uses `POST /v1/trust` as the wallet analysis signal in their counterparty risk scoring API for x402 agent commerce. Trust profile dimensions (stablecoins, governance, NFTs, staking — plus solana, xrpl, bitcoin when multi-chain wallets are provided) surface at `signal_scores.wallet.details.insumer_trust` in every Revettr score response. Revettr scores wallets, domains, IPs, and company names — wallet auth provides the on-chain verification layer alongside domain intelligence, IP intelligence, and sanctions screening. **SettlementWitness** (defaultverifier.com) uses `POST /v1/attest` as the pre-transaction verification layer in their Settlement Attestation Record (SAR) flow. The pre/post pattern: InsumerAPI attestation confirms the counterparty holds what they claim before payment, SettlementWitness confirms the deliverable after settlement. Wallet auth qualifies agents going in, SAR verifies delivery coming out. **KCP RFC-0004** (Knowledge Context Protocol) — InsumerAPI's `attestation_url` pattern is now part of the KCP standard (RFC-0004: Trust, Provenance, and Compliance). The spec adds two fields to KCP YAML manifests: `attestation_url` (endpoint for attestation verification) and `attestation_jwks` (JWKS endpoint for signature validation). Satisfying either `trusted_providers` or `attestation_url` is sufficient (OR logic), so OIDC-based allowlists and on-chain attestations coexist. The spec is mechanism-agnostic — any verification service serving HTTPS with a discoverable signing key fits the pattern. InsumerAPI is the reference implementation: `attestation_url: "https://api.insumermodel.com/v1/attest"`, `attestation_jwks: "https://insumermodel.com/.well-known/jwks.json"`. Full RFC: https://github.com/Cantara/knowledge-context-protocol/blob/main/RFC-0004-Trust-and-Compliance.md Case study: https://insumermodel.com/blog/kcp-rfc-0004-attestation-url-standard.html **UCP (Universal Commerce Protocol)** — Proposed attestation extension (#264) for eligibility claims and wallet_attestation mechanism type (#280). The UCP eligibility layer supports verifiable claims that merchants evaluate for conditional offers — InsumerAPI's signed boolean attestations are a natural provider for this pattern. Spec: https://github.com/Universal-Commerce-Protocol/ucp ## Agent SDKs & Integrations ### Claude Code Skill (authoring — write wallet auth into your project) Install: `smithery skill add douglasborthwick/insumer-skill` Smithery: https://smithery.ai/skills/douglasborthwick/insumer-skill GitHub: https://github.com/douglasborthwick-crypto/insumer-skill A Claude Code skill that helps developers add wallet auth to their own projects from inside Claude Code. Activates on phrases like "add wallet verification", "gate by token holdings", "token gating", "on-chain eligibility", "condition-based access", or "wallet_state". Emits signature-verifying integration code that calls api.insumermodel.com and validates responses offline against the public JWKS. Includes hard-stop guardrails (no inline keys, no unverified responses, no raw balance leaks, correct USDC decimals) so the first draft works on the first try. Use this when you want Claude Code to *write* wallet auth code into your project. Use the MCP server below when you want an agent to *call* InsumerAPI at runtime — different surfaces for the same API. ### MCP Server (Claude Desktop, Cursor, Windsurf) Install: `npx -y mcp-server-insumer` (v1.9.7) npm: https://www.npmjs.com/package/mcp-server-insumer GitHub: https://github.com/douglasborthwick-crypto/mcp-server-insumer Listed on: Official MCP Registry (io.github.douglasborthwick-crypto/insumer) Glama: https://glama.ai/mcp/servers/@douglasborthwick-crypto/mcp-server-insumer 27 tools covering all endpoints with full XRPL support. Set `INSUMER_API_KEY` as environment variable. Claude Desktop config: ```json { "mcpServers": { "insumer": { "command": "npx", "args": ["-y", "mcp-server-insumer"], "env": { "INSUMER_API_KEY": "insr_live_..." } } } } ``` ### LangChain (Python) Install: `pip install langchain-insumer` (v0.9.13) PyPI: https://pypi.org/project/langchain-insumer/ GitHub: https://github.com/douglasborthwick-crypto/langchain-insumer 26 tools with full XRPL support covering all endpoints: attest, wallet_trust, batch_wallet_trust, compliance_templates, verify, confirm_payment, jwks, list_merchants, get_merchant, list_tokens, check_discount, credits, buy_credits, buy_merchant_credits, create_merchant, merchant_status, configure_tokens, configure_nfts, configure_settings, publish_directory, request_domain_verification, verify_domain, acp_discount, ucp_discount, validate_code. Also submitted as PR #549 to langchain-community (langchain-ai/langchain-community). Same 26 tools with identical API surface, packaged for `from langchain_community.tools.insumer import ...` and `from langchain_community.utilities.insumer import InsumerAPIWrapper`. ### LlamaIndex (Python) Install: `pip install llama-index-tools-insumer` (v0.2.0) PyPI: https://pypi.org/project/llama-index-tools-insumer/ GitHub: https://github.com/douglasborthwick-crypto/llama-index-tools-insumer Single `InsumerToolSpec` class exposing six spec_functions usable as LlamaIndex agent tools: - **attest_wallet** — wallet attestation against 1-10 conditions (token_balance, nft_ownership, eas_attestation, farcaster_id). Returns an ECDSA-signed verdict per condition (maps to POST /v1/attest). - **get_trust_profile** — multi-dimensional trust profile across stablecoins, governance, NFTs, staking, plus optional Solana/XRPL/Bitcoin dimensions (maps to POST /v1/trust). - **list_compliance_templates** — discover pre-configured EAS templates (Coinbase Verified Account, Gitcoin Passport, etc.). No API key required. - **get_jwks** — fetch public JSON Web Key Set for offline verification of signed results. - **buy_api_key** — let an agent purchase its own new API key on-chain with USDC or BTC, no human in the loop. Transaction sender wallet is the identity; no email required. No X-API-Key needed (the payment is the auth). Maps to POST /v1/keys/buy. - **buy_credits** — top up credits on the existing API key with a USDC or BTC payment. Requires X-API-Key. Maps to POST /v1/credits/buy. Plugs into any LlamaIndex agent via `insumer.to_tool_list()`. The agentic commerce loop is complete: an agent can buy its own access, verify wallets, and top up credits — all on-chain. ### ElizaOS (TypeScript) Install: `npm install @insumermodel/plugin-eliza` npm: https://www.npmjs.com/package/@insumermodel/plugin-eliza 10 actions covering the full autonomous agent lifecycle — no human required at any step: - **BUY_API_KEY** — provision API key with USDC/USDT/BTC, no auth needed (maps to POST /v1/keys/buy) - **CREATE_MERCHANT** — create merchant profile, 100 free credits (maps to POST /v1/merchants) - **CONFIGURE_TOKENS** — set which tokens gate discounts + tier thresholds (maps to PUT /v1/merchants/{id}/tokens) - **ADD_CREDITS** — top up merchant credits with USDC/USDT/BTC (maps to POST /v1/merchants/{id}/credits) - **VERIFY_WALLET** — on-chain attestation, 1-10 conditions per call (maps to POST /v1/attest) - **CHECK_TRUST** — 26-check wallet trust profile (maps to POST /v1/trust) - **CHECK_TRUST_BATCH** — batch up to 10 wallets (maps to POST /v1/trust/batch) - **ACP_DISCOUNT** — check discount in OpenAI/Stripe ACP format (maps to POST /v1/acp/discount) - **UCP_DISCOUNT** — check discount in Google UCP format (maps to POST /v1/ucp/discount) - **CONFIRM_PAYMENT** — confirm on-chain stablecoin payment for discount code (maps to POST /v1/merchants/{id}/confirm-payment) Plus a dynamic provider that automatically surfaces trust data in the agent's context for autonomous decision-making. ### OpenAI GPT Available via GPT Store as "InsumerAPI Verify". 26 actions with full XRPL support, merchant onboarding, and commerce protocol integration. Uses the OpenAPI spec at https://insumermodel.com/openapi-gpt.yaml. ### Attestation Verifier (Node.js / Browser) Install: `npm install insumer-verify` npm: https://www.npmjs.com/package/insumer-verify GitHub: https://github.com/douglasborthwick-crypto/insumer-verify Independently verify attestation responses client-side. Used by AsterPay KYA for JWT verification in ERC-8183 hooks. Reference library to independently verify attestation responses. Zero dependencies. Runs 4 checks: 1. **Signature** — ECDSA P-256 over `{id, pass, results, attestedAt}` using InsumerAPI's public key 2. **Condition hashes** — Recomputes SHA-256 of canonical sorted-key JSON of each `evaluatedCondition`, compares to `conditionHash` 3. **Freshness** — Checks `blockTimestamp` age against caller-defined `maxAge` (optional) 4. **Expiry** — Checks whether the 30-minute attestation window has elapsed Zero runtime dependencies. Uses Web Crypto API (Node.js 18+ and modern browsers). ```typescript import { verifyAttestation } from "insumer-verify"; const result = await verifyAttestation(apiResponse); // result.valid: boolean, result.checks: { signature, conditionHashes, freshness, expiry } ``` ## Framework Adapters Each adapter packages the wallet auth primitive (read → evaluate → sign) into a host-shaped surface, so callers in those frameworks can use the primitive without adopting Insumer's HTTP API directly. ### WDK Protocol Module (TypeScript) Install: `npm install @insumermodel/wdk-protocol-wallet-auth` npm: https://www.npmjs.com/package/@insumermodel/wdk-protocol-wallet-auth GitHub: https://github.com/douglasborthwick-crypto/wdk-protocol-wallet-auth Walkthrough: https://insumermodel.com/blog/wdk-protocol-wallet-auth-tether-wallet-development-kit.html A WDK protocol module that lives alongside Tether's Wallet Development Kit's Swap, Bridge, Lending, and Fiat protocols. Two methods, two jobs: - **attest({ address, conditions })** — evaluate 1-10 on-chain conditions, get back a signed pass/fail attestation (maps to POST /v1/attest). - **trust({ address })** — get a multi-dimensional trust profile across stablecoins, governance, NFTs, staking (maps to POST /v1/trust). The base class is shape-compatible with `@tetherto/wdk-wallet/protocols`, so it composes with every other WDK protocol and can be proposed upstream as a fifth protocol module. ### mppx condition-gate (TypeScript) Install: `npm install @insumermodel/mppx-condition-gate` (v2.0.0) npm: https://www.npmjs.com/package/@insumermodel/mppx-condition-gate GitHub: https://github.com/douglasborthwick-crypto/mppx-condition-gate Walkthrough: https://insumermodel.com/blog/mppx-condition-gate-machine-payments-protocol.html A `Method.Server` adapter for MPP. Wraps any payment method (Tempo, Stripe, etc.) so wallets that meet the configured conditions get a free-access receipt (`reference: condition-gate:free:{attestationId}`); everyone else falls through to the normal paid path. Four condition types in v2: - **token_balance** — ERC-20, SPL, XRPL trust-line, or native balance check across 33 chains. - **nft_ownership** — ERC-721, ERC-1155, Solana cNFT, XRPL NFT. - **eas_attestation** — EAS-issued claims. Use a compliance template (`coinbase_verified_account`, `coinbase_verified_country`, `coinbase_one`, `gitcoin_passport_score`, `gitcoin_passport_active`) or raw schemaId/attester/indexer. - **farcaster_id** — Farcaster account registration check (always evaluated on Optimism). Mix any of the four in a single call. `matchMode: 'any'` (default) passes when any condition is met; `'all'` requires all of them. First listed entry on Tempo's MPP /extensions page. ```typescript import { Mppx, tempo } from 'mppx/server' import { conditionGate } from '@insumermodel/mppx-condition-gate' const gated = conditionGate(tempoCharge, { conditions: [ { type: 'eas_attestation', template: 'coinbase_verified_account', chainId: 8453 }, { type: 'farcaster_id' }, ], matchMode: 'any', }) ``` The adapter does not re-sign or wrap the attestation. The signed result is byte-identical to one a direct curl to `/v1/attest` would produce; the receipt's `reference` field carries only the attestation ID. ## Links - AI Agent Verification API guide: https://insumermodel.com/ai-agent-verification-api/ - JWKS (public signing key): https://insumermodel.com/.well-known/jwks.json - OpenAPI spec: https://insumermodel.com/openapi.yaml - Postman collection: https://insumermodel.com/insumerapi.postman_collection.json - Case study (AsterPay KYA): https://insumermodel.com/blog/asterpay-kya-erc8183-attestation-integration.html - Case study (KCP RFC-0004): https://insumermodel.com/blog/kcp-rfc-0004-attestation-url-standard.html - Agent payments thesis: https://insumermodel.com/blog/before-an-agent-pays-wallet-auth-agentic-commerce.html - Quantum resistance by architecture: https://insumermodel.com/blog/quantum-breaks-static-credentials-wallet-auth.html - KYA (Know Your Agent) and the multi-attestation spec convergence: https://insumermodel.com/blog/multi-attestation-spec-five-shipped-wallet-binding.html - Claude Code skill: https://smithery.ai/skills/douglasborthwick/insumer-skill - MCP server: https://www.npmjs.com/package/mcp-server-insumer - LangChain SDK: https://pypi.org/project/langchain-insumer/ - ElizaOS plugin: https://www.npmjs.com/package/@insumermodel/plugin-eliza - WDK protocol module: https://www.npmjs.com/package/@insumermodel/wdk-protocol-wallet-auth - mppx condition-gate: https://www.npmjs.com/package/@insumermodel/mppx-condition-gate - Attestation verifier: https://www.npmjs.com/package/insumer-verify - Changelog: https://insumermodel.com/developers/changelog/ - Developer hub: https://insumermodel.com/developers/ - Quickstart (first API call in 5 min): https://insumermodel.com/developers/quickstart/ - Verification docs: https://insumermodel.com/developers/verification/ - Trust profile docs: https://insumermodel.com/developers/trust/ - Compliance docs: https://insumermodel.com/developers/compliance/ - Commerce docs (ACP/UCP): https://insumermodel.com/developers/commerce/ - Merchant onboarding docs: https://insumermodel.com/developers/onboarding/ - API reference (all endpoints): https://insumermodel.com/developers/api-reference/ - API topology (visual endpoint graph): https://insumermodel.com/workbench/ - Terms of service: https://insumermodel.com/terms-of-service/ - Contact: contact@insumermodel.com