SNHP Store API

The store API from SNHP — 12 operation(s) for store.

Operations 12

GET /v1/store/catalog Store Catalog #
GET /v1/store/notary_pubkey Store Notary Pubkey #
POST /v1/fetch Store Fetch #
POST /v1/store/request Store Request #
GET /v1/store/request/{request_id} Store Request Status #
GET /v1/store/requests Store Requests #
GET /v1/store/observatory Store Observatory #
GET /v1/store/my_requests Store My Requests #
POST /v1/store/park Store Park #
GET /v1/store/parcel/{ticket} Store Retrieve #
POST /v1/memory/save Memory Save #
GET /v1/memory/parcel/{ticket} Memory Load #

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/snhp-dev-store-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

snhp-dev-store-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Game Theory Layer for AI Agents Store API
  description: 'Start with ONE tool: POST /v1/negotiate/turn — plain-dollar price negotiation (your walk-away + the other side''s offers in dollars -> the counter to send, a ready-to-send message, accept/walk advice).'
  version: 0.1.0
tags:
- name: Store
paths:
  /v1/store/catalog:
    get:
      tags:
      - Store
      summary: Store Catalog
      description: 'THE STORE''s shelf: the commodity slots (tier, admission cap,

        predicate id, request doc, serving-backend ids), the anchor SKUs, and the

        two published pricing facts — wholesale-passthrough cost basis on every

        receipt plus the counter fee on top-ups. No key material ever appears

        here.'
      operationId: store_catalog_v1_store_catalog_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/store/notary_pubkey:
    get:
      tags:
      - Store
      summary: Store Notary Pubkey
      description: 'The receipt-signing notary''s PUBLIC key, at a stable path so a verifier

        can PIN it OUT-OF-BAND (not just trust the pubkey embedded in a receipt) and

        confirm it matches the receipt''s pubkey_fingerprint. Returns {pubkey_pem,

        fingerprint, key_source}. This is the STORE receipt notary (vend.receipt_

        signing / NOTARY_KEY_PEM) — DISTINCT from /v1/keys/trust_anchor (first-strike

        CA) and /v1/keys/settlement_notary (AP2 mandates), which are different keys.


        key_source is VISIBLE: with ''ephemeral'' a signature proves only signer-

        consistency within one server lifetime; a production notary pins a persistent

        key (''env'', from NOTARY_KEY_PEM). Never returns private material.'
      operationId: store_notary_pubkey_v1_store_notary_pubkey_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/fetch:
    post:
      tags:
      - Store
      summary: Store Fetch
      description: 'Fetch/extract one page → markdown, paid from your wallet at wholesale

        passthrough. Settlement-on-delivery: charged ONLY on non-empty markdown.


        Pass your key in an `Authorization: Bearer gt_*` or `X-API-Key` header

        (RECOMMENDED — that reaches the 600/min keyed rate-limit lane; a body-only

        key falls to the 60/min per-IP floor because the limiter never parses

        bodies) or in the JSON body `api_key` (backcompat). The header wins if both

        are present.


        A backend or predicate failure is a NORMAL uncharged outcome — 200 with the

        canonical envelope {ok: false, charged: false, reason: ,

        code: } — because you cannot pay for nothing; that asymmetry is

        the product surface, not an HTTP error. `code` is one of unknown_slot,

        slot_unavailable, insufficient_balance, all_backends_failed, predicate_failed;

        a delivered-but-failed call may also carry backends_tried [{id, reason}],

        backends_untried, backend_id, and a retry_hint. One client code path reads

        `charged`/`code` for every outcome. (Legacy keys like `error` survive as

        aliases.) Insufficient balance → 402; a missing or unknown api_key → 401.'
      operationId: store_fetch_v1_fetch_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FetchIn'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/store/request:
    post:
      tags:
      - Store
      summary: Store Request
      description: 'File a request for a capability the store doesn''t stock. Free, keyless

        OK. Returns {request_id, status, watch, check} — the demand loop now hands

        back something to return FOR (GAUNTLET #5). Size-capped, stored as data,

        never rendered raw. Pass `watch: true` WITH an api_key to flag the ask for a

        heads-up on a status flip (poll GET /v1/store/my_requests — poll-based, no

        push); an anonymous watch is ignored, and the chosen flag is echoed back.'
      operationId: store_request_v1_store_request_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StoreRequestIn'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/store/request/{request_id}:
    get:
      tags:
      - Store
      summary: Store Request Status
      description: 'Check a filed request by id: {request_id, status, status_note, filed_at,

        door, text}. `status` is ''logged'' until the shelf-owner acts, then

        status_note carries the reason-to-return. Unknown id → 404. No key material;

        the text is display-truncated and remains untrusted data.'
      operationId: store_request_status_v1_store_request__request_id__get
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/store/requests:
    get:
      tags:
      - Store
      summary: Store Requests
      description: 'The public demand tally (GAUNTLET #5): {total, distinct, recent[],

        requests[]}. `requests` is distinct asks with EXACT-MATCH duplicate counts

        (whitespace/case folded, no fuzzy classification — mechanical, no LLM),

        most-asked first. No key material; text display-truncated.'
      operationId: store_requests_v1_store_requests_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/store/observatory:
    get:
      tags:
      - Store
      summary: Store Observatory
      description: 'The public, citable observatory (vend.observatory.snapshot): per-slot

        call volumes and the MECHANICAL tally of what agents ask for that nobody

        sells yet. Every number is a count, a sum, or an exact-match group — no

        interpretation, no LLM. Aggregate + PSEUDONYMOUS: wallets appear only as

        counts of a keyed pseudonym (repeat_key), never a raw api_key, so NO key

        material can leak. Pure read, no auth. The demand-loop citation asset: what

        the shelf is missing, straight from the raw records.'
      operationId: store_observatory_v1_store_observatory_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/store/my_requests:
    get:
      tags:
      - Store
      summary: Store My Requests
      description: 'Your OWN filings (roadmap: a voter comes back a reachable customer), keyed

        to YOUR api_key — the private counterpart to the public GET /v1/store/requests

        tally. Carry the key in `Authorization: Bearer gt_*` or `X-API-Key`, never a

        query param (a secret must not land in access logs). A missing or unknown key

        → 401. Returns {requests: [{request_id, filed_at, text, status, status_note,

        status_ts, watch, same_ask_count}]}, newest first — text display-truncated,

        still untrusted data; no key material and no repeat_key on the surface. Only

        rows attributable to this key (via the keyed pseudonym, never a raw key match)

        are returned, so one key can never read another''s filings.'
      operationId: store_my_requests_v1_store_my_requests_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/store/park:
    post:
      tags:
      - Store
      summary: Store Park
      description: 'Park an ENCRYPTED blob, get a claim ticket (blind locker, §2c). Charged a

        thin flat park fee ONLY on durable store; an empty/oversize/unencodable blob

        is uncharged. Key via `Authorization: Bearer`/`X-API-Key` (header wins) or

        body `api_key`. The receipt''s content_hash is over YOUR ciphertext, so you

        can prove what you stored without the store ever seeing plaintext.'
      operationId: store_park_v1_store_park_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParkIn'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/store/parcel/{ticket}:
    get:
      tags:
      - Store
      summary: Store Retrieve
      description: 'Retrieve a parked parcel by its claim ticket (blind locker, §2c). Returns

        {ok, blob_b64, size_bytes, expires_at} — the ciphertext you parked, which

        only YOU can decrypt. Key via `Authorization: Bearer`/`X-API-Key`. A wrong

        owner reads as a missing ticket (404). Retrieval is free (the park settled

        it). An expired TTL is 404; a lost at-rest key is 503.'
      operationId: store_retrieve_v1_store_parcel__ticket__get
      parameters:
      - name: ticket
        in: path
        required: true
        schema:
          type: string
          title: Ticket
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/memory/save:
    post:
      tags:
      - Store
      summary: Memory Save
      description: 'Save persistent memory for your agent across sessions (alias of

        POST /v1/store/park — the blind locker). You encrypt before saving; the store

        holds only ciphertext (blind custody) and signs a receipt over its hash — it

        cannot read your memory. Saving uses your prepaid wallet (a new key''s 50¢

        starter credit covers first saves); loading it back is free. Same handler and

        behavior as /v1/store/park.'
      operationId: memory_save_v1_memory_save_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParkIn'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/memory/parcel/{ticket}:
    get:
      tags:
      - Store
      summary: Memory Load
      description: 'Load a memory you saved in an earlier session (alias of

        GET /v1/store/parcel/{ticket}). Returns the ciphertext you saved, which only

        YOU can decrypt; retrieval is free. Same handler and behavior as

        /v1/store/parcel/{ticket}.'
      operationId: memory_load_v1_memory_parcel__ticket__get
      parameters:
      - name: ticket
        in: path
        required: true
        schema:
          type: string
          title: Ticket
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    StoreRequestIn:
      properties:
        text:
          type: string
          maxLength: 4000
          title: Text
          description: what you wish the counter stocked
        api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Api Key
        watch:
          type: boolean
          title: Watch
          description: with an api_key, flag this ask to hear back on a status flip — poll GET /v1/store/my_requests; no email/webhook
          default: false
      type: object
      required:
      - text
      title: StoreRequestIn
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    ParkIn:
      properties:
        api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Api Key
        blob_b64:
          type: string
          title: Blob B64
          description: your ciphertext as base64 — ENCRYPT BEFORE PARKING; the store holds only opaque bytes and cannot read them
        ttl_seconds:
          anyOf:
          - type: integer
          - type: 'null'
          title: Ttl Seconds
          description: requested lifetime; clamped to [60s, 7d]. The effective expires_at is returned — never a silent surprise.
      type: object
      required:
      - blob_b64
      title: ParkIn
    FetchIn:
      properties:
        api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Api Key
        url:
          type: string
          maxLength: 2048
          title: Url
          description: http(s) URL to read → markdown
      type: object
      required:
      - url
      title: FetchIn