---
title: "Create a chat completion"
description: "Drop-in replacement for OpenAI's `/v1/chat/completions`, with Truememory's persona and memory layers applied to every turn. Supports tools, streaming and all standard parameters.\n\nThe response comes in one of two shapes, depending on `stream`:\n\n- `stream: false` (default) — a single JSON `ChatCompletionResponse`.\n- `stream: true` — `text/event-stream` of `data:` lines, each an OpenAI-style chunk, terminated by `data: [DONE]`."
---

> Documentation Index
> Fetch the complete documentation index at: https://truememory-docs.mvstg.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: AI Gateway API › Chat

`POST /v1/chat/completions`

Drop-in replacement for OpenAI's `/v1/chat/completions`, with Truememory's persona and memory layers applied to every turn. Supports tools, streaming and all standard parameters.

The response comes in one of two shapes, depending on `stream`:

- `stream: false` (default) — a single JSON `ChatCompletionResponse`.
- `stream: true` — `text/event-stream` of `data:` lines, each an OpenAI-style chunk, terminated by `data: [DONE]`.

## Authentication

- `HTTPBearer`, http, header `Authorization`

## Header parameters

- `x-agent-id` (`chat_completions.header.x-agent-id`; any of, optional) — TIE agent to use
  - any of: `string`, `null`
- `x-app-id` (`chat_completions.header.x-app-id`; any of, optional) — Application ID for scoping threads
  - any of: `string`, `null`
- `X-On-Behalf-Of` (`chat_completions.header.X-On-Behalf-Of`; any of, optional)
  - any of: `string`, `null`
- `X-External-User-Id` (`chat_completions.header.X-External-User-Id`; any of, optional)
  - any of: `string`, `null`
- `X-App-Id` (`chat_completions.header.X-App-Id`; any of, optional)
  - any of: `string`, `null`

## Request body

_Required._

- `model` (`chat_completions.model`; string, required) — Model to use, e.g. 'anthropic/claude-sonnet-4-6'
- `messages` (`chat_completions.messages`; array<object>, required)
  - `role` (`chat_completions.messages.role`; string, required)
    - one of `"system"`, `"developer"`, `"user"`, `"assistant"`, `"tool"`
  - `content` (`chat_completions.messages.content`; any of, optional)
    - any of: `string`, `array<one of>`, `null`
  - `tool_calls` (`chat_completions.messages.tool_calls`; any of, optional)
    - any of: `array<object>`, `null`
  - `tool_call_id` (`chat_completions.messages.tool_call_id`; any of, optional)
    - any of: `string`, `null`
  - `name` (`chat_completions.messages.name`; any of, optional)
    - any of: `string`, `null`
  - `cache_control` (`chat_completions.messages.cache_control`; any of, optional) — Anthropic prompt-caching marker applied to the whole message. Example: ``{"type": "ephemeral"}``. Per Anthropic semantics, the marker attaches to the last content block, caching everything up to and including that block. Use this for the simple case (string-content messages); for fine-grained control, set ``cache_control`` on individual content parts. Forwarded to the underlying provider via the LangChain message's ``additional_kwargs``.
    - any of: `object`, `null`
- `tools` (`chat_completions.tools`; any of, optional)
  - any of: `array<unknown>`, `null`
- `stream` (`chat_completions.stream`; boolean, optional)
  - default `false`
- `stream_options` (`chat_completions.stream_options`; any of, optional)
  - any of: `StreamOptions`, `null`
- `temperature` (`chat_completions.temperature`; any of, optional)
  - any of: `number`, `null`
- `max_tokens` (`chat_completions.max_tokens`; any of, optional)
  - any of: `integer`, `null`
- `top_p` (`chat_completions.top_p`; any of, optional)
  - any of: `number`, `null`
- `seed` (`chat_completions.seed`; any of, optional)
  - any of: `integer`, `null`
- `stop` (`chat_completions.stop`; any of, optional)
  - any of: `array<string>`, `string`, `null`
- `max_history_tokens` (`chat_completions.max_history_tokens`; any of, optional) — Cap the replayed thread history to roughly this many tokens, keeping the most recent turns (the window starts on a human turn). Older turns are dropped from the replay — callers that set this should supply their own running summary so older context is preserved. Omit (default) to replay the full history unchanged.
  - any of: `integer`, `null`
