Skip to main content

Store a memory

user_id is a real field, not metadata. Putting a user id in metadata stores it but does not isolate anything: metadata is returned with results, never filtered on.
Response 201 Created
A synchronous write is slow, and async is roughly ten times faster. A memory is analyzed by a language model and its facts extracted before the call returns, so record waits for that work. Measured against production with a one-sentence memory:Anything a person is waiting on (a chat turn, a form submit, a page transition) should use async mode below. Reach for a synchronous write only when the very next thing you do is search for what you just stored.

Store a memory asynchronously

Set "async": true and the call returns in about a second with a job_id and status: "processing" in place of the stored memory_id. The memory is extracted and indexed in the background; poll the job to learn when it is searchable. This is the recommended way to write. The extraction work is identical and costs the same; you simply stop waiting for it. The one thing that changes is timing: the memory is not searchable the instant the call returns, so a flow that writes and then immediately retrieves needs to wait for the job (or use a synchronous write).
Pair async writes with webhooks and you can drop polling entirely: Anona posts to your endpoint when the memory is stored.

Bulk ingest

Queue many memories in a single call, which is the efficient way to backfill history. Bulk ingest is always asynchronous: the batch is accepted and a job_id returned immediately.
Response 202 Accepted
accepted is the number of items queued. Poll job_id for progress. A large batch may be split into several operations, all listed under job_ids.
To send more than 100 items, chunk them into multiple calls. Each item is charged a base cost when queued and reconciled to its real cost once processing finishes, exactly as a synchronous write is, so queuing does not make ingestion cheaper.

Job status

Checks a job returned by an async record or by record/batch. This read is free and consumes no credits.
memory_count and memory_ids are set once the job completes — they are how you address the memories an async write produced. While a batch is running, progress carries {stage, processed, total, parts_done, parts_total, memories_stored, updated_at}; processed/total count chunks in the parts that have started, so parts_done / parts_total and status are the completion signals, not processed == total. A 404 is returned when the job_id does not belong to the space.

Poll until complete

A record/batch job is polled exactly the same way. completed means every item in the batch has been stored and is searchable.

Cancel a job

Stops an ingestion job that has not finished. Cancelling is free, consumes no credits, and is never refused for an empty balance: a runaway import must always be stoppable.
Response 200 OK
A job is split into parts that run independently, and only a part still queued can be stopped. A part already being processed runs to completion. cancelled_parts is what this call stopped; running_parts is what it could not, so poll the job afterwards to see those finish.
Cancelling does not undo work already done. Memories written by parts that ran stay stored and searchable, and the base cost charged when the job was queued is not refunded — but the parts that never run are never charged for the extraction they would have done.
cURL

List memories in a space

Response 200 OK
Anona stores knowledge in two layers: the raw facts you record, and the note it synthesizes from them once they settle. Both describe the same thing, so listing them side by side reads as duplicates, so by default this endpoint returns the note and hides the facts folded into it. source_ids names those facts, and prefer_observations=false lists them as rows of their own. total follows the same rule, so paging stays consistent either way.
List results use different field names from the rest of the API. Map them before reusing the objects elsewhere.entities also differs in shape: the list returns a single comma-separated string, while retrieve returns an array of strings.

Edit or retire a memory

Correct what was stored, or reversibly retire it. Every field is optional; only what you send changes.
The response is the updated memory in the same shape the list returns, including its state, so an invalidate or restore can be confirmed from the reply. Notes (type: "note") cannot be edited — they are synthesized, and the engine rejects the attempt rather than letting a synthesis drift from its evidence.

Memory history

Memories are living records. As new information arrives, Anona updates what it knows and keeps the previous version. Fetch a memory’s history to see what it said before and when it changed.
Entries are written both by Anona’s own consolidation and by your edits. An empty history array means the memory has never changed.

Delete a memory

Response 204 No Content. The deletion is permanent and the body is empty. There is no endpoint for fetching a single memory by id — read one through listing or retrieve. Updating one is PATCH, above.

Error responses

See the full error reference.

Next steps

Retrieve API

Query memories semantically.

Reason API

Synthesize an answer across memories.

Documents

Ingest files into the same space.

Webhooks

Get told when ingestion finishes.