---
title: "Unified dual-write ingest (active memory + HelixDB)"
method: POST
path: "/ingestion/memory"
tags: ["ingestion-memory"]
---

# Unified dual-write ingest (active memory + HelixDB)

`POST /ingestion/memory`

## Request

- Base URL: `https://api.getmetacognition.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getmetacognition.com/ingestion/memory`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/metacognition/apis/tex-api/docs/ingestion/memory/post.ts> (a function with typed inputs; its response is checked against the schema)

Fan a list of conversational turns out to active memory + HelixDB.

``scope`` accepts BOTH shapes (shared contract with the SDK):
- legacy tenant dict {org_id, user_id, session_id} -> unchanged behavior;
- hierarchical write-scope string "<kind>:<value>" -> validated against
  the caller's visible scopes (403 with explanatory body otherwise) and
  stamped on every HelixDB write (X-Scope-Id). org/user then come from
  the auth context; the session is the body's top-level session_id when
  given (the SDK sends it alongside a string scope), else the auth
  context's, else "default-session".

## Request body

- IngestMemoryRequest: Request body for POST /ingestion/memory.
  - `timezone` string, nullable: The caller's timezone (IANA name, e.g. Europe/Berlin, or +HH:MM) for natural-language turn timestamps such as "yesterday 3pm"; default UTC
  - `scope` union, required: Tenant scope dict (legacy) OR hierarchical write-scope string "<kind>:<value>" (org/user then come from the auth context)
    - string
    - Scope: Multi-tenant scope.
      - `org_id` string, required: Organization ID
      - `user_id` string, nullable: User ID
      - `session_id` string, nullable: Session ID
  - `session_id` string, nullable: Explicit session id, honored on the string-scope path (the SDK sends it alongside a string scope; the legacy dict carries its own)
  - `agent_id` string, nullable: Agent identifier for the active-memory episode; falls back to default-agent if unset (same default as /recall)
  - `turns` IngestTurn[], required: At least one turn is required
    - `text` string, required: Turn text content (not blank, at most 65,536 characters; split into fragments)
    - `role` 'user' | 'assistant', required: Speaker role
    - `timestamp` string, required: Capture time: ISO 8601 (e.g. 2026-01-01T09:30:00Z) or epoch seconds/milliseconds, or natural language ("yesterday 3pm", "last Tuesday", "2 hours ago") resolved against the request's arrival time in `timezone`; anything else is stored with the arrival time, marked uncertain
    - `observations` string[]: Caller-supplied atomic facts to attach to this turn (each one fragment, at most 3800 characters)
  - `supersedes` string[], nullable: turn_ids this write CORRECTS. Each is retired once the new turns are durably stored, so a correction replaces the earlier text instead of sitting beside it. A turn id cannot be edited in place: its id is a hash of its own content, so a new version is always a new id, and this is what links them.
  - `options` IngestMemoryOptions: Toggles for the dual-write behaviour of /ingestion/memory.
    - `write_active` boolean: Write to active-memory worker
    - `write_passive` boolean: Write to HelixDB (passive tier)
    - `ingest_mode` 'sequential' | 'batched', nullable: Internal: write path override (platform admin only; ignored otherwise)
  - `inactivity_timeout_seconds` integer, nullable: Idle time in seconds after which this active-memory episode is closed and consolidated into long-term memory. Stored on the episode (later writes without it keep it). Omitted: the org default, else 1800 (30 min). Bounds: 300-86400.
  - `metadata` object, nullable: Free-form caller metadata (currently unused)

## Response `202`

Successful Response

- IngestMemoryResponse: Response for POST /ingestion/memory.
  - `turn_times` TurnTime[]: Each turn's resolved capture time, in request order
    - `turn_index` integer, required
    - `original` unknown, required
    - `timestamp` string, required: Capture time, ISO 8601 UTC
    - `timestamp_ms` integer, required
    - `source` 'explicit' | 'relative' | 'arrival', required: explicit time / natural language resolved against arrival / not understood
    - `uncertain` boolean, required: True when the capture time is only the arrival time
  - `job_id` string, required: Per-call observability id (uuid hex)
  - `active_fragment_ids` string[]: Fragment ids written to active memory (turn first, then observations)
  - `turn_ids` string[]: Turn id (the item's content hash) of each stored item, parallel to active_fragment_ids. This is the handle for retiring a remembered turn (DELETE /ingestion/memory/turns/{turn_id}); the fragment id is a one-way hash of scope+turn id and cannot be converted back.
  - `not_stored_forgotten` string[]: turn_ids in this request that were NOT stored because their owner had forgotten them (a resend of history, a retried batch). They are refused rather than brought back; remember new text to store it again.
  - `superseded` string[]: turn_ids this write retired, from the request's `supersedes`
  - `supersede_errors` string[]: Why a requested supersede did not complete. Non-empty means the OLD turn may still answer recall alongside the new one — the new turns are stored regardless, so this is never a reason to retry the whole write.
  - `passive_job_id` string, nullable: Reserved for future async passive job tracking
  - `usage` Usage: Token usage for a metered API call. Surfaced on every metered response so developers can see the cost of each call inline — mirrors OpenAI / Anthropic ``usage`` objects so the Tex bill is denominated in the same unit they already track for their LLM provider. Tokens are counted server-side with the ``cl100k_base`` encoding (matches ``text-embedding-3-large``).
    - `tokens_in` integer: Tokens in the request payload
    - `tokens_out` integer: Tokens in the response payload

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/metacognition/apis/tex-api.md) - [All operations](https://skmtc.dev/metacognition/apis/tex-api/llms.txt) - [OpenAPI document](https://skmtc.dev/metacognition/apis/tex-api/revisions/3bef47e50f2e?raw)
