> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gc.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-turn Conversations

> Continue a chat across multiple completions by passing chat_id

A single [`POST /chat/completions`](/api-reference/create-chat-completion) 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:

```bash theme={null}
# Turn 1 — omit chat_id to start a new chat
curl -X POST https://app.gc.ai/api/external/v1/chat/completions \
  -H "Authorization: gcai_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Summarize the indemnification clause in plain English." }'
# → result.chat_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

# Turn 2 — pass chat_id to continue
curl -X POST https://app.gc.ai/api/external/v1/chat/completions \
  -H "Authorization: gcai_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
        "chat_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "message": "Now redline it to be more favorable to the buyer."
      }'
```

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](/api-reference/concepts/async-jobs). 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}`](/api-reference/get-async-job) until the turn is terminal first.

## Who can continue what

Continuing a chat is scoped exactly like [materialization](/api-reference/concepts/chat-visibility#who-can-materialize-what), and only [API-created chats](/api-reference/concepts/chat-visibility) can be continued:

| Key type                    | Can continue                                          |
| --------------------------- | ----------------------------------------------------- |
| **Personal** (`u:gcai_…`)   | Only chats it created.                                |
| **Organization** (`gcai_…`) | Only chats created by other organization-scoped keys. |

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](/api-reference/concepts/chat-visibility) until you explicitly [materialize](/api-reference/materialize-chat) it.

## Related

* [Create a Chat Completion](/api-reference/create-chat-completion): each turn; returns the `chat_id`.
* [Chat Visibility](/api-reference/concepts/chat-visibility): why API chats stay headless and how ownership scoping works.
* [Asynchronous Requests](/api-reference/concepts/async-jobs): the job envelope, waiting, and polling.
