insumermodel-com Point of Sale API

In-person recognition. Partner-operated scanner PINs, login-less scanner sessions, and pass verification. The partner builds only UI; signing stays inside the primitive and is never exposed as an API call.

Operations 4

POST /v1/merchants/{id}/scanners Add or remove an in-person scanner PIN #
GET /v1/merchants/{id}/scanners List a merchant's scanners #
POST /v1/scanner/session Validate a scanner PIN and return merchant config #
POST /v1/pass/verify Verify a scanned pass and compute the discount #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/insumermodel-com:insumermodel-com-point-of-sale-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

insumermodel-com-point-of-sale-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Insumer Point of Sale API
  version: '1.0'
  description: 'InsumerAPI is the API for wallet auth — the primitive: read on-chain state, evaluate against caller-supplied conditions, return ECDSA-signed booleans across 37 chains. Conditions in, signed attestations out. Provable and private — no shared secrets, no identity-first claims, no static credentials. Never exposes wallet balances. Every result is signed and checkable offline against the published keys, and on EVM chains an optional Merkle proof lets the verifier check the balance against the block header without trusting the API. What a signed result shows: a signed result is InsumerAPI''s statement that it read chain state and evaluated the stated conditions. It does not show who controls the wallet or who the person is, and it describes state at its anchor, valid until expiresAt. With a Merkle proof the value can be checked against the chain itself; without one, the result is as reliable as InsumerAPI, its upstream data sources, and its signing keys. A failed read is refused, never signed. Full list of limits: "What a signed result shows, and what it does not" in https://insumermodel.com/llms-full.txt. InsumerAPI is the programmatic interface for The Insumer Model — used by developers, AI agents, and platforms alike. One endpoint checks token balances, NFT ownership, EAS attestations, Farcaster identity, arbitrary boolean view calls, dimensionless ratio rules (balance vs a transaction amount, or share of supply), account code (plain key, EIP-7702 delegation or contract at the wallet address, any EVM chain), and agent standing on Base (ERC-8004 registration, ERC-7710 delegation validity) across 37 blockchains, returns ECDSA P-256 signed booleans, and never exposes wallet balances. The primitive is five operations: POST /v1/attest, POST /v1/trust, POST /v1/trust/batch, GET /v1/jwks, and GET /v1/compliance/templates (tags Wallet Auth and Trust Fact Profiles). The other 41 operations are applications built on it (merchant discounts and codes, point-of-sale recognition, ACP/UCP formats for agent commerce, the public directory) and the plumbing around it (keys, credits, billing, health). Supports up to 10 conditions per request, each with its own chainId. Optional Merkle storage proofs (EIP-1186) for trustless verification. Pre-configured compliance templates for Coinbase Verifications (KYC, country, Coinbase One) on Base. Not a points program. Not a reputation network. Not an identity system. Not a DeFi protocol. Not a payments processor. Not an oracle network. Used by AsterPay KYA (ERC-8183 agent trust scoring) and Revettr (counterparty risk for x402). 5 agent SDKs: MCP server (npx -y mcp-server-insumer), LangChain (pip install langchain-insumer), LlamaIndex (pip install llama-index-tools-insumer), ElizaOS (@insumermodel/plugin-eliza), ChatGPT plugin (OpenAI''s plugin directory). 2 framework adapters: WDK protocol module (@insumermodel/wdk-protocol-wallet-auth) for Tether''s Wallet Development Kit; mppx condition-gate (@insumermodel/mppx-condition-gate) for Machine Payments Protocol routes (first listed entry on Tempo''s extensions page). Attestations independently verifiable with insumer-verify (npm install insumer-verify, or pip install insumer-verify for Python; same checks, same published test vectors; source https://github.com/insumerapi/insumer-verify). Full guide: https://insumermodel.com/ai-agent-verification-api/ Visual endpoint map: https://insumermodel.com/workbench/'
  contact:
    email: support@insumermodel.com
    url: https://insumermodel.com/developers/
  termsOfService: https://insumermodel.com/terms-of-service/
  license:
    name: Proprietary
servers:
- url: https://api.insumermodel.com
  description: Production
security:
- ApiKeyAuth: []
tags:
- name: Point Of Sale
  description: In-person recognition. Partner-operated scanner PINs, login-less scanner sessions, and pass verification. The partner builds only UI; signing stays inside the primitive and is never exposed as an API call.
