Ingest documents at scale
Load documents, or structured items and edges, into institutional memory with POST /api/v1/institutional/ingest/batch.
Prerequisites
Section titled “Prerequisites”- An Enterprise install. On Core the endpoint returns
403 enterprise_required. - The URL of the workspace’s memory-api, exported here as
MEMORY_API. - A ServiceAccount bearer token in an
Authorization: Bearerheader wheninternalServiceAuth.enabledis set. See Memory API. - A
workspace_idin each request body (the workspace name or UID) when the memory-api has not resolved its own Workspace UID. Otherwise omit it.
Submit a document batch
Section titled “Submit a document batch”-
Post up to 100 documents under one
sourcename. Each document needs aurl, which is the key of its node and chunks.Terminal window curl -fsS -X POST "$MEMORY_API/api/v1/institutional/ingest/batch" \-H 'Content-Type: application/json' \-d '{"source": "handbook","documents": [{"title": "Returns policy","url": "https://docs.example.com/returns","site": "operations","text": "# Return window\nCustomers may return unused items within 30 days.\n\n# Exclusions\nPersonalised items are excluded.","author": "Operations","modified_at": "2026-09-01T00:00:00Z","content_hash": "sha256:replace-with-source-hash"}]}' -
Read the
202response. It carriesaccepted,skipped,forgotten,rejectedandembedding_backlog. A document or item that fails lands inrejectedwith its reason, and the rest of the batch still lands. -
Choose how the body is split. Send
sections[]on a document when the source already knows its headings. Otherwise sendtext, and memory-api splits it on Markdown headings. Chunks are cut within sections using the ingestion strategy from the workspace’s MemoryPolicy. See MemoryPolicyingestion.
Submit structured items and edges
Section titled “Submit structured items and edges”Send items[] and edges[] instead of documents[] for code indexers and other sources that already know their structure. A request carries at most 5000 items.
{ "source": "repo-main", "items": [{ "about": {"kind": "function", "key": "pkg.Save"}, "kind": "function", "name": "Save", "content": "Writes a memory.", "metadata": {"path": "memory/store.go"} }], "edges": [{ "from": {"kind": "file", "key": "memory/store.go"}, "to": {"kind": "function", "key": "pkg.Save"}, "type": "defines" }]}Items upsert by about. Edges resolve both endpoints by the same references, from this request first and then from items already stored. An edge whose endpoint is unknown is rejected without failing the batch.
Keep the corpus in step with the source
Section titled “Keep the corpus in step with the source”-
Set a
content_hashon each document. A re-ingest with the same hash, source and chunking settings is skipped. Items are always written. -
Re-ingest a shortened document to remove the surplus chunks.
-
Add a
presentmanifest to forget items of one kind that left the source:"present": {"kind": "document", "keys": ["https://docs.example.com/returns"]}Entries of that kind from the same source whose key is not listed are forgotten, along with the chunks of forgotten documents.
-
Remove everything one source wrote:
Terminal window curl -fsS -X DELETE "$MEMORY_API/api/v1/institutional/sources/handbook"This soft-deletes every institutional entity whose source is
handbookand returns the count asforgotten.
Verify
Section titled “Verify”List the documents a source wrote:
curl -fsS "$MEMORY_API/api/v1/institutional/documents?source=handbook"Each document reports chunk_count, section_count and embedded_count. Ingest does not wait for vectors, so embedded_count trails chunk_count until the backlog drains. Follow Operate memory embeddings to drain it.
Troubleshooting
Section titled “Troubleshooting”The request returns 403
Section titled “The request returns 403”The response body enterprise_required means the install is Core. A body saying the workspace “is not this memory-api’s workspace” means the workspace_id or workspace names another workspace: send this memory-api’s workspace name or UID, or omit it. Any other 403 comes from service authentication: send a valid ServiceAccount bearer token.
The request returns 400
Section titled “The request returns 400”Check the error text. The causes are a missing source, more than 100 documents or 5000 items, or a missing workspace_id where one is required.
A document appears under rejected
Section titled “A document appears under rejected”A document with no url is rejected under its title. Fix the field and resend that document.
Related pages
Section titled “Related pages”- Memory API lists every endpoint.
- Write an S3 memory populator builds a sync loop on this contract.
- Operate memory embeddings