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

# GET /presentations/generate/:generationId/status

> Returns the current state of a generation job.

<RequestExample>
  ```shellscript cURL theme={null}
  curl "https://api.chroniclehq.com/api/v1/presentations/generate/gen_123/status" \
    -H "Authorization: Bearer $API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.chroniclehq.com/api/v1/presentations/generate/gen_123/status",
    {
      headers: {
        Authorization: `Bearer ${API_KEY}`,
      },
    },
  );

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

### Parameters

<ParamField path="generationId" type="string" required>
  The generation job ID
</ParamField>

### Response

<ResponseExample>
  ```json generating (standalone) theme={null}
  {
    "generation_id": "gen_123",
    "status": "generating",
    "phase": "storyline",
    "tokens_used": 1280
  }
  ```

  ```json generating theme={null}
  {
    "generation_id": "gen_123",
    "status": "generating",
    "progress": {
      "slides_total": 9,
      "slides_completed": 3,
      "current_step": "Creating slide 4 of 9"
    },
    "tokens_used": 12450
  }
  ```

  ```json awaiting input theme={null}
  {
    "generation_id": "gen_123",
    "status": "awaiting_input",
    "message": "What does your company do?"
  }
  ```

  ```json completed theme={null}
  {
    "generation_id": "gen_123",
    "status": "completed",
    "presentation": {
      "id": "pres_123",
      "title": "Agency pitch deck",
      "workspace_id": "ws_123",
      "sections": [],
      "is_public": false,
      "url": "https://app.chroniclehq.com/ws_123/document/pres_123",
      "created_at": "2026-04-30T00:00:00.000Z",
      "updated_at": "2026-04-30T00:00:00.000Z"
    },
    "tokens_used": 38200
  }
  ```

  ```json failed theme={null}
  {
    "generation_id": "gen_123",
    "status": "failed",
    "error": "Generation timed out"
  }
  ```
</ResponseExample>

#### Common fields

<ResponseField name="generation_id" type="string">
  Generation job ID
</ResponseField>

<ResponseField name="status" type="string">
  Current generation status: one of `generating`, `awaiting_input`, `completed`,
  `failed`.
</ResponseField>

#### When status = "generating"

<ResponseField name="progress" type="object">
  Optional progress object. Present once Chronicle has begun generating slides.

  <Expandable title="child attributes">
    <ResponseField name="slides_total" type="number">
      Total number of slides expected
    </ResponseField>

    <ResponseField name="slides_completed" type="number">
      Number of slides completed so far
    </ResponseField>

    <ResponseField name="current_step" type="string">
      Human-readable progress message
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="phase" type="string">
  Optional. Present only for Standalone generations (when `template_id` was
  omitted on the original request). One of `storyline` (Chronicle is planning
  the deck outline) or `slides` (Chronicle is generating the slides from the
  storyline). Use this to give users finer-grained progress feedback than the
  time-based stage progression.
</ResponseField>

<ResponseField name="tokens_used" type="number">
  Optional running token total for this generation. Present when non-zero.
</ResponseField>

#### When status = "awaiting\_input"

<ResponseField name="message" type="string">
  Clarifying question or follow-up prompt from Chronicle. Reply via [POST
  /presentations/generate/:generationId/message](/post-send-followup-message).
</ResponseField>

#### When status = "completed"

<ResponseField name="presentation" type="object">
  The materialized presentation. Same shape as [GET /presentations/:id](/get-presentations-id).

  <Expandable title="child attributes">
    <ResponseField name="id" type="string">
      Presentation ID
    </ResponseField>

    <ResponseField name="title" type="string">
      Presentation title
    </ResponseField>

    <ResponseField name="workspace_id" type="string">
      Workspace ID that owns the presentation
    </ResponseField>

    <ResponseField name="sections" type="array">
      Presentation slides
    </ResponseField>

    <ResponseField name="is_public" type="boolean">
      Whether the presentation is public
    </ResponseField>

    <ResponseField name="url" type="string">
      Canonical presentation URL
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO timestamp when the presentation was created
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      ISO timestamp when the presentation was last updated
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="tokens_used" type="number">
  Optional total tokens consumed by the generation. Present when non-zero.
</ResponseField>

#### When status = "failed"

<ResponseField name="error" type="string">
  Human-readable failure reason (for example `Generation timed out` or a
  propagated upstream error message).
</ResponseField>

***

## FAQs

<AccordionGroup>
  <Accordion title="How often should I poll for status?">
    Poll at a short interval, such as every few seconds.

    Avoid polling in a tight loop.
  </Accordion>

  <Accordion title="What statuses should my client handle?">
    Your client should handle these statuses:

    * `generating`
    * `completed`
    * `failed`
    * `awaiting_input`
  </Accordion>

  <Accordion title="What do I get when generation completes?">
    When generation completes, Chronicle returns the final presentation object.

    That response includes the information you need to open or continue working with the presentation.
  </Accordion>

  <Accordion title="What should I do if the status is `failed`?">
    Treat `failed` as a terminal state and surface the error clearly in your app or logs.

    Do not continue polling after generation has failed.
  </Accordion>

  <Accordion title="Can I show progress while generation is running?">
    Yes. The status response can include progress details while the presentation is being generated.

    Use those fields to give users better feedback than a generic loading state.
  </Accordion>

  <Accordion title="What does the `phase` field mean?">
    For Standalone generations (no `template_id`), Chronicle works in two phases: it first generates the storyline outline, then it generates the slides from that outline. The `phase` field tells you which one is currently active so your UI can show a more accurate progress indicator.

    Template-based generations don't emit a `phase` — they're single-phase from the API's perspective.
  </Accordion>
</AccordionGroup>

***

## Related posts

* [POST /presentations/generate](/post-presentations-generate)
* [POST /presentations/generate/:generationId/message](/post-send-followup-message)
* [API scope and rate limits](/api-scope-rate-limits)
