Ingest memories
Async ingest. Returns 202 + job_id by default; the extraction
runs in the background and the caller polls
GET /v1/memories/jobs/{job_id}.
With ?wait=true the server holds the connection up to ~30
seconds waiting for extraction to terminate. If it finishes in
time, the response is 200 OK with the terminal job inline
(status: "succeeded" or "failed"). If the wait window
elapses first, the response falls back to 202 + pending and
the caller resumes the normal polling pattern.
Documentation Index
Fetch the complete documentation index at: https://docs.mem.xtrace.ai/llms.txt
Use this file to discover all available pages before exploring further.
Authorizations
Long-lived org API key. Alternative: Authorization: Bearer <key>.
Required alongside the API key (no key→org reverse index).
Headers
Query Parameters
When true, hold the connection up to ~30s waiting for extraction to terminate. Returns 200 + terminal job inline on success; falls back to 202 + pending on timeout. Default false → 202 + pending immediately.
Body
POST /v1/memories — async ingest from a message list.
Required entities: user_id and conv_id. user_id keys
xmem's per-user session-cache namespace (one MultiKBSet per
(org, user), so a user's facts accumulate in one place rather
than fragmenting per-conversation). conv_id anchors every
extracted memory to a conversation for replay, export, and bulk
retract. agent_id and app_id remain optional — set either,
both, or neither. There is no auto-default app_id rule.
extract_artifacts opts in to the artifact-extraction stage
(off by default — most expensive stage and most callers don't
need it). Episodes are always extracted (conv_id is now
guaranteed). Facts are always extracted. (Per SoT decision #4.)
There is no client-facing pipeline hint: the server picks live
vs batch by len(messages) (SoT decision #4 + Settings
threshold).
Chat-style turns to extract memories from. Must be non-empty — an empty list returns 400 invalid_messages (the route raises this explicitly so the wire error carries the stable code rather than a generic Pydantic validation message). Server picks live vs batch extraction by length; no client-facing strategy hint.
User identifier. REQUIRED. Keys the per-user session namespace so a user's facts accumulate across their conversations rather than fragmenting per-conv. Also stored as an indexed filter axis on every row.
1"alice"
Conversation identifier. REQUIRED. Anchors every extracted memory to a conversation for replay, export, and bulk retract.
1"conv-2026-05-15-abc"
Optional agent scope. Indexed alongside the other entity ids.
Optional app scope. Indexed alongside the other entity ids.
Free-form customer metadata. Each key lands as its own indexed payload key, filterable on search. Reserved internal keys (tag1-tag5, kb_type, org_id, etc.) are stripped silently — see the reserved_field PATCH error for the list.
When true, run the artifact-extraction stage in addition to fact + episode extraction. Off by default — most expensive stage and most callers don't need it. Setting this routes the request through the batch extraction path regardless of message count.
Response
Inline terminal response. Returned when ?wait=true is set and the extraction pipeline completes inside the wait window (~30s). Body is the terminal IngestJobResponse with status: "succeeded" (carrying result) or "failed" (carrying error).
Returned by POST /v1/memories (with status 202 by default,
200 when ?wait=true succeeds inline) and by
GET /v1/memories/jobs/{job_id}. Same wire shape across
every read of a job's lifecycle.
Opaque job id of the form job_<32-hex-chars>.
"job_a1b2c3d4e5f6071829304a5b6c7d8e9f"
Lifecycle state. pending → enqueued. running → extraction in progress. succeeded → result is set. failed → error is set. Terminal jobs (succeeded / failed) are retained for 24h before TTL sweep returns 404 job_not_found.
pending, running, succeeded, failed ISO-8601 timestamp the job was created.
Constant discriminator for the resource type.
"ingest_job"ISO-8601 timestamp of the most recent state transition.
Populated when status = succeeded; null otherwise.
Populated when status = failed; null otherwise.