> ## Documentation Index
> Fetch the complete documentation index at: https://metacognition-fdc534de-master.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Ingest conversation memory

> Write turns under a scope. Active memory is saved first; enrichment continues in the background.

This is the REST version of **`tex.conversations.remember`**. Use it to write turns under a scope. Tex saves active memory first, then continues enrichment in the background.

## Headers

```http theme={null}
Authorization: Bearer <access_token>
Content-Type: application/json
```

## Body

```json theme={null}
{
  "scope": {
    "org_id": "org_...",
    "user_id": "user_...",
    "session_id": "chat-1"
  },
  "turns": [
    {
      "role": "user",
      "text": "I'm allergic to shellfish.",
      "timestamp": "2026-05-08T14:00:00Z"
    },
    {
      "role": "assistant",
      "text": "Got it.",
      "timestamp": "2026-05-08T14:00:01Z"
    }
  ],
  "options":  { "write_active": true, "write_passive": true },
  "metadata": { "channel": "support" }
}
```

<ParamField body="scope.org_id" type="string" required>
  Your org id. Minimum length is 1 character. The server still uses the JWT's `org_id` claim for tenancy; this field is required for request validation.
</ParamField>

<ParamField body="scope.user_id" type="string">
  End-user partition. Defaults to the JWT's user.
</ParamField>

<ParamField body="scope.session_id" type="string">
  Conversation/channel/task id. Defaults to the JWT's `session_id` if set, else `"default-session"`.
</ParamField>

<ParamField body="turns" type="array" required>
  At least one turn (`min_length=1`). Each turn: `{role, text, timestamp, observations?}`. See [How memory works](/concepts/memory-model).
</ParamField>

<ParamField body="options" type="object">
  Optional write toggles: `{ write_active: bool = true, write_passive: bool = true }`. Advanced callers can disable one storage tier.
</ParamField>

<ParamField body="metadata" type="object">
  Free-form metadata. It is stored today and reserved for future filters.
</ParamField>

## Response — `202 Accepted`

<ResponseField name="job_id" type="string">
  Stable id for this write.
</ResponseField>

<ResponseField name="active_fragment_ids" type="array[string]">
  Active-memory fragment ids. These are already recallable.
</ResponseField>

<ResponseField name="passive_job_id" type="string | null">
  Background enrichment job id, when one is needed.
</ResponseField>

<ResponseField name="usage" type="object">
  `{tokens_in, tokens_out}` billed for this call.
</ResponseField>

```json Response theme={null}
{
  "job_id": "1737f27b090743bab9f129b48fd44831",
  "active_fragment_ids": [
    "c9fcfbf51b03bbc3c05075671b5fa5aa7e34d803c13b554391746188bfa22d22"
  ],
  "passive_job_id": null,
  "usage": { "tokens_in": 6, "tokens_out": 0 }
}
```

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.getmetacognition.com/ingestion/memory \
    -H "Authorization: Bearer $JWT" \
    -H 'content-type: application/json' \
    -d '{
      "scope": {"org_id":"org_…","session_id":"chat-1"},
      "turns": [
        {"role":"user","text":"hello","timestamp":"2026-05-08T14:00:00Z"}
      ]
    }'
  ```

  ```python Python theme={null}
  import httpx

  resp = httpx.post(
      "https://api.getmetacognition.com/ingestion/memory",
      headers={"Authorization": f"Bearer {jwt}"},
      json={
          "scope": {"org_id": "org_…", "session_id": "chat-1"},
          "turns": [
              {"role": "user", "text": "hello", "timestamp": "2026-05-08T14:00:00Z"}
          ],
      },
      timeout=10,
  )
  resp.raise_for_status()
  ```
</CodeGroup>

## Idempotency

Tex computes a stable hash per turn from `role`, `text`, and `timestamp`. Re-sending the same turn is a no-op. It does not create duplicate fragments or double bill the turn. It is safe to retry after a network failure.