- `system_prompt_cache_contract` (`chat_completions.system_prompt_cache_contract`; string, optional) — How to read multi-block system content. "legacy" (default, unchanged behaviour): a block list with no `cache_control` marker anywhere is treated as entirely STABLE — the historical reading, so existing callers that use block lists for structure are unaffected. "explicit": markers are the caller's cacheability declaration — blocks through the last marked one are stable, later blocks are dynamic, and a list with NO marker means nothing is cacheable. Opt in only if you place markers deliberately: under "explicit" an unmarked system prompt is delivered as per-request context inside the user turn, not as a system message.
  - one of `"legacy"`, `"explicit"`; default `"legacy"`
- `prompt_cache_key` (`chat_completions.prompt_cache_key`; any of, optional) — OpenAI cache-routing key (GPT-5.6+), forwarded verbatim to the provider so same-conversation requests land on the same cache shard. Ignored for non-OpenAI models. Send an opaque, privacy-safe value (a hash, never raw user/thread identifiers).
  - any of: `string`, `null`
- `context_management` (`chat_completions.context_management`; any of, optional) — Context-management strategies for this request. At most one entry is supported. Include a `{"type": "compaction", ...}` entry to enable thread compaction: when the upcoming request is over budget (`compact_threshold` when set, else the model's context window minus a buffer), older turns fold into a rolling summary checkpoint before the model call runs; subsequent turns replay the checkpoint plus newer messages instead of the full transcript. The thread's stored history is never modified. Omit to disable.
  - any of: `array<unknown>`, `null`
- `thread_id` (`chat_completions.thread_id`; any of, optional) — TIE thread ID for state persistence
  - any of: `string`, `null`
- `parent_message_id` (`chat_completions.parent_message_id`; any of, optional) — ID of the last stored message the client received. When set, anything already stored after it is not appended again, so a request that failed mid-run can be re-sent unchanged. `messages` holds the messages after it, optionally preceded by replayed history that ends at it; that history is dropped exactly as it is without this field. Use the `message_id` from the previous response. Ignored without `thread_id`: a turn with no thread has no stored state.
  - any of: `string`, `null`
- `store` (`chat_completions.store`; boolean, optional) — Whether to persist this turn to the user's chat history. Default: true. Set to false for system-internal or ephemeral calls. Memory injection (pre-LLM) and usage tracking are unaffected.
  - default `true`
- `persona_id` (`chat_completions.persona_id`; any of, optional) — Persona to use. Falls back to the user's active persona if omitted.
  - any of: `string`, `null`
- `metadata` (`chat_completions.metadata`; any of, optional) — Up to 16 key-value pairs attached to this request. Persisted with the thread and returned in history.
  - any of: `map<string>`, `null`
- `skill_instructions` (`chat_completions.skill_instructions`; any of, optional) — Caller-composed skill prompt. Injected after persona, before memory context. Never replaces persona or base instructions — purely additive.
  - any of: `string`, `null`
- `skill_selection` (`chat_completions.skill_selection`; string, optional) — `auto` lets Truememory pick skills for this turn by matching the user's message against each visible skill's `use_case` and `detection_patterns`. Only skills the caller could already list are considered, and only ones carrying trigger data. Combines with `skills`: explicit keys always apply, matches are added after them. Defaults to `off` — no existing caller changes behaviour.
  - one of `"off"`, `"auto"`; default `"off"`
- `skills` (`chat_completions.skills`; array<string>, optional) — Skill keys to resolve from the registry and inject, in the order given. Truememory reads each skill's stored `prompt`, so the registry stays authoritative instead of each caller pasting a copy. A key you cannot see is a 404, never a silent drop. Resolved prompts are injected before `skill_instructions`, which still works and can be used alongside them for per-request text.
- `skill_files` (`chat_completions.skill_files`; boolean, optional) — Let the model read the files of this turn's skills (from `skills` and `skill_selection`): each such skill's file list follows its prompt, and the model gets a `read_skill_file` tool. Off by default, so a skill injects only its `prompt`, as before. Ignored on a deployment without skill file storage.
  - default `false`
- `memory` (`chat_completions.memory`; any of, optional) — Per-request memory controls. Defaults to read/write enabled for user-scoped requests.
  - any of: `MemoryOptions`, `null`
- `tool_callback` (`chat_completions.tool_callback`; any of, optional) — Callback configuration for tool execution. When set, TIE runs the tool loop and executes caller-defined tools via HTTPS POST to {base_url}/{tool_name}. ``tools`` must also be provided.
  - any of: `ToolCallback`, `null`
- `extra_context` (`chat_completions.extra_context`; any of, optional) — Free-form caller-provided context injected into the system prompt before tool definitions. TIE does not interpret it.
  - any of: `object`, `null`
- `skill_id` (`chat_completions.skill_id`; any of, optional) — Skill ID whose associated knowledge packs are searched and injected into the system prompt. Works alongside skill_instructions — neither requires the other.
  - any of: `string`, `null`
- `knowledge_pack_ids` (`chat_completions.knowledge_pack_ids`; any of, optional) — Explicit knowledge pack IDs to search. Combined with skill_id when both are provided. No document context is injected when both are absent.
  - any of: `array<string>`, `null`
- `brain_id` (`chat_completions.brain_id`; any of, optional) — Brain ID whose knowledge packs are searched and injected into the system prompt. Resolved to knowledge_pack_ids before context injection. Ignored when knowledge_pack_ids is also provided. Singular alias for brain_ids — when both are set, their union is resolved.
  - any of: `string`, `null`
- `brain_ids` (`chat_completions.brain_ids`; any of, optional) — Brain IDs whose knowledge packs are searched and injected into the system prompt. All named brains are resolved to one deduplicated set of knowledge_pack_ids before context injection. Every ID must be readable by the caller — an unknown or unreachable one is a 404, not a silent drop. Ignored when knowledge_pack_ids is also provided.
  - any of: `array<string>`, `null`
- `mind_ids` (`chat_completions.mind_ids`; any of, optional) — Minds whose memory namespaces are blended into per-message retrieval alongside the user's own memory. Each is resolved through the mind read gate, so only minds the caller can actually read take effect; an unknown or unreachable id is a 404, not a silent drop. Namespace facts appear in the injected memory context — conversation ingestion still writes only to the user's own graph.
  - any of: `array<string>`, `null`
- `graph_ids` (`chat_completions.graph_ids`; any of, optional) — Raw shared knowledge-graph namespaces, by slug. Service principals only — a namespace slug carries no ownership, so honouring one from a user token would let any caller read any namespace they can guess. First-party callers name minds instead, via mind_ids.
  - any of: `array<string>`, `null`

## Example request

```json
{
  "model": "string",
  "messages": [
    {
      "role": "system",
      "content": "string",
      "tool_calls": [
        {}
      ],
      "tool_call_id": "string",
      "name": "string",
      "cache_control": {}
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "list_tasks",
        "description": "List user tasks filtered by status",
        "parameters": {}
      }
    }
  ],
  "stream": false,
  "stream_options": {
    "include_usage": false
  },
  "temperature": 0,
  "max_tokens": 0,
  "top_p": 0,
  "seed": 0,
  "stop": [
    "string"
  ],
  "max_history_tokens": 0,
  "system_prompt_cache_contract": "legacy",
  "prompt_cache_key": "string",
  "context_management": [
    {
      "type": "compaction",
      "compact_threshold": 0,
      "keep_tokens": 0,
      "model": "string"
    }
  ],
  "thread_id": "string",
  "parent_message_id": "string",
  "store": true,
  "persona_id": "string",
  "metadata": {
    "property1": "string",
    "property2": "string"
  },
  "skill_instructions": "string",
  "skill_selection": "off",
  "skills": [
    "summarize-thread"
  ],
  "skill_files": false,
  "memory": {
    "read": true,
    "write": true
  },
  "tool_callback": {
    "base_url": "https://api.blinklearn.envision.io/agent-tools",
    "auth_token": "string",
    "timeout_ms": 8000
  },
  "extra_context": {},
  "skill_id": "string",
  "knowledge_pack_ids": [
    "string"
  ],
  "brain_id": "5ff5069c-3661-4a30-92df-9e098e7ad88f",
  "brain_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "mind_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "graph_ids": [
    "string"
  ]
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://truememory-api.mvstg.com/v1/chat/completions \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "string",
  "messages": [
    {
      "role": "system",
      "content": "string",
      "tool_calls": [
        {}
      ],
      "tool_call_id": "string",
      "name": "string",
      "cache_control": {}
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "list_tasks",
        "description": "List user tasks filtered by status",
        "parameters": {}
      }
    }
  ],
  "stream": false,
  "stream_options": {
    "include_usage": false
  },
  "temperature": 0,
  "max_tokens": 0,
  "top_p": 0,
  "seed": 0,
  "stop": [
    "string"
  ],
  "max_history_tokens": 0,
  "system_prompt_cache_contract": "legacy",
  "prompt_cache_key": "string",
  "context_management": [
    {
      "type": "compaction",
      "compact_threshold": 0,
      "keep_tokens": 0,
      "model": "string"
    }
  ],
  "thread_id": "string",
  "parent_message_id": "string",
  "store": true,
  "persona_id": "string",
  "metadata": {
    "property1": "string",
    "property2": "string"
  },
  "skill_instructions": "string",
  "skill_selection": "off",
  "skills": [
    "summarize-thread"
  ],
  "skill_files": false,
  "memory": {
    "read": true,
    "write": true
  },
  "tool_callback": {
    "base_url": "https://api.blinklearn.envision.io/agent-tools",
    "auth_token": "string",
    "timeout_ms": 8000
  },
  "extra_context": {},
  "skill_id": "string",
  "knowledge_pack_ids": [
    "string"
  ],
  "brain_id": "5ff5069c-3661-4a30-92df-9e098e7ad88f",
  "brain_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "mind_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "graph_ids": [
    "string"
  ]
}
'
```

### TypeScript

```typescript
const url = 'https://truememory-api.mvstg.com/v1/chat/completions';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', Authorization: 'Bearer <token>'},
  body: JSON.stringify({
    model: 'string',
    messages: [
      {
        role: 'system',
        content: 'string',
        tool_calls: [{}],
        tool_call_id: 'string',
        name: 'string',
        cache_control: {}
      }
    ],
    tools: [
      {
        type: 'function',
        function: {
          name: 'list_tasks',
          description: 'List user tasks filtered by status',
          parameters: {}
        }
      }
    ],
    stream: false,
    stream_options: {include_usage: false},
    temperature: 0,
    max_tokens: 0,
    top_p: 0,
    seed: 0,
    stop: ['string'],
    max_history_tokens: 0,
    system_prompt_cache_contract: 'legacy',
    prompt_cache_key: 'string',
    context_management: [{type: 'compaction', compact_threshold: 0, keep_tokens: 0, model: 'string'}],
    thread_id: 'string',
    parent_message_id: 'string',
    store: true,
    persona_id: 'string',
    metadata: {property1: 'string', property2: 'string'},
    skill_instructions: 'string',
    skill_selection: 'off',
    skills: ['summarize-thread'],
    skill_files: false,
    memory: {read: true, write: true},
    tool_callback: {
      base_url: 'https://api.blinklearn.envision.io/agent-tools',
      auth_token: 'string',
      timeout_ms: 8000
    },
    extra_context: {},
    skill_id: 'string',
    knowledge_pack_ids: ['string'],
    brain_id: '5ff5069c-3661-4a30-92df-9e098e7ad88f',
    brain_ids: ['497f6eca-6276-4993-bfeb-53cbbbba6f08'],
    mind_ids: ['497f6eca-6276-4993-bfeb-53cbbbba6f08'],
    graph_ids: ['string']
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://truememory-api.mvstg.com/v1/chat/completions"

payload = {
    "model": "string",
    "messages": [
        {
            "role": "system",
            "content": "string",
            "tool_calls": [{}],
            "tool_call_id": "string",
            "name": "string",
            "cache_control": {}
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "list_tasks",
                "description": "List user tasks filtered by status",
                "parameters": {}
            }
        }
    ],
    "stream": False,
    "stream_options": { "include_usage": False },
    "temperature": 0,
    "max_tokens": 0,
    "top_p": 0,
    "seed": 0,
    "stop": ["string"],
    "max_history_tokens": 0,
    "system_prompt_cache_contract": "legacy",
    "prompt_cache_key": "string",
    "context_management": [
        {
            "type": "compaction",
            "compact_threshold": 0,
            "keep_tokens": 0,
            "model": "string"
        }
    ],
    "thread_id": "string",
    "parent_message_id": "string",
    "store": True,
    "persona_id": "string",
    "metadata": {
        "property1": "string",
        "property2": "string"
    },
    "skill_instructions": "string",
    "skill_selection": "off",
    "skills": ["summarize-thread"],
    "skill_files": False,
    "memory": {
        "read": True,
        "write": True
    },
    "tool_callback": {
        "base_url": "https://api.blinklearn.envision.io/agent-tools",
        "auth_token": "string",
        "timeout_ms": 8000
    },
    "extra_context": {},
    "skill_id": "string",
    "knowledge_pack_ids": ["string"],
    "brain_id": "5ff5069c-3661-4a30-92df-9e098e7ad88f",
    "brain_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
    "mind_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
    "graph_ids": ["string"]
}
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <token>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

A chat completion. JSON when `stream` is false; an SSE stream of chunks when it is true.

#### Example

```json
{
  "id": "string",
  "object": "chat.completion",
  "created": 0,
  "model": "string",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "string",
        "tool_calls": [
          {}
        ]
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {},
  "metadata": {
    "property1": "string",
    "property2": "string"
  },
  "context_management": [
    {
      "type": "compaction",
      "status": "completed"
    }
  ],
  "message_id": "string"
}
```

- `id` (`chat_completions.response.200.id`; string, required)
- `created` (`chat_completions.response.200.created`; integer, required)
- `model` (`chat_completions.response.200.model`; string, required)
- `choices` (`chat_completions.response.200.choices`; array<object>, required)
  - `message` (`chat_completions.response.200.choices.message`; object, required)
    - `role` (`chat_completions.response.200.choices.message.role`; string, optional)
      - default `"assistant"`
    - `content` (`chat_completions.response.200.choices.message.content`; any of, optional)
      - any of: `string`, `null`
    - `tool_calls` (`chat_completions.response.200.choices.message.tool_calls`; any of, optional)
      - any of: `array<object>`, `null`
  - `index` (`chat_completions.response.200.choices.index`; integer, optional)
    - default `0`
  - `finish_reason` (`chat_completions.response.200.choices.finish_reason`; any of, optional)
    - default `"stop"`
    - any of: `string`, `null`
- `object` (`chat_completions.response.200.object`; string, optional)
  - default `"chat.completion"`
- `usage` (`chat_completions.response.200.usage`; object, optional)
- `metadata` (`chat_completions.response.200.metadata`; any of, optional)
  - any of: `map<string>`, `null`
- `context_management` (`chat_completions.response.200.context_management`; any of, optional)
  - any of: `array<unknown>`, `null`
- `message_id` (`chat_completions.response.200.message_id`; any of, optional) — ID of the last message stored on the thread by this turn. Send it as `parent_message_id` on the next request. Streaming responses carry it as a top-level `message_id` on the chunk with a non-error `finish_reason`. Only set for requests with a `thread_id`.
  - any of: `string`, `null`

### 422

Validation Error

#### Example

```json
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}
```

- `detail` (`chat_completions.response.422.detail`; array<object>, optional)
  - `loc` (`chat_completions.response.422.detail.loc`; array<any of>, required)
    - any of: `string`, `integer`
  - `msg` (`chat_completions.response.422.detail.msg`; string, required)
  - `type` (`chat_completions.response.422.detail.type`; string, required)
  - `input` (`chat_completions.response.422.detail.input`; unknown, optional)
  - `ctx` (`chat_completions.response.422.detail.ctx`; object, optional)


Source: https://truememory-docs.mvstg.com/api/chat/completions/index.md
