> ## 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.

# Create chat completion

> Ask GC AI a legal question or give it a task.

<Info>
  **Tool** `ask_gcai` · **Behavior** Open world
</Info>

Ask GC AI a legal question or give it a task. Optionally ground it in uploaded files (`file_ids`), playbooks (`playbook_ids`), or skills (`skill_ids`). Returns a job envelope, not a final answer: while `status` is `pending` or `running`, keep polling `ask_gcai_status` with the returned `job_id` until `status` is `succeeded` (then `result` holds the answer). Pass `chat_id` to continue a prior conversation, sending only the new message (conversation state is kept server-side).

## Input parameters

<ParamField body="message" type="string" required>
  The user's message or prompt
</ParamField>

<ParamField body="file_ids" type="string (uuid)[]">
  Optional uploaded file IDs to attach as context for this completion. Upload files first via `POST /files`.
</ParamField>

<ParamField body="playbook_ids" type="string (uuid)[]">
  Optional playbook IDs to ground the completion in (up to 20). The model uses each playbook's checks and guidance to structure its review of the attached files. Discover playbooks via `GET /playbooks`.

  Org-scoped keys can use org-visible and official playbooks.
</ParamField>

<ParamField body="playbook_id" type="string">
  Deprecated and no longer accepted. Use `playbook_ids` (an array) instead. Requests that include this field are rejected with a 400 so the playbook is never silently dropped.
</ParamField>

<ParamField body="skill_ids" type="string (uuid)[]">
  Optional skill IDs to run on the first turn. Each skill's instructions are injected as context for this completion. Discover skills via `GET /skills`.

  Only valid when starting a new chat; omit them when continuing with `chat_id`.
</ParamField>

<ParamField body="chat_id" type="string (uuid)">
  Optional chat ID to continue an existing conversation, from the `chat_id` of a prior completion. Omit to start a new chat.

  Conversation state is held server-side, so send only your new `message` (plus any new `file_ids`); do **not** re-send prior turns or previously returned documents/emails/diagrams. Only one turn may be in flight per chat at a time. See [Multi-turn Conversations](/api-reference/concepts/multi-turn).
</ParamField>

## Response

<ResponseField name="job_id" type="string">
  Job identifier. Pass it to the matching `*_status` tool to poll.
</ResponseField>

<ResponseField name="status" type="'pending' | 'running' | 'succeeded' | 'failed' | 'canceled'">
  `succeeded` means `result` is populated; `running`/`pending` means poll again; `failed`/`canceled` are terminal.
</ResponseField>

<ResponseField name="result" type="object | null">
  Typed result when `status` is `succeeded`; `null` until then.

  <Expandable title="properties">
    <ResponseField name="result" type="string">
      The AI-generated response text
    </ResponseField>

    <ResponseField name="chat_id" type="string (uuid)">
      The chat ID. API chats stay out of chat history until you materialize them. Pass this ID to `POST /chat/{id}/materialize` to surface the chat. See [Chat Visibility](/api-reference/concepts/chat-visibility).
    </ResponseField>

    <ResponseField name="documents" type="object[]">
      Documents produced during this completion: either edits of an attached file (the document editing tool) or newly generated files (the document or slide generation tools). Present only when at least one document was produced. Each entry exposes a new `file_id` and a signed download URL; edits also reference the preserved original via `original_file_id`.

      <Expandable title="properties">
        <ResponseField name="file_id" type="string (uuid)">
          The new uploaded file ID for the produced document. Use it with `POST /chat/completions` `file_ids` to apply further edits to this version. Download via `signed_url` for the finished file.
        </ResponseField>

        <ResponseField name="original_file_id" type="string (uuid)">
          The `file_id` the changes were applied to (edits only). The original file is preserved unchanged. Omitted for newly generated documents.
        </ResponseField>

        <ResponseField name="filename" type="string">
          Filename of the produced document (edits are prefixed with `edited_`).
        </ResponseField>

        <ResponseField name="original_filename" type="string">
          Filename of the source file the changes were applied to (edits only). Omitted for newly generated documents.
        </ResponseField>

        <ResponseField name="signed_url" type="string (uri)">
          Time-limited direct download URL (no login required). Valid for 7 days from job completion. Download promptly; the URL is not re-minted, so re-fetching the job after expiry returns the same expired URL. For a link you intend to store or email, use `download_url` instead.
        </ResponseField>

        <ResponseField name="download_url" type="string (uri)">
          Permanent, login-gated download link for the produced document. Unlike `signed_url` it never expires: it points at a GC AI web page that mints a fresh download for a signed-in user with access to the file, and redirects to GC AI login otherwise. Use this for links you store or email. The produced document inherits the source document's access, so it opens for whoever can already see the source: a document uploaded to the organization is org-visible, one in a project is visible to that project's members, and one in personal files stays private to the uploader. Recipients still need a GC AI login.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="emails" type="object[]">
      Email drafts produced during this completion by the email drafting tool. Present only when at least one email was drafted. Each entry is a structured draft (`to`, `subject`, `body`, …) ready to send via your own mail client or provider.

      <Expandable title="properties">
        <ResponseField name="to" type="string">
          Recipient email address(es), comma-separated. May be an empty string when the prompt named no recipient; fill it in before sending.
        </ResponseField>

        <ResponseField name="cc" type="string">
          CC recipient email address(es), comma-separated.
        </ResponseField>

        <ResponseField name="bcc" type="string">
          BCC recipient email address(es), comma-separated.
        </ResponseField>

        <ResponseField name="subject" type="string">
          Email subject line. Always present, inferred from context when the prompt did not specify one.
        </ResponseField>

        <ResponseField name="body" type="string">
          Email body in markdown.
        </ResponseField>

        <ResponseField name="plaintext_body" type="string">
          Email body with markdown stripped, for plain-text clients.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="diagrams" type="object[]">
      Diagrams produced during this completion by the diagram tool. Present only when at least one diagram was produced. Each entry exposes validated Mermaid source (`mermaid`) you can render with any Mermaid-compatible renderer.

      <Expandable title="properties">
        <ResponseField name="title" type="string">
          A short descriptive title for the diagram.
        </ResponseField>

        <ResponseField name="diagram_type" type="string">
          The semantic type of diagram, e.g. orgChart, dealStructure, workflow, timeline, sequence, entityRelationship, or general.
        </ResponseField>

        <ResponseField name="mermaid" type="string">
          The diagram source as validated Mermaid syntax. Render it with any Mermaid-compatible renderer.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="status_tool" type="string">
  The exact tool to call to poll this job. Call it yourself with `job_id`; do not ask the user to poll.
</ResponseField>

<ResponseField name="poll_after_seconds" type="number | null">
  While `status` is `pending`/`running`, wait this many seconds, then call `status_tool` with `job_id`. `null` once the job is terminal.
</ResponseField>

<ResponseField name="hint" type="string">
  Plain-language next step. Follow it before responding.
</ResponseField>
