Skip to main content
A document is parsed, split into chunks, and stored as memory, so the same Retrieve and Reason calls surface file content alongside anything you recorded conversationally.
Legacy .doc and .ppt are accepted and then fail. The upload returns 202, and the job ends failed because there is no reader for the old binary formats yet. Save as .docx / .pptx first. Audio from voice-memo apps is usually .m4a, which is refused outright — convert it to MP3.

Upload files

If you use scoping, upload with the same scope you retrieve with. Scoped search is strict, so a document uploaded without user_id is not returned to a search with one: it is only reachable from an unscoped search.
Video is allowed more because 25 MB is a few seconds of it at any real bitrate. Ingestion is always asynchronous. The call returns immediately with a job_ids list; poll each with the job status endpoint. When a job reaches completed, that file’s content is searchable. For an upload the job’s own memory_count and memory_ids stay null; how many memories a file produced is on the document — memory_count from List documents.
Known issue: files over about 1 MB currently fail. Above roughly 1 MB per file, the request is refused with 400 bad_request (“There was an error parsing the body”) instead of being accepted up to the limits above. Several smaller files in one request work. We are fixing this; until then, split or compress large files.
Uploading to a space that does not exist yet creates it, exactly as a first record does — an upload is a write, so there is no space to pre-create. Response 202 Accepted
The TypeScript client takes 1–20 files in one call; the Python client takes one per call. Both carry user_id / agent_id / session_id (userId / agentId / sessionId in TypeScript), and passing them matters whenever the space is scoped at all: a scoped retrieve is strict, so an upload written without scope is invisible to every scoped query — silently, since the files are stored and the job completes.
Parsing and embedding a document is billed on completion, not at upload. Larger files cost more, because more content is processed. Images and audio are read into text first and then treated as text, so each costs what its reading costs.An image yields a verbatim transcription of any text in it, so a screenshot is worth uploading; a photograph with no text in it currently yields little, since the description of what it shows is not being produced yet. A video yields its on-screen text and a description of what happens. Speech in a video is not transcribed yet — for a recording where the words matter, upload the audio track as MP3.Very long recordings are rejected rather than truncated: a transcript that stopped early would be stored as though it were the whole thing. Split a long recording and upload the parts.

List documents

Response 200 OK
memory_count is how many searchable memories were extracted from the document.

What counts as a document

This list contains everything ingested into the space, not only uploaded files. Storing a memory with POST /v1/record also creates a document row, so source tells you which is which. Newest rows come first, and a space with steady record traffic accumulates memory rows fast, so uploads are often not on the first page. Ask for the kind you want rather than paging until you find it:
limit and offset then apply to the filtered set, and total counts only the matching documents. Every memory that was ingested belongs to a document — an uploaded file, or the memory row POST /v1/record writes for it — and carries that document_id on retrieve and in the listings, so you can walk from a search hit back to the document that produced it, and deleting a document removes every memory extracted from it. document_id is nullable, and the common null is a note: a consolidation is derived from raw facts rather than ingested, so it belongs to no document. Walk its source_ids to the facts it was built from, and read their document_id.
The dashboard’s Documents tab hides memory rows by default for this reason, with a toggle to show everything ingested.

Get a document

Returns the document’s metadata and ingestion status, in the same shape as one item in the list above.

Delete a document

Removes the document and every memory extracted from it. On a space shared with you, only the owning organization can delete a document, whatever your role: deleting one removes memories other members wrote and rely on, the same reason memory delete is owner-only.
Response 204 No Content.

Error responses

See the full error reference.

Next steps

Retrieve API

Search across recorded memory and uploaded documents.

Memories API

Record memories and poll ingestion jobs.