paths:
  /v1/merchants/{id}/scanners:
    post:
      operationId: manageMerchantScanners
      summary: Add or remove an in-person scanner PIN
      description: 'Add or remove a scanner PIN on a merchant you manage, so a partner can run a login-less branded scanner with no account of its own. Only the API key that created the merchant can call this. A merchant can hold a limited number of scanners. PINs are stored salted + hashed and are never returned. Send `{ name?, pin }` to add, or `{ remove: scannerId }` to remove.'
      tags:
      - Point Of Sale
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: Merchant ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
              - type: object
                required:
                - pin
                properties:
                  name:
                    type: string
                    maxLength: 50
                    description: Scanner label (defaults to "Register").
                  pin:
                    type: string
                    pattern: ^\d{4,8}$
                    description: 4-8 digit PIN.
              - type: object
                required:
                - remove
                properties:
                  remove:
                    type: string
                    description: Scanner id to remove.
            examples:
              add:
                value:
                  name: Front Register
                  pin: '4821'
              remove:
                value:
                  remove: a1b2c3d4e5f6
      responses:
        '200':
          description: Scanner removed
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      removed:
                        type: string
                      totalScanners:
                        type: integer
                      changed:
                        type: boolean
                  meta:
                    $ref: '#/components/schemas/Meta'
        '201':
          description: Scanner added
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      name:
                        type: string
                      totalScanners:
                        type: integer
                  meta:
                    $ref: '#/components/schemas/Meta'
        '400':
          description: PIN not 4-8 digits, or the merchant has reached its limit on scanners
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: API key does not own this merchant
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Merchant not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
    get:
      operationId: listMerchantScanners
      summary: List a merchant's scanners
      description: List the scanners configured on a merchant you manage. Owner key only. Returns id and name only — PINs are never exposed.
      tags:
      - Point Of Sale
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: Merchant ID
      responses:
        '200':
          description: Scanner list
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      scanners:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                  meta:
                    $ref: '#/components/schemas/Meta'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: API key does not own this merchant
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Merchant not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
  /v1/scanner/session:
    post:
      operationId: scannerSession
      summary: Validate a scanner PIN and return merchant config
      description: Validate a scanner PIN and return the merchant config for a login-less branded scanner. Owner key only (the partner key that provisioned the merchant). Lets a scanner with no account of its own authenticate with just the merchant id + a PIN. Repeated failed PIN attempts are limited per merchant (429).
      tags:
      - Point Of Sale
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - merchantId
              - pin
              properties:
                merchantId:
                  type: string
                pin:
                  type: string
                  description: 4-8 digit PIN.
            example:
              merchantId: acme-coffee
              pin: '4821'
      responses:
        '200':
          description: PIN valid
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      valid:
                        type: boolean
                        const: true
                      scannerId:
                        type: string
                      scannerName:
                        type: string
                      merchantName:
                        type: string
                      discountMode:
                        type: string
                        enum:
                        - highest
                        - stack
                        - capped
                      discountCap:
                        type: integer
                  meta:
                    $ref: '#/components/schemas/Meta'
        '400':
          description: Missing merchantId or pin
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Invalid scanner code or PIN
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: API key does not own this merchant
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Merchant not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Too many failed PIN attempts, or the key's daily request limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          $ref: '#/components/responses/ServerError'
  /v1/pass/verify:
    post:
      operationId: verifyPass
      summary: Verify a scanned pass and compute the discount
      description: 'Verify a scanned pass and compute the discount. X-API-Key required (metered on the partner key). All cryptography stays server-side: InsumerAPI verifies the ECDSA signature on the scanned QR, enforces 65-second freshness, then computes the discount against the merchant config. The partner''s scanner only displays the result. A bad signature is rejected with no discount. There is deliberately no companion "sign" endpoint — passes are issued by InsumerAPI''s own pass surface; signing is the primitive and is never exposed as an API call.'
      tags:
      - Point Of Sale
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - merchantId
              - qr
              properties:
                merchantId:
                  type: string
                qr:
                  type: object
                  description: 'The scanned pass object exactly as encoded, including its `sig`. The signed bytes are the QR object with `sig` removed, re-serialized (`sig` is always the last key).

                    '
                  properties:
                    w:
                      type: string
                      description: Truncated wallet address.
                    t:
                      type: string
                      description: Encoded token balances.
                    nft:
                      type: string
                      description: Encoded NFT holdings.
                    ts:
                      type: integer
                      description: Issue timestamp in ms (65-second freshness window).
                    n:
                      type: string
                      description: Nonce.
                    sig:
                      type: string
                      description: Base64 P1363 ECDSA signature.
                  required:
                  - sig
            example:
              merchantId: acme-coffee
              qr:
                w: 0x1234…5678
                t: ACME:1500.00@8453
                ts: 1749150000000
                n: a1b2c3
                sig: <base64 P1363 ECDSA signature>
      responses:
        '200':
          description: Pass verified
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      recognized:
                        type: boolean
                      matched:
                        type: array
                        description: 'Which configured assets the pass holds. A superset of breakdown: recognition entries carry no discount.'
                        items:
                          type: object
                          properties:
                            symbol:
                              type: string
                              description: Token symbol, or collection name for NFTs
                            kind:
                              type: string
                              enum:
                              - token
                              - nft
                      configured:
                        type: integer
                        description: How many assets this merchant recognizes at all. Distinguishes "nothing configured yet" from "pass not recognized".
                      discount:
                        type: integer
                      breakdown:
                        type: array
                        items:
                          type: object
                          properties:
                            symbol:
                              type: string
                            tier:
                              type: string
                            discount:
                              type: integer
                      merchantName:
                        type:
                        - string
                        - 'null'
                        description: The merchant's display name, or null when none is configured.
                      paused:
                        type: boolean
                        description: 'Present and true when the store''s owner has paused its recognition: recognized is false, discount is 0, and configured still counts what the store recognizes. Show the store as paused, not as unconfigured.'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '400':
          description: Missing merchantId, or qr/sig
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Invalid signature or expired pass
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Merchant not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    Meta:
      type: object
      properties:
        version:
          type: string
          example: '1.0'
        timestamp:
          type: string
          format: date-time
    ErrorEnvelope:
      type: object
      required:
      - ok
      - error
      - meta
      properties:
        ok:
          type: boolean
          const: false
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: integer
            message:
              type: string
        meta:
          $ref: '#/components/schemas/Meta'
  responses:
    RateLimited:
      description: 'Rate limit exceeded. API-key requests count against the key''s daily limit; every authenticated response carries X-RateLimit-Limit and X-RateLimit-Remaining headers, and a 429 additionally carries Retry-After (seconds until the window resets).

        '
      headers:
        X-RateLimit-Limit:
          schema:
            type: string
          description: The key's daily request limit.
        X-RateLimit-Remaining:
          schema:
            type: string
          description: Requests remaining in the current daily window.
        Retry-After:
          schema:
            type: string
          description: Seconds until the rate-limit window resets.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ServerError:
      description: 'Unexpected server error. Safe to retry; no credits are charged on a 500. Router endpoints return the standard error envelope; standalone endpoints (the ones whose 200 is a flat object) return a flat {"error": "..."} object.

        '
      content:
        application/json:
          schema:
            oneOf:
            - $ref: '#/components/schemas/ErrorEnvelope'
            - type: object
              properties:
                error:
                  type: string
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'API key in format: insr_live_ followed by 40 hex characters'
    WalletAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Wallet-signed authentication. Accepted on: POST /v1/attest, POST /v1/trust, POST /v1/trust/batch, GET /v1/credits, and POST /v1/credits/buy. Other endpoints return 501 for this scheme. Header value: `Wallet <base64(JSON({message, signature}))>` where `message` is a SIWE (EIP-4361) string with `Domain: api.insumermodel.com` and `signature` is an EIP-191 personal_sign over `message`. The signing wallet must (1) match the wallet registered to the API key (the sender wallet from POST /v1/keys/buy) and (2) hold the Insumer Access pass (soulbound ERC-721 on Base, collection 0x3E2a408cc6eceba04FF9d04A5B8B05aBa8DD50ce). Nonce is single-use; `Issued At` must be within the last 5 minutes. Wallet auth authenticates the caller only. Every wallet evaluated by /v1/attest, /v1/trust, or /v1/trust/batch comes from the request body, is independent of the signer, and is not required to match it. A relying party that needs the verdict bound to the presenting wallet verifies that wallet''s own signature first, then attests the recovered address (the pattern `@skyemeta/access` implements). Drop-in middleware available as `@skyemeta/access` on npm.

        '
x-auth-note: 'Default authentication is the X-API-Key header. Five endpoints — POST /v1/attest, POST /v1/trust, POST /v1/trust/batch, GET /v1/credits, and POST /v1/credits/buy — also accept wallet-signed auth via an Authorization: Wallet header (SIWE envelope) from a wallet that holds an Insumer Access pass. All other endpoints require X-API-Key. POST /v1/attest, POST /v1/trust, and POST /v1/trust/batch additionally accept x402 pay-per-call: a request with NO credential headers on those three receives a 402 quote (see each operation''s 402 response and x-payment-info) rather than a 401. A credential-less GET or HEAD to one of those three paths receives the same 402 quote (the quote''s resource.method still says POST; paid handling stays POST-only). Everywhere else, and whenever a credential is present but invalid, the response is 401 with {ok: false, error: {code: 401, message: ''Invalid or missing API key.''}}. One exception: a request presenting an Authorization: Wallet header to any endpoint outside that five-endpoint wallet-auth allowlist returns 501, stating that wallet-pass auth is scoped to those endpoints only.'