openapi: 3.1.0
info:
  title: InsumerAPI
  version: "1.0"
  description: >
    The Insumer Model is read-first blockchain verification infrastructure that returns ECDSA-signed, privacy-preserving booleans across 33 chains — without exposing wallet balances or requiring trust in the API provider.
    InsumerAPI is its API surface. Checks token balances, NFT ownership, EAS attestations (Coinbase, Gitcoin Passport), and Farcaster identity across 33 blockchains. Up to 10 conditions per request. ACP/UCP compatible.
    Not a loyalty program. Not a reputation network. Not an identity system.
    Full guide: https://insumermodel.com/ai-agent-verification-api/

servers:
  - url: https://api.insumermodel.com
    description: Production

security:
  - ApiKeyAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: "API key in format: insr_live_ followed by 40 hex characters"
  schemas: {}

paths:
  /v1/attest:
    post:
      operationId: createAttestation
      summary: Create on-chain verification
      description: >
        Verify 1-10 on-chain conditions (token balances, NFT ownership, EAS
        attestations, Farcaster identity). Returns signed booleans, never
        balances. 1 credit, or 2 with proof:"merkle". Use wallet for EVM (0x),
        solanaWallet for Solana (base58), xrplWallet for XRP Ledger (r-address).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [conditions]
              properties:
                wallet:
                  type: string
                  description: "EVM wallet address (0x followed by 40 hex chars)"
                solanaWallet:
                  type: string
                  description: "Solana wallet address (base58 encoded)"
                xrplWallet:
                  type: string
                  description: "XRPL wallet address (r-address, 25-35 chars). Required when any condition uses chainId: \"xrpl\"."
                proof:
                  type: string
                  enum: ["merkle"]
                  description: "Set to 'merkle' to include EIP-1186 Merkle storage proofs. Costs 2 credits. Proofs available for token_balance on 27 of 30 EVM chains."
                format:
                  type: string
                  enum: ["jwt"]
                  description: "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 https://insumermodel.com/.well-known/jwks.json. No additional cost."
                conditions:
                  type: array
                  minItems: 1
                  maxItems: 10
                  description: "Array of on-chain conditions to verify"
                  items:
                    type: object
                    required: [type]
                    properties:
                      type:
                        type: string
                        enum: [token_balance, nft_ownership, eas_attestation, farcaster_id]
                        description: "token_balance checks balance >= threshold; nft_ownership checks NFT ownership; eas_attestation checks EAS attestation via template or schemaId; farcaster_id checks Farcaster registration"
                      contractAddress:
                        type: string
                        description: "Token or NFT contract address (required for token_balance and nft_ownership). For XRPL: use \"native\" for XRP, or the issuer r-address for trust line tokens."
                      chainId:
                        description: "EVM chain ID (integer, e.g. 1, 8453), \"solana\" (string), or \"xrpl\" (string). Not needed for farcaster_id."
                      threshold:
                        type: number
                        description: "Minimum token balance (for token_balance). Human-readable units (e.g. 1000 for 1000 USDC). Must be > 0 when proof is merkle (use 0.000001 for prove-any-balance)."
                      decimals:
                        type: integer
                        description: "Token decimals. Auto-detected from contract if omitted."
                      template:
                        type: string
                        enum: [coinbase_verified_account, coinbase_verified_country, coinbase_one, gitcoin_passport_score, gitcoin_passport_active]
                        description: "Compliance template name (for eas_attestation). Use instead of raw schemaId."
                      schemaId:
                        type: string
                        description: "Raw EAS schema ID (for eas_attestation, if not using template)"
                      attester:
                        type: string
                        description: "Expected attester address (optional, for eas_attestation). Recipient auto-binds to the verified wallet and must match the attestation's recipient field."
                      indexer:
                        type: string
                        description: "EAS indexer contract address. Required for raw (non-template) eas_attestation. Verifier calls getAttestationUid(address,bytes32) on this contract (selector 0xab2717dd) to resolve the UID. Custom issuers deploy their own."
                      currency:
                        type: string
                        description: "XRPL currency code (required for XRPL trust line tokens). 3-char code (e.g. \"USD\") or token name (e.g. \"RLUSD\", auto hex-encoded)."
                      taxon:
                        type: integer
                        description: "XRPL NFToken taxon filter (optional, for nft_ownership on XRPL only)."
                      label:
                        type: string
                        description: "Human-readable label for this condition (e.g. 'USDC >= 1000')"
      responses:
        "200":
          description: Verification created
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      attestation:
                        type: object
                        properties:
                          id:
                            type: string
                            description: "Format: ATST- followed by 16 uppercase hex characters"
                          pass:
                            type: boolean
                            description: "true only when ALL conditions are met"
                          results:
                            type: array
                            items:
                              type: object
                              properties:
                                condition:
                                  type: integer
                                label:
                                  type: string
                                type:
                                  type: string
                                chainId:
                                  oneOf:
                                    - type: integer
                                    - type: string
                                      enum: ["solana", "xrpl"]
                                met:
                                  type: boolean
                                evaluatedCondition:
                                  type: object
                                  description: "The exact condition logic evaluated. Callers recompute conditionHash from this to verify integrity."
                                  properties:
                                    type:
                                      type: string
                                    chainId:
                                      oneOf:
                                        - type: integer
                                        - type: string
                                          enum: ["solana", "xrpl"]
                                    contractAddress:
                                      type: string
                                    operator:
                                      type: string
                                      description: "gte for token_balance, gt for nft_ownership, valid for eas_attestation, decoder for Gitcoin, registered for farcaster_id"
                                    threshold:
                                      type: number
                                    decimals:
                                      type: integer
                                      nullable: true
                                      description: "Present only for token_balance. May be null for Solana and XRPL conditions in attest when not provided in the request. Auto-detected for all 30 EVM chains. Trust profiles always return a non-null value."
                                    currency:
                                      type: string
                                      description: "Normalized XRPL currency code (present only for XRPL trust line conditions)"
                                    taxon:
                                      type: integer
                                      description: "XRPL NFToken taxon filter (present only for XRPL nft_ownership conditions)"
                                conditionHash:
                                  type: string
                                  description: "SHA-256 of canonical evaluatedCondition JSON, 0x-prefixed"
                                blockNumber:
                                  type: string
                                  description: "Hex block number at which the condition was evaluated. Present on all 30 EVM chains; Solana uses slot, XRPL uses ledgerIndex. API returns 503 if the block anchor could not be captured."
                                blockTimestamp:
                                  type: string
                                  description: "ISO 8601 block timestamp. Present on all 30 EVM chains."
                                ledgerIndex:
                                  type: integer
                                  description: "XRPL validated ledger index (present only for XRPL conditions)"
                                ledgerHash:
                                  type: string
                                  description: "XRPL validated ledger hash (present only for XRPL conditions)"
                                trustLineState:
                                  type: object
                                  description: "Trust line state flags (XRPL trust line tokens only). Frozen lines fail attestation."
                                  properties:
                                    frozen:
                                      type: boolean
                                slot:
                                  type: integer
                                  description: "Solana slot at which the condition was evaluated. Present only for Solana conditions. Verifiers can reproduce the read by querying wallet state at this slot or later."
                                blockHeight:
                                  type: integer
                                  description: "Bitcoin chain tip block height at observation time. Present only for Bitcoin conditions. Evidence-of-freshness anchor — Bitcoin's UTXO model does not permit reproducible balance-at-block queries."
                                blockHash:
                                  type: string
                                  description: "Bitcoin chain tip block hash (64-char hex) at observation time. Present only for Bitcoin conditions. Co-reported with blockHeight."
                                proof:
                                  type: object
                                  description: "Present only when proof: 'merkle' is requested. Contains EIP-1186 storage proof or available: false with reason."
                                  properties:
                                    type:
                                      type: string
                                    available:
                                      type: boolean
                                    blockNumber:
                                      type: string
                                    mappingSlot:
                                      type: integer
                                    storageKey:
                                      type: string
                                    accountProof:
                                      type: array
                                      items:
                                        type: string
                                    storageProof:
                                      type: array
                                      items:
                                        type: object
                                    storageHash:
                                      type: string
                                    reason:
                                      type: string
                          passCount:
                            type: integer
                          failCount:
                            type: integer
                          attestedAt:
                            type: string
                          expiresAt:
                            type: string
                      sig:
                        type: string
                        description: "ECDSA P-256 signature (base64)"
                      kid:
                        type: string
                        description: "Key ID for JWKS lookup (e.g. insumer-attest-v1). Fetch public key from https://insumermodel.com/.well-known/jwks.json"
                      jwt:
                        type: string
                        description: "Wallet Auth by InsumerAPI token — ES256 JWT (only present when format: 'jwt' is requested). Verifiable with any standard JWT library using the JWKS endpoint."
                  meta:
                    type: object
                    properties:
                      creditsRemaining:
                        type: integer
                      creditsCharged:
                        type: integer
                        description: "1 for standard, 2 for proof: merkle"
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/compliance/templates:
    get:
      operationId: listComplianceTemplates
      summary: List EAS compliance templates
      description: >
        Lists available compliance templates for EAS attestation verification.
        Templates provide pre-configured schema IDs for Coinbase Verifications
        (Base) and Gitcoin Passport (Optimism). Free, no auth required.
      security: []
      responses:
        "200":
          description: Compliance template catalog
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      templates:
                        type: object
                        description: "Template name to config mapping"
                        additionalProperties:
                          type: object
                          properties:
                            provider:
                              type: string
                            description:
                              type: string
                            chainId:
                              type: integer
                            chainName:
                              type: string

  /v1/trust:
    post:
      operationId: walletTrust
      summary: Wallet trust fact profile
      description: >
        ECDSA-signed wallet trust profile. 36 base checks across stablecoins (USDC and USDT), governance, NFTs, staking. Optional Solana/XRPL wallets for up to 39 checks. 3 credits, 6 with merkle.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [wallet]
              properties:
                wallet:
                  type: string
                  description: "EVM wallet address (0x followed by 40 hex chars)"
                solanaWallet:
                  type: string
                  description: "Solana wallet address (base58). If provided, adds Solana USDC check."
                xrplWallet:
                  type: string
                  description: "XRPL wallet address (r-address). If provided, adds XRPL stablecoin checks (RLUSD + USDC)."
                proof:
                  type: string
                  enum: ["merkle"]
                  description: "Set to 'merkle' for EIP-1186 Merkle storage proofs. 6 credits."
      responses:
        "200":
          description: Trust fact profile
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      trust:
                        type: object
                        properties:
                          id:
                            type: string
                            description: "Format: TRST-XXXXX"
                          wallet:
                            type: string
                          conditionSetVersion:
                            type: string
                          dimensions:
                            type: object
                            description: "Object with keys: stablecoins, governance, nfts, staking, solana (if solanaWallet provided), xrpl (if xrplWallet provided)"
                            additionalProperties:
                              type: object
                              properties:
                                checks:
                                  type: array
                                  items:
                                    type: object
                                    properties:
                                      label:
                                        type: string
                                      chainId:
                                        oneOf:
                                          - type: integer
                                          - type: string
                                            enum: ["solana", "xrpl"]
                                      met:
                                        type: boolean
                                      evaluatedCondition:
                                        type: object
                                      conditionHash:
                                        type: string
                                      blockNumber:
                                        type: string
                                      blockTimestamp:
                                        type: string
                                      ledgerIndex:
                                        type: integer
                                        description: "XRPL validated ledger index (XRPL only)"
                                      ledgerHash:
                                        type: string
                                        description: "XRPL validated ledger hash (XRPL only)"
                                      trustLineState:
                                        type: object
                                        description: "Trust line state flags (XRPL trust line tokens only). Frozen lines fail attestation."
                                        properties:
                                          frozen:
                                            type: boolean
                                      slot:
                                        type: integer
                                        description: "Solana slot at which the condition was evaluated. Present only for Solana conditions. Verifiers can reproduce the read by querying wallet state at this slot or later."
                                      blockHeight:
                                        type: integer
                                        description: "Bitcoin chain tip block height at observation time. Present only for Bitcoin checks. Evidence-of-freshness anchor — Bitcoin's UTXO model does not permit reproducible balance-at-block queries."
                                      blockHash:
                                        type: string
                                        description: "Bitcoin chain tip block hash (64-char hex) at observation time. Present only for Bitcoin checks. Co-reported with blockHeight."
                                      proof:
                                        type: object
                                passCount:
                                  type: integer
                                failCount:
                                  type: integer
                                total:
                                  type: integer
                          summary:
                            type: object
                            properties:
                              totalChecks:
                                type: integer
                              totalPassed:
                                type: integer
                              totalFailed:
                                type: integer
                              dimensionsWithActivity:
                                type: integer
                              dimensionsChecked:
                                type: integer
                          profiledAt:
                            type: string
                          expiresAt:
                            type: string
                      sig:
                        type: string
                        description: "ECDSA P-256 signature over the trust object (base64)"
                      kid:
                        type: string
                        description: "Key ID for JWKS lookup"
                  meta:
                    type: object
                    properties:
                      creditsRemaining:
                        type: integer
                      creditsCharged:
                        type: integer
                        description: "3 for standard, 6 for proof: merkle"
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/trust/batch:
    post:
      operationId: batchWalletTrust
      summary: Batch wallet trust profiles
      description: >
        Profile up to 10 wallets in one request. Block numbers fetched once (5-8x faster than sequential calls).
        Each wallet gets an independently ECDSA-signed profile. Partial success supported. 3 credits/wallet, 6 with merkle.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [wallets]
              properties:
                wallets:
                  type: array
                  minItems: 1
                  maxItems: 10
                  items:
                    type: object
                    required: [wallet]
                    properties:
                      wallet:
                        type: string
                        description: "EVM wallet address (0x...)"
                      solanaWallet:
                        type: string
                        description: "Solana wallet (base58). Adds Solana USDC check."
                      xrplWallet:
                        type: string
                        description: "XRPL wallet (r-address). Adds XRPL stablecoin checks (RLUSD + USDC)."
                proof:
                  type: string
                  enum: ["merkle"]
                  description: "EIP-1186 Merkle proofs. 6 credits/wallet."
      responses:
        "200":
          description: Batch trust profiles
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        description: "One entry per wallet (trust profile or error)"
                        items:
                          type: object
                          properties:
                            trust:
                              type: object
                              description: "Full trust profile (same as POST /v1/trust)"
                            sig:
                              type: string
                            kid:
                              type: string
                            error:
                              type: object
                              properties:
                                wallet:
                                  type: string
                                message:
                                  type: string
                      summary:
                        type: object
                        properties:
                          requested:
                            type: integer
                          succeeded:
                            type: integer
                          failed:
                            type: integer
                  meta:
                    type: object
                    properties:
                      creditsCharged:
                        type: integer
                      creditsRemaining:
                        type: integer
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/credits:
    get:
      operationId: getCredits
      summary: Check verification credit balance
      description: "Returns the verification credit balance, tier, and daily rate limit for the authenticated API key."
      responses:
        "200":
          description: Credit balance
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      apiKeyCredits:
                        type: integer
                      tier:
                        type: string
                        description: "free, pro, or enterprise"
                      dailyLimit:
                        type: integer
                  meta:
                    type: object
                    properties:
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/merchants:
    get:
      operationId: listMerchants
      summary: List merchants in public directory
      description: "Browse merchants that reward token and NFT holders. Returns public directory listings with optional filters."
      security: []
      parameters:
        - name: token
          in: query
          schema:
            type: string
          description: "Filter by accepted token symbol (e.g. UNI, SHIB)"
        - name: verified
          in: query
          schema:
            type: string
            enum: ["true", "false"]
          description: "Filter by domain verification status"
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
          description: "Results per page (max 200)"
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
          description: "Pagination offset"
      responses:
        "200":
          description: Merchant list
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        companyName:
                          type: string
                        website:
                          type: string
                        location:
                          type: string
                        verified:
                          type: boolean
                        tokens:
                          type: array
                          items:
                            type: object
                            properties:
                              symbol:
                                type: string
                              maxDiscount:
                                type: integer
                        nftCollections:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                              discount:
                                type: integer
                        discountMode:
                          type: string
                          description: "highest, stack, or capped"
                        discountCap:
                          type: integer
                  meta:
                    type: object
                    properties:
                      total:
                        type: integer
                      limit:
                        type: integer
                      offset:
                        type: integer
                      version:
                        type: string
                      timestamp:
                        type: string
    post:
      operationId: createMerchant
      summary: Create a new merchant
      description: >
        Create a merchant programmatically. Receives 100 free verification credits.
        The API key that creates the merchant owns it. Max 10 merchants per API key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [companyName, companyId]
              properties:
                companyName:
                  type: string
                  description: "Display name"
                companyId:
                  type: string
                  description: "Unique ID (alphanumeric, dash, underscore)"
                location:
                  type: string
                  description: "City or region"
      responses:
        "201":
          description: Merchant created
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      companyName:
                        type: string
                      credits:
                        type: integer
                      apiAccessEnabled:
                        type: boolean

  /v1/merchants/{id}:
    get:
      operationId: getMerchant
      summary: Get merchant details
      description: "Returns full public merchant profile including token tiers, NFT collections, and discount settings."
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      responses:
        "200":
          description: Merchant details
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      companyName:
                        type: string
                      website:
                        type: string
                      location:
                        type: string
                      verified:
                        type: boolean
                      verifiedDomain:
                        type: string
                      discountMode:
                        type: string
                        description: "highest, stack, or capped"
                      discountCap:
                        type: integer
                      tokens:
                        type: array
                        items:
                          type: object
                      ownToken:
                        type: object
                        nullable: true
                      partnerTokens:
                        type: array
                        items:
                          type: object
                      nftCollections:
                        type: array
                        items:
                          type: object
                      acceptsUsdc:
                        type: boolean
                  meta:
                    type: object
                    properties:
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/tokens:
    get:
      operationId: listTokens
      summary: List registered tokens and NFTs
      description: "Returns all tokens and NFT collections in the registry. Use filters to narrow results by chain, symbol, or type."
      security: []
      parameters:
        - name: chain
          in: query
          schema:
            oneOf:
              - type: integer
              - type: string
                enum: ["solana", "xrpl"]
          description: "Filter by chain ID (integer for EVM, or 'solana'/'xrpl')"
        - name: symbol
          in: query
          schema:
            type: string
          description: "Filter by token symbol (e.g. UNI)"
        - name: type
          in: query
          schema:
            type: string
            enum: [token, nft]
          description: "Filter by asset type"
      responses:
        "200":
          description: Token and NFT registry
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      tokens:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            symbol:
                              type: string
                            name:
                              type: string
                            chainId:
                              type: integer
                            chainName:
                              type: string
                            contractAddress:
                              type: string
                            decimals:
                              type: integer
                            logo:
                              type: string
                      nfts:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            contractAddress:
                              type: string
                            chainId:
                              type: integer
                            chainName:
                              type: string
                            image:
                              type: string
                            standard:
                              type: string
                  meta:
                    type: object
                    properties:
                      tokenCount:
                        type: integer
                      nftCount:
                        type: integer
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/discount/check:
    get:
      operationId: checkDiscount
      summary: Calculate discount for wallet at merchant
      description: >
        Checks on-chain balances and calculates the total discount a wallet qualifies
        for at a specific merchant. Free to call — does not consume credits. Provide
        wallet (0x address) for EVM chains, solanaWallet for Solana, and/or xrplWallet for XRPL.
      security: []
      parameters:
        - name: wallet
          in: query
          schema:
            type: string
          description: "EVM wallet address (0x followed by 40 hex chars)"
        - name: solanaWallet
          in: query
          schema:
            type: string
          description: "Solana wallet address (base58 encoded)"
        - name: xrplWallet
          in: query
          schema:
            type: string
          description: "XRPL wallet address (r-address)"
        - name: merchant
          in: query
          required: true
          schema:
            type: string
          description: "Merchant ID"
      responses:
        "200":
          description: Discount calculation
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      eligible:
                        type: boolean
                      totalDiscount:
                        type: integer
                        description: "Total discount percentage"
                      discountMode:
                        type: string
                        description: "highest, stack, or capped"
                      breakdown:
                        type: array
                        items:
                          type: object
                          properties:
                            symbol:
                              type: string
                            tier:
                              type: string
                            discount:
                              type: integer
                            chain:
                              type: string
                      merchantId:
                        type: string
                      merchantName:
                        type: string
                      chainsChecked:
                        type: array
                        items:
                          type: string
                  meta:
                    type: object
                    properties:
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/verify:
    post:
      operationId: createVerification
      summary: Create signed discount code
      description: >
        Creates a signed discount verification code (INSR-XXXXX) valid for 30 minutes.
        Consumes 1 merchant credit. The code can be presented at checkout for the
        calculated discount. Provide wallet (0x) for EVM, solanaWallet for Solana, and/or xrplWallet for XRPL.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [merchantId]
              properties:
                merchantId:
                  type: string
                  description: "Merchant ID"
                wallet:
                  type: string
                  description: "EVM wallet address (0x followed by 40 hex chars)"
                solanaWallet:
                  type: string
                  description: "Solana wallet address (base58 encoded)"
                xrplWallet:
                  type: string
                  description: "XRPL wallet address (r-address)"
      responses:
        "200":
          description: Verification code created
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      verified:
                        type: boolean
                      totalDiscount:
                        type: integer
                        description: "Total discount percentage"
                      code:
                        type: string
                        description: "Discount code (format: INSR-XXXXX), valid 30 minutes"
                      expiresAt:
                        type: string
                      breakdown:
                        type: array
                        items:
                          type: object
                          properties:
                            symbol:
                              type: string
                            tier:
                              type: string
                            discount:
                              type: integer
                      stripeCodeCreated:
                        type: boolean
                      cloverDiscountName:
                        type: string
                        nullable: true
                      merchantName:
                        type: string
                      sig:
                        type: string
                        description: "ECDSA P-256 signature"
                      usdcPayment:
                        type: object
                        nullable: true
                        description: "Present when merchant has USDC payments enabled"
                        properties:
                          evmAddress:
                            type: string
                          preferredChainId:
                            type: integer
                          preferredChainName:
                            type: string
                          usdcContract:
                            type: string
                          solanaAddress:
                            type: string
                            nullable: true
                          supportedChains:
                            type: array
                            items:
                              type: object
                              properties:
                                chainId:
                                  type: integer
                                name:
                                  type: string
                                usdcContract:
                                  type: string
                  meta:
                    type: object
                    properties:
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/acp/discount:
    post:
      operationId: acpDiscount
      summary: ACP-format discount eligibility check
      description: >
        Checks token-holder discount eligibility in OpenAI/Stripe Agentic Commerce
        Protocol format. Returns coupon objects, applied/rejected arrays, per-item
        allocations. Same verification as createVerification, in ACP format. 1 credit.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [merchantId]
              properties:
                merchantId:
                  type: string
                  description: "Merchant ID"
                wallet:
                  type: string
                  description: "EVM wallet address (0x followed by 40 hex chars)"
                solanaWallet:
                  type: string
                  description: "Solana wallet address (base58 encoded)"
                xrplWallet:
                  type: string
                  description: "XRPL wallet address (r-address)"
                items:
                  type: array
                  description: "Optional line items for per-item cent-amount allocations"
                  items:
                    type: object
                    properties:
                      path:
                        type: string
                        description: "JSONPath reference, e.g. $.line_items[0]"
                      amount:
                        type: integer
                        description: "Item price in cents"
      responses:
        "200":
          description: ACP-format discount response
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      protocol:
                        type: string
                      version:
                        type: string
                      discounts:
                        type: object
                        properties:
                          codes:
                            type: array
                            items:
                              type: string
                          applied:
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                code:
                                  type: string
                                coupon:
                                  type: object
                                  properties:
                                    id:
                                      type: string
                                    name:
                                      type: string
                                    percent_off:
                                      type: integer
                                amount:
                                  type: integer
                                  nullable: true
                                automatic:
                                  type: boolean
                                method:
                                  type: string
                                priority:
                                  type: integer
                                allocations:
                                  type: array
                                  items:
                                    type: object
                                    properties:
                                      path:
                                        type: string
                                      amount:
                                        type: integer
                                start:
                                  type: string
                                  format: date-time
                                end:
                                  type: string
                                  format: date-time
                          rejected:
                            type: array
                            items:
                              type: object
                              properties:
                                code:
                                  type: string
                                reason:
                                  type: string
                      verification:
                        type: object
                        properties:
                          code:
                            type: string
                          expiresAt:
                            type: string
                            format: date-time
                          breakdown:
                            type: array
                            items:
                              type: object
                              properties:
                                symbol:
                                  type: string
                                tier:
                                  type: string
                                discount:
                                  type: integer
                          sig:
                            type: string
                          kid:
                            type: string
                  meta:
                    type: object
                    properties:
                      creditsRemaining:
                        type: integer
                      creditsCharged:
                        type: integer
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/ucp/discount:
    post:
      operationId: ucpDiscount
      summary: UCP-format discount eligibility check
      description: >
        Checks token-holder discount eligibility in Google Universal Commerce Protocol
        format. Returns title, extension field, applied array. Same verification as
        createVerification, in UCP format. 1 merchant credit.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [merchantId]
              properties:
                merchantId:
                  type: string
                  description: "Merchant ID"
                wallet:
                  type: string
                  description: "EVM wallet address (0x followed by 40 hex chars)"
                solanaWallet:
                  type: string
                  description: "Solana wallet address (base58 encoded)"
                xrplWallet:
                  type: string
                  description: "XRPL wallet address (r-address)"
                items:
                  type: array
                  description: "Optional line items for per-item cent-amount allocations"
                  items:
                    type: object
                    properties:
                      path:
                        type: string
                        description: "JSONPath reference, e.g. $.line_items[0]"
                      amount:
                        type: integer
                        description: "Item price in cents"
      responses:
        "200":
          description: UCP-format discount response
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      protocol:
                        type: string
                      version:
                        type: string
                      extension:
                        type: string
                      discounts:
                        type: object
                        properties:
                          codes:
                            type: array
                            items:
                              type: string
                          applied:
                            type: array
                            items:
                              type: object
                              properties:
                                code:
                                  type: string
                                title:
                                  type: string
                                amount:
                                  type: integer
                                  nullable: true
                                automatic:
                                  type: boolean
                                method:
                                  type: string
                                priority:
                                  type: integer
                                allocations:
                                  type: array
                                  items:
                                    type: object
                                    properties:
                                      path:
                                        type: string
                                      amount:
                                        type: integer
                      verification:
                        type: object
                        properties:
                          code:
                            type: string
                          expiresAt:
                            type: string
                          sig:
                            type: string
                          kid:
                            type: string
                  meta:
                    type: object
                    properties:
                      creditsRemaining:
                        type: integer
                      creditsCharged:
                        type: integer
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/codes/{code}:
    get:
      operationId: validateCode
      summary: Validate INSR-XXXXX discount code
      description: >
        Validates a discount code for merchant backends during ACP/UCP checkout.
        No authentication required, no credits consumed. Returns validity, discount
        percent, and expiry. Does not expose wallet or token data.
      security: []
      parameters:
        - name: code
          in: path
          required: true
          schema:
            type: string
          description: "Discount code in INSR-XXXXX format"
      responses:
        "200":
          description: Code validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      valid:
                        type: boolean
                      code:
                        type: string
                      merchantId:
                        type: string
                        description: "Present when valid"
                      discountPercent:
                        type: integer
                        description: "Present when valid"
                      expiresAt:
                        type: string
                        description: "Present when valid"
                      reason:
                        type: string
                        description: "Present when invalid: expired, already_used, not_found"
                  meta:
                    type: object
                    properties:
                      version:
                        type: string
                      timestamp:
                        type: string

  /v1/jwks:
    get:
      operationId: getJwks
      summary: Get JWKS (public key set)
      description: >
        Returns the JSON Web Key Set containing InsumerAPI's ECDSA P-256 public signing key.
        Use this to verify attestation signatures. No authentication required. Cached 24h.
      security: []
      responses:
        "200":
          description: JWKS document
          content:
            application/json:
              schema:
                type: object
                properties:
                  keys:
                    type: array
                    items:
                      type: object
                      properties:
                        kty:
                          type: string
                        crv:
                          type: string
                        x:
                          type: string
                        y:
                          type: string
                        use:
                          type: string
                        alg:
                          type: string
                        kid:
                          type: string

  /v1/credits/buy:
    post:
      operationId: buyCredits
      summary: Buy verification credits with USDC, USDT, or BTC
      description: "Buy credits with USDC, USDT, or BTC. Send to the platform wallet, submit txHash. USDC/USDT auto-detected on EVM/Solana; BTC market-rate USD, 1 confirmation. Volume discounts apply. First purchase registers sender wallet; subsequent must match (403). Set updateWallet: true to change."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [txHash, chainId]
              properties:
                txHash:
                  type: string
                  description: "Transaction hash proving payment"
                chainId:
                  oneOf:
                    - type: integer
                      enum: [1, 56, 8453, 43114, 137, 42161, 10]
                    - type: string
                      enum: ["solana", "bitcoin"]
                  description: "Chain where payment was sent"
                amount:
                  type: number
                  minimum: 5
                  description: "Stablecoin amount sent (min 5). Not required for BTC — USD value derived from on-chain BTC amount at market rate."
                updateWallet:
                  type: boolean
                  default: false
                  description: "Set true to change the registered sender wallet for this API key. The verified transfer from the new address proves ownership."
      responses:
        "200":
          description: Credits purchased
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      creditsAdded:
                        type: integer
                      totalCredits:
                        type: integer
                      usdcPaid:
                        type: string
                      chainName:
                        type: string

  /v1/payment/confirm:
    post:
      operationId: confirmPayment
      summary: Confirm USDC payment for discount code
      description: >
        After /v1/verify generates a discount code, confirm that a USDC payment was made
        on-chain. The server checks the transaction receipt to verify USDC arrived at the
        merchant address.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [code, txHash, chainId, amount]
              properties:
                code:
                  type: string
                  description: "Discount code (e.g. INSR-A7K3M)"
                txHash:
                  type: string
                  description: "On-chain transaction hash"
                chainId:
                  oneOf:
                    - type: integer
                      enum: [1, 56, 8453, 43114, 137, 42161, 10]
                    - type: string
                      enum: ["solana"]
                  description: "Chain where USDC was sent"
                amount:
                  oneOf:
                    - type: string
                    - type: number
                  description: "USDC amount sent"
      responses:
        "200":
          description: Payment confirmed
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      confirmed:
                        type: boolean
                      code:
                        type: string
                      txHash:
                        type: string
                      chainId:
                        type: integer
                        description: "Chain ID where USDC payment was confirmed"
                      chainName:
                        type: string
                      amountVerified:
                        type: string
                      confirmedAt:
                        type: string

  /v1/merchants/{id}/status:
    get:
      operationId: getMerchantStatus
      summary: Get full private merchant details
      description: >
        Returns full details including credits, token configs, directory status,
        domain verification status, and USDC settings. Only accessible by the
        API key that created the merchant.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      responses:
        "200":
          description: Full merchant status
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      companyName:
                        type: string
                      location:
                        type: string
                      credits:
                        type: integer
                      apiAccessEnabled:
                        type: boolean
                      discountMode:
                        type: string
                      discountCap:
                        type: integer
                      listedInDirectory:
                        type: boolean
                      ownToken:
                        type: object
                        nullable: true
                      partnerTokens:
                        type: array
                        items:
                          type: object
                      nftCollections:
                        type: array
                        items:
                          type: object
                      usdcPayment:
                        type: object
                        nullable: true
                      verification:
                        type: object
                        properties:
                          status:
                            type: string
                            enum: [unverified, pending, verified]
                          domain:
                            type: string
                            nullable: true
                          method:
                            type: string
                            nullable: true
                            enum: [dns, meta, file]
                          verifiedAt:
                            type: string
                            nullable: true
                      createdAt:
                        type: object
                        description: "Firestore timestamp object"
                        properties:
                          _seconds:
                            type: integer
                          _nanoseconds:
                            type: integer

  /v1/merchants/{id}/tokens:
    put:
      operationId: updateMerchantTokens
      summary: Configure merchant token tiers
      description: >
        Set up the merchant's own token and/or partner tokens with discount tiers.
        Max 8 tokens total. Must be called by the API key that created the merchant.
        For XRPL tokens: use chainId "xrpl", contractAddress as issuer r-address or
        "native" for XRP, add "currency" for trust line tokens.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ownToken:
                  type: object
                  nullable: true
                  description: "Merchant's own token config, or null to disable"
                  properties:
                    symbol:
                      type: string
                    chainId:
                      oneOf:
                        - type: integer
                        - type: string
                          enum: ["solana", "xrpl"]
                      description: "EVM chain ID (integer), or 'solana'/'xrpl' (string)"
                    contractAddress:
                      type: string
                      description: "EVM 0x address, Solana mint, XRPL issuer r-address, or 'native' for XRP"
                    decimals:
                      type: integer
                    currency:
                      type: string
                      description: "XRPL trust line currency code (e.g. 'RLUSD'). Only for XRPL."
                    tiers:
                      type: array
                      items:
                        type: object
                        properties:
                          name:
                            type: string
                          threshold:
                            type: number
                          discount:
                            type: integer
                partnerTokens:
                  type: array
                  items:
                    type: object
                    properties:
                      symbol:
                        type: string
                      chainId:
                        oneOf:
                          - type: integer
                          - type: string
                            enum: ["solana", "xrpl"]
                      contractAddress:
                        type: string
                      decimals:
                        type: integer
                      currency:
                        type: string
                        description: "XRPL trust line currency code (only for XRPL)"
                      tiers:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                            threshold:
                              type: number
                            discount:
                              type: integer
      responses:
        "200":
          description: Tokens configured
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      ownToken:
                        type: object
                        nullable: true
                      partnerTokens:
                        type: array
                        items:
                          type: object
                      totalTokens:
                        type: integer
                      maxTokens:
                        type: integer

  /v1/merchants/{id}/nfts:
    put:
      operationId: updateMerchantNfts
      summary: Configure NFT collections
      description: >
        Set NFT collections that grant discounts. Max 4 collections.
        Must be called by the API key that created the merchant.
        For XRPL NFTs: use chainId "xrpl", contractAddress as issuer r-address,
        optional "taxon" field to filter by NFToken taxon.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [nftCollections]
              properties:
                nftCollections:
                  type: array
                  maxItems: 4
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                      contractAddress:
                        type: string
                        description: "EVM 0x address, or XRPL issuer r-address"
                      chainId:
                        oneOf:
                          - type: integer
                          - type: string
                            enum: ["xrpl"]
                        description: "EVM chain ID (integer) or 'xrpl' (string)"
                      discount:
                        type: integer
                      taxon:
                        type: integer
                        description: "XRPL NFToken taxon filter (optional, XRPL only)"
      responses:
        "200":
          description: NFTs configured
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      nftCollections:
                        type: array
                        items:
                          type: object
                      totalCollections:
                        type: integer
                      maxCollections:
                        type: integer

  /v1/merchants/{id}/settings:
    put:
      operationId: updateMerchantSettings
      summary: Update merchant settings
      description: >
        Update discount stacking mode, cap, and USDC payment settings.
        All fields optional. Must be called by the API key that created the merchant.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                discountMode:
                  type: string
                  enum: [highest, stack, capped]
                  description: "'highest' uses best single discount, 'stack' sums all, 'capped' sums all then caps at discountCap"
                discountCap:
                  type: integer
                  description: "Maximum total discount percentage (1-100)"
                usdcPayment:
                  type: object
                  nullable: true
                  description: "USDC payment config, or null to disable"
                  properties:
                    enabled:
                      type: boolean
                    evmAddress:
                      type: string
                      description: "EVM wallet for USDC (0x + 40 hex)"
                    solanaAddress:
                      type: string
                      description: "Solana wallet for USDC (base58)"
                    preferredChainId:
                      oneOf:
                        - type: integer
                          enum: [1, 56, 8453, 43114, 137, 42161, 10]
                        - type: string
                          enum: ["solana"]
      responses:
        "200":
          description: Settings updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      discountMode:
                        type: string
                      discountCap:
                        type: integer
                      usdcPayment:
                        type: object
                        nullable: true

  /v1/merchants/{id}/credits:
    post:
      operationId: buyMerchantCredits
      summary: Buy merchant credits with USDC, USDT, or BTC
      description: "Buy merchant credits with USDC, USDT, or BTC (consumed by /v1/verify). Send to the platform wallet, submit txHash. USDC/USDT auto-detected on EVM/Solana; BTC market-rate USD, 1 confirmation. Volume discounts apply. Same sender-wallet verification as buyCredits."
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [txHash, chainId]
              properties:
                txHash:
                  type: string
                  description: "Transaction hash proving payment"
                chainId:
                  oneOf:
                    - type: integer
                      enum: [1, 56, 8453, 43114, 137, 42161, 10]
                    - type: string
                      enum: ["solana", "bitcoin"]
                  description: "Chain where payment was sent"
                amount:
                  type: number
                  minimum: 5
                  description: "Stablecoin amount sent (min 5). Not required for BTC — USD value derived from on-chain BTC amount at market rate."
                updateWallet:
                  type: boolean
                  default: false
                  description: "Set true to change the registered sender wallet for this API key. The verified transfer from the new address proves ownership."
      responses:
        "200":
          description: Credits purchased
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      creditsAdded:
                        type: integer
                      totalCredits:
                        type: integer
                      usdcPaid:
                        type: string
                      chainName:
                        type: string

  /v1/merchants/{id}/directory:
    post:
      operationId: publishToDirectory
      summary: Publish merchant to public directory
      description: >
        Publish (or refresh) the merchant's listing in the public directory.
        No request body needed. Call again after updating tokens/settings.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      responses:
        "200":
          description: Published
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      published:
                        type: boolean
                      tokensListed:
                        type: integer
                      nftCollectionsListed:
                        type: integer

  /v1/merchants/{id}/domain-verification:
    post:
      operationId: requestDomainVerification
      summary: Request domain verification token
      description: >
        Generates a verification token for proving domain ownership. Place via
        DNS TXT record, HTML meta tag, or a verification file. Each POST regenerates
        the token. Only the API key that created the merchant can call this.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [domain]
              properties:
                domain:
                  type: string
                  description: "Domain to verify (e.g. example.com). No protocol prefix."
      responses:
        "200":
          description: Verification token generated
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      domain:
                        type: string
                      token:
                        type: string
                        description: "Verification token (insumer-XXXXXXXXXXXXXXXX)"
                      methods:
                        type: object
                        properties:
                          dns:
                            type: object
                            properties:
                              type:
                                type: string
                              host:
                                type: string
                              value:
                                type: string
                              instructions:
                                type: string
                          meta:
                            type: object
                            properties:
                              tag:
                                type: string
                              instructions:
                                type: string
                          file:
                            type: object
                            properties:
                              path:
                                type: string
                              content:
                                type: string
                              instructions:
                                type: string
    put:
      operationId: verifyDomain
      summary: Trigger domain verification check
      description: >
        Checks all three verification methods (DNS TXT, meta tag, file) for the
        previously requested domain. Rate limited to 5 attempts per hour per merchant.
        Only the API key that created the merchant can call this.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: "Merchant ID"
      responses:
        "200":
          description: Verification result
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      verified:
                        type: boolean
                      domain:
                        type: string
                      method:
                        type: string
                        description: "Present only when verified (dns, meta, or file)"
                      verifiedAt:
                        type: string
                        description: "Present only when verified"
                      message:
                        type: string
                        description: "Present only when not verified"
                      attemptsRemaining:
                        type: integer
                        description: "Present only when not verified"

  /v1/keys/buy:
    post:
      operationId: buyKey
      summary: Buy a new API key with USDC, USDT, or BTC (no auth required)
      security: []
      description: "Buy API key with USDC/USDT/BTC, no auth. Send to platform wallet; submit txHash/chainId/appName (amount required for stablecoins, not BTC). USDC/USDT auto-detected on EVM/Solana; BTC market-rate USD, 1 confirmation. Sender wallet = key identity. One key per wallet. Volume discounts apply."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [txHash, chainId, appName]
              properties:
                txHash:
                  type: string
                  description: "Transaction hash proving payment"
                chainId:
                  oneOf:
                    - type: integer
                      enum: [1, 56, 8453, 43114, 137, 42161, 10]
                    - type: string
                      enum: ["solana", "bitcoin"]
                  description: "Chain where payment was sent"
                amount:
                  type: number
                  minimum: 5
                  description: "Stablecoin amount sent (min 5). Not required for BTC — USD value derived from on-chain BTC amount at market rate."
                appName:
                  type: string
                  description: "Name for this API key (e.g. your agent or app name)"
      responses:
        "200":
          description: API key created with credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  data:
                    type: object
                    properties:
                      success:
                        type: boolean
                      key:
                        type: string
                        description: "Your new API key (store securely — shown only once)"
                      name:
                        type: string
                      tier:
                        type: string
                      dailyLimit:
                        type: integer
                      creditsAdded:
                        type: integer
                      totalCredits:
                        type: integer
                      usdcPaid:
                        type: string
                      effectiveRate:
                        type: string
                      chainName:
                        type: string
                      registeredWallet:
                        type: string
                        description: "Wallet address registered to this key (extracted from transaction)"
