Skip to main content
A single POST /chat/completions call is one turn. To hold a conversation — ask a follow-up, refine a draft, react to what the model said — you continue the same chat across turns by passing its chat_id.

How it works

Every completion returns a chat_id in its result envelope. Pass that value back as chat_id on your next request and the new message is appended to the same conversation:
The model sees the full prior conversation on turn 2 — the earlier messages, any tool calls it made, and the files you attached — so the follow-up can refer back to “it” without restating context.

State lives on the server

Conversation state is stored server-side and reconstructed for you on every turn. Send only the new message (plus any new file_ids) — never re-send prior turns. In particular, you do not echo back anything the API returned to you:
  • Files stay attached. A file you sent with file_ids on an earlier turn remains available; you don’t re-attach it.
  • Generated outputs are remembered. Documents, emails, and diagrams returned on result.documents / result.emails / result.diagrams are already persisted to the chat. The model can refer to and build on them without you sending them back. Those response fields are there for your convenience — to download or display — not state you must round-trip.
This keeps requests small and avoids the drift that comes from a client reassembling history by hand.

One turn at a time

Each turn runs as an async job. Only one turn may be in flight per chat: if you send a new message while a prior turn is still pending or running, the request is rejected with 409. Wait for the prior turn to reach a terminal state (succeeded / failed) before sending the next. This prevents two turns from racing on the same message history. If you long-poll (wait > 0) you’ll usually have the result before you send the next turn; with fire-and-forget (wait=0) poll GET /jobs/{id} until the turn is terminal first.

Who can continue what

Continuing a chat is scoped exactly like materialization, and only API-created chats can be continued: A chat_id that doesn’t exist (or that this key can’t reach) returns 404; a chat owned by a different scope returns 403; a chat that wasn’t created through the API returns 409. Continuing a chat does not materialize it — the conversation stays headless until you explicitly materialize it.