emem Verify API

The Verify API from emem — 8 operation(s) for verify.

Operations 8

POST /v1/verify verify a structured claim #
GET /.well-known/emem-verifier.json Alias of GET /v1/verifier_spec: the code-generated signing/verification… #
GET /.well-known/jwks.json This responder's ed25519 public key as a JWK set (OKP/Ed25519, alg EdDSA). #
POST /v1/echo_verify Close the last mile: check the value YOU emitted against the signed fact your… #
GET /v1/guard/capabilities The emem-guard contract, machine-readable: every deny code and what it means… #
POST /v1/guard/verdict Run emem-guard's policy pipeline over a transcript against this responder's… #
GET /v1/state/{cid} The record an emem:state: address commits to, as stored, with its canonical… #
GET /v1/verifier_spec Machine-readable specification of how this responder signs, emitted from the… #

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/emem-dev-verify-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

emem-dev-verify-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  description: emem is shared memory for AI agents working together in the real world.
  license:
    name: Apache-2.0
  title: emem Verify API
  version: 2.4.0
  x-emem-surface-asymmetry:
    memory_notes: MCP only
    reach_them_at: POST /mcp, method tools/call
    read_side_is_here:
    - /v1/memory/search
    - /v1/memory/sse
    - /memories/{path}
    tools:
    - emem_memory_create
    - emem_memory_view
    - emem_memory_delete
    - emem_memory_rename
    - emem_memory_str_replace
    - emem_memory_supersede
    why_not_here: These write the agent correspondence plane, which is prose and untrusted-by-declaration. It is deliberately not part of the REST fact surface, and the two planes are kept apart rather than merged for convenience.
servers:
- description: Hosted instance (HTTPS-only)
  url: https://emem.dev
