API reference
28 endpoints. Base URL https://api.wontopos.com, JSON in and JSON out, one
API key in an X-API-Key header. Every call is scoped to a store — the user_id that holds one end-user's memories.
Two things authenticate a call. The API key says which account you are, and user_id says whose memories you are touching. Stores are explicit: reading or
writing a store that was never created returns a 404 rather than inventing one. Start with Create a store.
Writing memories
Put something in, correct it later, or take it back out.
- POST /api/v1/memory/store Store one memory
- POST /api/v1/memory/store-turn Store a conversation turn One user + assistant exchange into short-term and long-term memory.
- POST /api/v1/memory/bulk-store Bulk-ingest a large blob Split and indexed server-side. For backfilling long histories.
- POST /api/v1/memory/supersede Supersede an out-of-date memory Replaces old content with new; the old memory stops answering. Speaker tags follow.
- POST /api/v1/memory/forget Delete one memory — or every memory in the store With memory_id: delete that memory. WITHOUT memory_id: delete EVERY memory in the store (GDPR erase). Omitting the id is destructive by design — send it explicitly for single deletes.
Reading memories
Semantic search, one-call context, and plain reads that return the original text.
- POST /api/v1/memory/search Search memories Returns
memories, ordered most useful first. Two more fields can appear beside it:imageswhen you passmax_images, andverify_usedwhen you passverify— the number of extra passes that actually ran, which is what you are billed for. In the SDKs,search()returns the merged list of memories only and does not carry those two fields. Usesearch_full()(searchFull()in TypeScript) when you pass either option, or the results you paid for have nowhere to arrive. - POST /api/v1/memory/recall One-call LLM context Short-term turns + long-term matches + surrounding context in one bounded call.
- POST /api/v1/memory/get Fetch one memory by id (the original text you stored) Returns a single stored memory by the id that /store or /list returned — the original text plus its metadata, and nothing internal. Same visibility as /list: an id that is not a stored memory, an invalidated memory, or an id from another store is a 404.
- POST /api/v1/memory/list List a store’s memories (the original text you stored) Paginates the raw memories in a store — the text you stored plus its metadata, and nothing internal. Use it to browse or export a store. Pass the returned
next_cursorback ascursorfor the next page; a null cursor means the last page. - POST /api/v1/memory/history Recent turns (short-term memory)
- POST /api/v1/memory/stats Memory counts for a store
Images
An image can be the memory itself, found by a sentence in any language.
- POST /api/v1/memory/image The picture we hold for an image memory The only call on this plane that answers with something other than JSON: the stored image itself, with its own Content-Type. Not necessarily your upload — anything over 1568px on its long edge was stored downscaled, and re-encoded to WebP unless it was a JPEG, so a PNG comes back as image/webp. When the format changed,
x-wos-image-converted-fromnames what you sent; take the file extension from Content-Type rather than from your upload. A memory that exists but carries no image is a 404, same as an unknown id. - POST /api/v1/memory/images A store’s image memories, newest first Cursor paging, never an offset: hand
next_beforeandnext_skip_idsback asbeforeandskip_ids. A bulk write stamps many memories with the SAME instant, so cutting on time alone silently drops the rest of that instant.countis the store total, so you can show “142 images” without walking every page. - DELETE /api/v1/memory/image Remove the image, keep the text Drops the image and leaves the caption — unless the memory was only a image, in which case the memory goes too. The response says which happened.
preview: trueasks without changing anything.
Stores
Each end-user gets their own store. Stores are explicit: writing to one that does not exist is a 404.
- POST /api/v1/memory/collection Create a store Stores are explicit: a store must exist before you write to or read it. Idempotent. Every account starts with a built-in "default" store.
- GET /api/v1/memory/collections List your stores
- DELETE /api/v1/memory/collection Delete a store and ALL its memories Destructive. Also drops the store’s registered speakers and their tags.
Speakers
Who said each memory, so a group conversation does not collapse into one voice.
- POST /api/v1/memory/speakers Register a person Speakers are explicit, like stores: register once, then store with metadata.speaker. "me" (the agent itself) is reserved, exact lowercase, never registered and never counted. Up to 50 people per store to start.
- GET /api/v1/memory/speakers List registered people
- DELETE /api/v1/memory/speakers Unregister a person Their memories stay; the name tag goes. Re-registering does not restore old tags.
- POST /api/v1/memory/by-speaker What one person said, newest first
speakeris the tag written at store time —"me"for the assistant’s own words, otherwise a registered name. Same cursor paging as /images.chunksandrecords_to_deletesay how much a delete would actually remove, which is usually more thanreturned— worth showing someone before they confirm one. (points_to_deleteis the same number under a deprecated name.)
Engrams
Multi-hop retrieval pipelines the engine runs for you, with no LLM in the loop.
- GET /api/v1/engram List engrams the selected model can run
- POST /api/v1/engram/run Run an engram Built-in multi-hop retrieval in one call. Call GET /api/v1/engram for the catalog the selected model can run, with a description of each. Available: deep_recall, timeline, equilibrium, tone_stabilizer, gather. Input is billed per engine hop the engram performs, output by what it returns.
Won — calls for the model
Free, rate-limited calls meant for the model to ask on its own, not for your UI.
- POST /api/v1/won/revisions How much of this store has been altered How many memories in this store have been changed since they were written. Intended to be asked freely — by your app and by a model reading its own store — so it carries NO charge: no tokens, no per-request fee. Rate limited to 10 requests per minute, counted per endpoint per account, separately from your paid limit. Counts transforms (supersede); does not count deletions — a deleted memory leaves nothing to count — and counts only the memories you stored, not anything the engine keeps for itself. By default the answer is COUNTS ONLY, and its size does not depend on how much memory you have: a store of a hundred and a store of a hundred million get the same few numbers back. Send
includeto also receive one page of the memories behind a number — at most 20 per call, and never both lists at once. Page withbefore/skip_idsfrom the previous response, as /api/v1/memory/images does. Also served at /api/v1/memory/revisions, which is where clients published before 2026-08-18 call it; the two share one rate-limit budget. - POST /api/v1/memory/revisions How much of this store has been altered (alias of /api/v1/won/revisions) The original path for this call, kept for good: wontopos-mcp 1.0.14 and every client published before 2026-08-18 call it here. Identical behaviour, identical rate-limit budget — see /api/v1/won/revisions for the full description.
- POST /api/v1/memory/lineage The chain of edits behind one memory, oldest first /won/revisions says how much a store moved; this says what happened to one fact.
is_currentmarks the version in force.
Service
What is live and what this account can reach.
Errors
Errors come back with the HTTP status and a JSON body carrying a machine-readable code and a sentence a human can act on. The rules the whole API follows:
- Out of range is refused, not clamped. Asking for 20 results and silently getting 10 reads as "that is all there is", which is a worse failure than an error.
- A missing store is a 404, not an empty result. A cold store must never look like an empty one.
- 401 means the key is missing or wrong. 429 means you hit the rate limit for your tier.
The full status list, rate limits per tier, and retry guidance are in Errors & limits.
For coding agents
The whole API fits in one file at llms.txt — drop it into an IDE or a
coding agent and build. The machine-readable schema is at openapi.json (OpenAPI 3.1), and the same
surface is available over MCP with npx -y wontopos-mcp.