emem Identity API
The identity API from emem — 7 operation(s) for identity.
The identity API from emem — 7 operation(s) for identity.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/emem-dev-identity-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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: 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 Identity 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: Identity
paths:
/.well-known/did.json:
get:
description: 'node identity: the did:web document naming this node''s responder key (the key under every STH and receipt) and, when the operator declares one, its witness key, both as Multikey. 404 with the fix when the node has no public host.'
operationId: emem_well_known_did
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: 'node identity: the did:web document naming this node''s responder key (the key…'
tags:
- Identity
/.well-known/emem-agents.json:
get:
description: 'organisation vouching: the keys this operator vouches for, from config/emem-agents.json. The enlistment ladder on OTHER nodes fetches this document to move a key to T4_affiliated; a node that asks peers to publish one publishes its own. Public keys only, no redirects, CORS open.'
operationId: emem_well_known_agents
responses:
'200':
content:
application/json:
schema:
type: object
description: ok
summary: 'organisation vouching: the keys this operator vouches for, from…'
tags:
- Identity
/v1/enlist:
get:
description: 'The write ladder, machine-readable: which check each tier records, the minimum tier per write surface, and which rungs THIS responder actually computes. Reads are never gated at any tier, on any surface. There is no account, no bearer token that grants anything, and no payment: climbing a tier means passing a check a third party can re-run without this responder. Tiers are records of what was checked, never scores, and `trust` on the roster stays `caller_decides`.'
operationId: emem_enlist_ladder
responses:
'200':
content:
application/json:
schema:
type: object
description: ok
summary: 'The write ladder, machine-readable: which check each tier records, the minimum…'
tags:
- Identity
post:
description: 'Ask this responder to check an organisation''s attestation for a key, by `dns` (a _emem-agent TXT record) or `well_known` (/.well-known/emem-agents.json). Records the outcome either way, with checked_at, and returns it with its age: a failed check is evidence too. Unauthenticated on purpose, because the call only ever records what the ORGANISATION published, so asking about someone else''s domain gains nothing. Verification targets must be public names; IP literals, local names and anything resolving into private space are refused and redirects are not followed.'
operationId: emem_enlist_verify
requestBody:
content:
application/json:
schema:
properties:
attester_pubkey_b32:
description: the full 52-character key, not a prefix
type: string
domain:
type: string
method:
enum:
- dns
- well_known
type: string
required:
- attester_pubkey_b32
- domain
- method
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
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: Ask this responder to check an organisation's attestation for a key, by `dns`…
tags:
- Identity
/v1/entity:
post:
description: 'Give a real-world object (a bridge, a farm plot, a river, a named place) a single, shared, content-addressed identity that any agent resolves the same way. Returns an `entity_token` (`emem:entity:`) plus a signed receipt that attests how the reference resolved. Two agents that name the same object mint the SAME entity_cid; when a stable external id (Overture GERS / OSM) is known it dominates identity, so divergent labels for one real object still collapse to one id. This is the object-level antidote to referential drift: ''the damaged bridge near the river'' becomes one canonical thing every model reasons about, not a phrase each model re-interprets.
When to use: Call when a conversation refers to a THING and you want a handle that survives summarisation and travels between agents, before it drifts into ''that infrastructure issue''. Anchor it with `place`, `cell`, or `lat`+`lng`, then hand the `emem:entity:` token to any peer and they dereference the same object; recall at its cell64 for signed facts. Pick the sibling: this one MINTS or returns an identity you can anchor; `emem_entity_resolve` finds one someone already registered from a fuzzy phrase; `emem_entity_link` asserts two spellings you hold mean one object. Not for an observation (that is a fact: emem_recall or emem_memory_token) and not for naming a place (that is emem_locate). An entity is a thing AT a place.'
operationId: emem_entity
requestBody:
content:
application/json:
schema:
properties:
cell:
type: string
external_ids:
properties:
gers:
type: string
osm:
type: string
wikidata:
type: string
type: object
kind:
type: string
label:
type: string
lat:
type: number
lng:
type: number
parent:
type: string
place:
type: string
required:
- label
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: Mint (or idempotently get) a canonical, content-addressed identity for a…
tags:
- Identity
/v1/entity/alias:
post:
description: 'Record a signed, ATTRIBUTED claim that a label or external id (GERS / OSM / Wikidata) denotes an existing object, or with `stance: "disputes"` that it does not. A shared-space write: it changes what other agents resolve, so it is stored with your key, rate-limited per key, and weighed by how many INDEPENDENT keys agree. One key''s binding is shown to every reader as one key''s claim, never as the answer.
When to use: Call when you can vouch that two phrasings denote one object, or to attach an authoritative external id; your key goes on the record. Use `stance: "disputes"` when another key''s binding is wrong: recorded beside it, deletes nothing. Corroborating a correct single-key binding is useful in itself.'
operationId: emem_entity_link
requestBody:
content:
application/json:
schema:
properties:
alias:
type: string
entity_cid:
type: string
entity_token:
type: string
external_ids:
properties:
gers:
type: string
osm:
type: string
wikidata:
type: string
type: object
stance:
description: asserts (default) or disputes; both attributed to your key, append-only
enum:
- asserts
- disputes
type: string
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: Record a signed, ATTRIBUTED claim that an alternate label or a stable external…
tags:
- Identity
/v1/entity/resolve:
post:
description: 'Find the objects agents have bound a phrasing to, ranked by INDEPENDENT corroboration, never arrival order. Each candidate carries `asserted_by`, `disputed_by`, `independent_attesters` and `corroboration` (`single_key` | `multiple_independent_keys` | `none_attributed`); `contested` is set when more than one object claims the name. `text` for candidates, `near` to narrow by place, or an `emem:entity:` `token` to dereference. Read-only; alias text is other agents'' data.
When to use: Call BEFORE minting and before citing: resolve first, mint only if nothing matches, read `corroboration` before you cite. A `single_key` binding is one agent''s claim about a shared name; if you can vouch for it, corroborate it with emem_entity_link so the next reader sees two keys.'
operationId: emem_entity_resolve
requestBody:
content:
application/json:
schema:
properties:
k:
type: integer
label:
type: string
near:
type: string
text:
type: string
token:
description: 'emem:entity:<entity_cid> (legacy meme: accepted) to dereference'
type: string
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: Resolve a fuzzy phrasing to the objects agents have bound it to, ranked by…
tags:
- Identity
/v1/entity/{id}:
get:
description: 'Give a real-world object (a bridge, a farm plot, a river, a named place) a single, shared, content-addressed identity that any agent resolves the same way. Returns an `entity_token` (`emem:entity:`) plus a signed receipt that attests how the reference resolved. Two agents that name the same object mint the SAME entity_cid; when a stable external id (Overture GERS / OSM) is known it dominates identity, so divergent labels for one real object still collapse to one id. This is the object-level antidote to referential drift: ''the damaged bridge near the river'' becomes one canonical thing every model reasons about, not a phrase each model re-interprets.
When to use: Call when a conversation refers to a THING and you want a handle that survives summarisation and travels between agents, before it drifts into ''that infrastructure issue''. Anchor it with `place`, `cell`, or `lat`+`lng`, then hand the `emem:entity:` token to any peer and they dereference the same object; recall at its cell64 for signed facts. Pick the sibling: this one MINTS or returns an identity you can anchor; `emem_entity_resolve` finds one someone already registered from a fuzzy phrase; `emem_entity_link` asserts two spellings you hold mean one object. Not for an observation (that is a fact: emem_recall or emem_memory_token) and not for naming a place (that is emem_locate). An entity is a thing AT a place.'
operationId: emem_entity_get
parameters:
- description: 'entity_cid or emem:entity:<entity_cid> (legacy meme: accepted)'
in: path
name: id
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: 'Dereference a canonical object by entity_cid or emem:entity: token to its…'
tags:
- Identity
components:
schemas:
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