tags:
- name: Verify
paths:
  /v1/verify:
    post:
      description: 'Verify a structured claim against a cell''s facts. Returns verdict + evidence CIDs + signed receipt.


        When to use: Call when the user asks a yes/no question about a cell (''is the NDVI > 0.7 here'', ''has this been deforested''), or when downstream code wants citable evidence for a logical predicate.'
      operationId: emem_verify
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyReq'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyResp'
          description: ok
        default:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          description: 'error, the emem.error.v1 envelope. Branch on the stable `code` (see GET /v1/errors), not the message. A malformed or missing-field request body returns `code: invalid_argument` with the offending field named in `message`.'
      summary: verify a structured claim
      tags:
      - Verify
  /.well-known/emem-verifier.json:
    get:
      description: 'Alias of GET /v1/verifier_spec: the code-generated signing/verification specification, at a well-known path so an offline verifier can discover it without reading the OpenAPI document.'
      operationId: emem_verifier_spec_well_known
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
      summary: 'Alias of GET /v1/verifier_spec: the code-generated signing/verification…'
      tags:
      - Verify
  /.well-known/jwks.json:
    get:
      description: This responder's ed25519 public key as a JWK set (OKP/Ed25519, alg EdDSA). The agent card's signature names this document in its `jku`, so a client holding only the card can fetch the key and verify the card without being told where to look.
      operationId: emem_jwks
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
      summary: This responder's ed25519 public key as a JWK set (OKP/Ed25519, alg EdDSA).
      tags:
      - Verify
  /v1/echo_verify:
    post:
      description: 'Grade a value you are about to emit against the signed fact your citation points at. Returns `matches` and, when it does not, the `drift` between what you were about to say and what emem holds. This is the step that turns a transcription error into a caught event instead of a silent wrong number: a model that resolves a fact correctly can still retype `0.2411` for `0.241103`, and nothing else in the loop notices. Memory algebra: the `verify` operation (https://emem.dev/docs/model.html).


        When to use: Call immediately before publishing, logging, or handing on any value you took from an emem fact, and treat a false `matches` as a gate rather than a warning. Pair it with `value_verbatim` from resolve: quote that exact decimal string rather than reformatting the number, then echo-verify what you actually emitted. For a due-diligence or compliance record this is what lets you assert `every cited value was echo-verified` with a signed check per citation instead of a promise. Accepts a bare cid too, so a damaged citation still grades rather than failing closed.'
      operationId: emem_echo_verify
      requestBody:
        content:
          application/json:
            schema:
              properties:
                claimed_value:
                  description: the value you emitted, string or number; a string is compared verbatim first
                  type:
                  - string
                  - number
                token:
                  description: emem:fact:<cell64>:<fact_cid>, or a bare fact_cid (degraded)
                  type: string
              required:
              - token
              - claimed_value
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
        '400':
          content:
            application/json:
              schema:
                properties:
                  details:
                    type: object
                  error:
                    type: string
                type: object
          description: invalid argument; `details.code` names which rule refused
        '404':
          content:
            application/json:
              schema:
                properties:
                  error:
                    type: string
                type: object
          description: not found
        default:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          description: 'error, the emem.error.v1 envelope. Branch on the stable `code` (see GET /v1/errors), not the message. A malformed or missing-field request body returns `code: invalid_argument` with the offending field named in `message`.'
      summary: 'Close the last mile: check the value YOU emitted against the signed fact your…'
      tags:
      - Verify
  /v1/guard/capabilities:
    get:
      description: 'The emem-guard contract, machine-readable: every deny code and what it means, every remedy and what to do about it, the reason grammar, what the hosted route will and will not do, and how to stand up a node that enforces. Mirrors the /.well-known/emem-guard.json a self-hosted node serves, so an agent that learned one learned both.'
      operationId: emem_guard_capabilities
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
      summary: 'The emem-guard contract, machine-readable: every deny code and what it means…'
      tags:
      - Verify
  /v1/guard/verdict:
    post:
      description: 'Run emem-guard''s policy pipeline over text you are about to send, against this responder''s corpus. Finds every emem: citation, resolves each one, and returns allow or deny with a machine-readable reason: `EMEM-GUARD DENY token= fix= leaf=`. Codes are PROV_SIG (signature did not verify), PROV_BYTES (resolved to different content than claimed), PROV_DRIFT (reading has moved past its band threshold), CLAIM_UNGROUNDED (a measurable claim with no citation, opt-in via claim_gating). `fix` is the actionable half: refresh_token, remove_reference, contact_admin, cite_observation. ADVISORY: nothing is blocked, and a citation this responder does not hold is never a denial, because it is indistinguishable from one minted elsewhere. Memory algebra: the `verify` operation (https://emem.dev/docs/model.html).


        When to use: Call it on your own draft before you assert something, or on a tool result before you reason on it, to catch a citation that does not resolve while you can still fix it. `claim_gating: true` also names measurable claims with no citation and the band that would answer them. For a payload another framework produced (CloudEvent, OPA input, OpenAI moderations body, another server''s tool call) send it as-is and name its `shape`: the default reader sees only `texts`, and a check that read nothing still answers allow. To ENFORCE rather than consult, emem_guard_selfhost returns the procedure for your own node.'
      operationId: emem_guard_verdict
      parameters:
      - description: 'Which envelope the body is in, and which envelope to answer in. Exists so you never reshape a payload to ask the question: post the body your own framework produced. `mcp` reads a JSON-RPC tools/call or a tool result and answers with the CallToolResult to substitute on a deny; `openai` reads a moderations or chat-completions body; `cloudevent` reads a CloudEvents 1.0 structured event; `policy` reads {input} and answers {result:{allow,deny}}. An unrecognised value falls back to native rather than erroring.'
        in: query
        name: shape
        required: false
        schema:
          default: native
          enum:
          - native
          - mcp
          - openai
          - cloudevent
          - policy
          type: string
      - description: Also flag measurable physical-world claims that carry NO citation. Reports on absence rather than on a failed check, so it is off unless asked for.
        in: query
        name: claim_gating
        required: false
        schema:
          default: false
          type: boolean
      requestBody:
        content:
          application/json:
            schema:
              properties:
                agent:
                  description: Free-text label for the caller. Advisory, never a trust boundary.
                  type: string
                claim_gating:
                  default: false
                  description: Also flag measurable physical-world claims that carry no citation.
                  type: boolean
                messages:
                  description: A chat-completions-shaped transcript, read for its text only.
                  items:
                    type: object
                  type: array
                texts:
                  description: 'Free text to check: a draft answer, a tool result, a whole turn.'
                  items:
                    type: string
                  type: array
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
        default:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
          description: 'error, the emem.error.v1 envelope. Branch on the stable `code` (see GET /v1/errors), not the message. A malformed or missing-field request body returns `code: invalid_argument` with the offending field named in `message`.'
      summary: Run emem-guard's policy pipeline over a transcript against this responder's…
      tags:
      - Verify
  /v1/state/{cid}:
    get:
      description: 'The record an emem:state: address commits to, as stored, with its canonical CBOR and the address recomputed from those bytes beside the one asked for. Third step of the order a peer set for reasoning states: canonicalisation (published), worked vector (published), then this route. 404 for an address this responder never stored; the answer that carried it remains recomputable via /v1/verifier_spec.'
      operationId: emem_state_record
      parameters:
      - description: The state cid, or the whole emem:state:<cid> token.
        in: path
        name: cid
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
        '404':
          content:
            application/json:
              schema:
                properties:
                  error:
                    type: string
                type: object
          description: not found
      summary: 'The record an emem:state: address commits to, as stored, with its canonical…'
      tags:
      - Verify
  /v1/verifier_spec:
    get:
      description: Machine-readable specification of how this responder signs, emitted from the same compiled emem-attest tag constants the signer uses, so it cannot drift from the wire. Returns the receipt preimage v1 segment table (tag, name, scalar|list, optional) plus the domain-separation and length-prefix rules, and the segment table for every other signed family (attestation, transparency-log STH, witness co-signature, operator attestation, corpus_state_stats, stream tick). Consume once and reproduce the preimage for any signature this responder emits. Also served at /.well-known/emem-verifier.json.
      operationId: emem_verifier_spec
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: ok
      summary: Machine-readable specification of how this responder signs, emitted from the…
      tags:
      - Verify
components:
  schemas:
    Cost:
      description: 'Self-declared cost block on every receipt. Honest accounting: latencies are observed, freshness is the age of the stalest source cited (null when undatable, never 0 as a stand-in), `was_cached` is true when the hot cache served the read.'
      properties:
        credits:
          description: Conceptual cost units; 0 for L0/L1 read endpoints on the hosted responder.
          type: number
        latency_p50_ms:
          type: number
        latency_p99_ms:
          type: number
        source_freshness_s:
          description: 'Age of the STALEST source this response cites: now minus the earliest captured_at across the returned facts'' sources. null when nothing in the response carries a dated source, which is the honest answer for a primitive that reads no observation. Was a hardcoded 0 until 2026-08-05, so a 2021 DEM tile reported as 0 s old; a null here means unknown, never fresh.'
          type:
          - integer
          - 'null'
        was_cached:
          type: boolean
      type: object
    ErrorEnvelope:
      description: The `emem.error.v1` failure envelope returned by every endpoint on a 4xx/5xx. Branch on the stable `code` (not the human `message`). See GET /v1/errors for the full code catalog.
      properties:
        code:
          description: Stable machine-readable error code. One of the codes in GET /v1/errors.
          example: invalid_argument
          type: string
        details:
          description: Optional structured recovery hints; present on errors that ship machine-readable next-steps.
          type: object
        message:
          description: Human-readable detail. For invalid_argument this names the offending field (e.g. "missing field `q`").
          type: string
        path:
          description: Request path that produced the error.
          example: /v1/ask
          type: string
        schema:
          const: emem.error.v1
          type: string
      required:
      - code
      - message
      - schema
      type: object
    PubKey:
      description: Ed25519 32-byte public key, base32-nopad-lowercase encoded (52 chars). Returned in receipts and `/.well-known/emem.json`.
      example: 777er3yihgifqmv5hmc2wwmyszgddzderzhsx6rex4yoakwomvka
      type: string
    VerifyResp:
      description: Response of /v1/verify. `holds` is the boolean verdict; `evidence_cids` are the fact CIDs the verifier walked to reach the verdict.
      properties:
        evidence_cids:
          items:
            $ref: '#/components/schemas/FactCid'
          type: array
        explanation:
          type: string
        holds:
          type: boolean
        receipt:
          $ref: '#/components/schemas/Receipt'
      required:
      - holds
      - receipt
      type: object
    Cell64:
      description: 'cell64 wire form: four base-65,536 bigrams separated by dots, e.g. `defi.zb4d9.pefa.zf619`. Encoded resolution is ~9.55 m at the equator. Each bigram is either a CVCV quad, consonant `[bcdfghjklmnpqrstvwxyz]` followed by vowel `[aeiouAEIOU]` repeated twice, OR a synthetic 5-char `z[0-9a-f]{4}` slot used for the unused pad cells in the 65,536-entry alphabet. The regex pin matches `pattern` below byte-for-byte and is also surfaced under `Cell64Pattern` so agents can validate before sending.'
      example: defi.zb4d9.pefa.zf619
      maxLength: 23
      minLength: 19
      pattern: ^(?:(?:[bcdfghjklmnpqrstvwxyz][aeiouAEIOU]){2}|z[0-9a-f]{4})(?:\.(?:(?:[bcdfghjklmnpqrstvwxyz][aeiouAEIOU]){2}|z[0-9a-f]{4})){3}$
      type: string
    FactCid:
      description: 'Content id of a fact: base32-nopad-lowercase encoding of `blake3(canonical_cbor(fact))`, the FULL 32-byte digest with no truncation. Always 52 characters, alphabet `[a-z2-7]`. A cid of any other length is a damaged citation, not a shorter address: /v1/memory_token/resolve rejects it as `fact_cid_malformed_length` rather than guessing. Note that `entity_cid` and `bundle_cid` are NOT this shape; both truncate to 16 bytes (26 characters) and hash an identity anchor or a citation list rather than a complete body.'
      example: qtv2bco56qw4pmlohk56dotoxyl3atmnjpmzrijj2kazw2mj57oq
      maxLength: 52
      minLength: 52
      pattern: ^[a-z2-7]{52}$
      type: string
    Claim:
      properties:
        agg:
          description: Aggregation over `window`
          enum:
          - any
          - all
          - mean
          - min
          - max
          type: string
        band:
          description: Band key (e.g. `indices.ndvi`, `copdem30m.elevation_mean`)
          type: string
        op:
          description: Comparison or membership operator
          enum:
          - eq
          - ne
          - lt
          - le
          - gt
          - ge
          - in
          - ni
          - exists
          - absent
          type: string
        tslot:
          description: Specific tslot; one of `tslot` or `window` MUST be set
          type: integer
        value:
          description: Right-hand value, band-typed (number for scalar bands, array for vector bands, set for in/ni). Required even for exists/absent where it is ignored.
        window:
          description: Inclusive [start, end] u64 Unix-epoch range
          items:
            type: integer
          maxItems: 2
          minItems: 2
          type: array
      required:
      - band
      - op
      - value
      type: object
    VerifyReq:
      properties:
        cell:
          type: string
        claim:
          $ref: '#/components/schemas/Claim'
        mode:
          enum:
          - fast
          - resolve
          type: string
      required:
      - claim
      - cell
      type: object
    Receipt:
      description: 'Ed25519-signed receipt. The browser-side verifier at /verify reconstructs the preimage from the receipt fields alone, no callback to the issuer. **A receipt is byte-for-byte or nothing.** Current receipts carry `preimage_version: 2`, whose preimage binds request_id, served_at, primitive, cells, fact_cids AND, when present, the scope / as_of / edges / source_versions / field digests and the `merkle_proof` segment. Reshaping a receipt — dropping a field an SDK considers redundant, re-keying it, summarising it, round-tripping it through a lossy model — invalidates the signature BY DESIGN, and the result is indistinguishable on the wire from tampering. Store and forward the responder''s exact bytes. POST /v1/verify_receipt names which of the two it is where it can prove the difference (`reason: receipt_reshaped_after_signing` with a `failure_detail`). What is NOT signed: the caller''s `place`/`q` string, raw `lat`/`lng`, requested `bands[]`, requested `tslot`, and `intent` — a wrong-place geocode produces a valid signature for the wrong cell. Branch on /v1/locate `selected.is_high_confidence` before trusting place-anchored answers. Also: `fact_cid` is per-replica (signed_at differs across responders even for byte-identical upstream pixels); cross-replica join key is the tuple (cell, band, tslot). /v1/recall_polygon emits one independently signed receipt per cell under `by_cell.<cell>.receipt`, `merged_facts[]` is convenience flattening and is NOT covered by an aggregate signature.'
      properties:
        cells:
          items:
            $ref: '#/components/schemas/Cell64'
          type: array
        cost:
          $ref: '#/components/schemas/Cost'
        fact_cids:
          items:
            $ref: '#/components/schemas/FactCid'
          type: array
        intent:
          description: Optional natural-language hint. Populated when served via /v1/intent.
          type: string
        merkle_proof:
          description: 'Inclusion proof for `fact_cids[0]` when persisted. Omitted from JSON when the cited facts pre-date the proof tree; under preimage_version 2 that absence is itself signed (an explicit ABSENT marker), so it is a statement rather than a gap. Do not strip this field: v2 binds it into the signature and removing it makes an authentic receipt report `signature_valid: false`.'
          properties:
            leaf_index:
              description: u32 leaf index in the canonical-sorted batch.
              type: integer
            path:
              description: Sibling hashes leaf→root.
              items:
                description: 32-byte sibling hash as a byte array
                items:
                  type: integer
                type: array
              type: array
            root:
              description: The expected 32-byte batch root as a byte array.
              items:
                type: integer
              type: array
            version:
              description: 'Merkle hashing rule: 0 (omitted) = legacy unprefixed, 1 = RFC 6962-style prefixed.'
              type: integer
          required:
          - leaf_index
          - path
          - root
          type: object
        primitive:
          description: 'Namespaced wire form: `emem.recall`, `emem.find_similar`, `emem.verify`, …'
          type: string
        registry_cid:
          description: CID of the function registry version in force.
          type: string
        request_id:
          description: ULID generated per request.
          type: string
        responder:
          $ref: '#/components/schemas/PubKey'
        responder_key_epoch:
          description: u32 rotation counter; bumps when the operator rotates keys.
          type: integer
        responder_pubkey_b32:
          $ref: '#/components/schemas/PubKey'
        schema_cid:
          description: CID of the active CDDL profile.
          type: string
        served_at:
          description: ISO 8601 UTC, second precision.
          type: string
        signature:
          description: Ed25519 signature, 64 bytes base32-nopad-lowercase encoded.
          type: string
        source_versions:
          additionalProperties:
            type: string
          description: Per-source freshness map.
          type: object
      required:
      - request_id
      - served_at
      - primitive
      - cells
      - fact_cids
      - schema_cid
      - responder
      - responder_key_epoch
      - responder_pubkey_b32
      - signature
      - registry_cid
      type: object