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

# POST /presentations/generate

> Starts an asynchronous AI presentation generation job.

<RequestExample>
  ```shellscript cURL — template theme={null}
  curl "https://api.chroniclehq.com/api/v1/presentations/generate" \
    -X POST \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "template_id": "tpl_123",
      "prompt": "Create a sales pitch deck for Chronicle aimed at agencies",
      "attachments": [
        {
          "id": "att_123",
          "url": "https://chronicle-attachments.s3.us-east-1.amazonaws.com/...",
          "file_name": "agency-research.pdf",
          "type": "application/pdf"
        }
      ]
    }'
  ```

  ```javascript JavaScript — template theme={null}
  const response = await fetch(
    "https://api.chroniclehq.com/api/v1/presentations/generate",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        template_id: "tpl_123",
        prompt: "Create a sales pitch deck for Chronicle aimed at agencies",
        attachments: [
          {
            id: "att_123",
            url: "https://chronicle-attachments.s3.us-east-1.amazonaws.com/...",
            file_name: "agency-research.pdf",
            type: "application/pdf",
          },
        ],
      }),
    },
  );

  const data = await response.json();
  console.log(data);
  ```

  ```shellscript cURL — standalone theme={null}
  curl "https://api.chroniclehq.com/api/v1/presentations/generate" \
    -X POST \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "Create a research deck on renewable-energy adoption in EU manufacturing",
      "non_interactive": true,
      "narrative_type": "Research",
      "section_count": 7,
      "language": "uk"
    }'
  ```

  ```javascript JavaScript — standalone theme={null}
  const response = await fetch(
    "https://api.chroniclehq.com/api/v1/presentations/generate",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        prompt:
          "Create a research deck on renewable-energy adoption in EU manufacturing",
        non_interactive: true,
        narrative_type: "Research",
        section_count: 7,
        language: "uk",
      }),
    },
  );

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

### Parameters

<ParamField body="prompt" type="string" required>
  Instruction for what to generate.
</ParamField>

<ParamField body="template_id" type="string">
  Template that seeds the generation. If omitted, Chronicle uses the Standalone
  flow — a storyline outline is generated first, then slides. This is the same
  path the product UI uses when a user creates a deck from a prompt without
  picking a template.
</ParamField>

<ParamField body="selected_section_ids" type="string[]">
  Optional subset of section IDs from the template to include. If omitted, all
  sections are included. Ignored on the Standalone path.
</ParamField>

<ParamField body="attachments" type="object[]">
  Optional list of files to ground the generation in. Each attachment is
  uploaded via [POST /uploads/create-target](/post-uploads-create-target) first;
  the returned `download_url` becomes this object's `url`. When provided, every
  field on each entry (`id`, `url`, `file_name`, `type`) is required.
</ParamField>

<ParamField body="non_interactive" type="boolean" default="false">
  When true, Chronicle never pauses to ask clarifying questions and
  auto-proceeds end-to-end. Required for automation integrations like n8n,
  Zapier, Make, or MCP — anything that can't pause mid-workflow to answer
  follow-up questions. When false (default), Chronicle may return
  `awaiting_input` and wait for a reply via [POST
  /presentations/generate/:generationId/message](/post-send-followup-message).
</ParamField>

<ParamField body="narrative_type" type="string">
  Storyline archetype. One of `Pitch`, `Showcase`, `Sales`, `Proposal`,
  `Research`, `Guide`, `Meeting`, `Portfolio`, `Auto`. Defaults to `Auto`
  (Chronicle picks). Only honored on the Standalone path (no `template_id`) with
  `non_interactive: true`.
</ParamField>

<ParamField body="rewrite_style" type="string">
  How aggressively Chronicle rewrites your input prompt and any attachment
  content. One of `Strong`, `Subtle`, `Preserve`. Defaults to `Subtle`. Only
  honored on the Standalone path with `non_interactive: true`.
</ParamField>

<ParamField body="section_count" type="number | string">
  Target number of sections in the storyline. Pass a positive integer (for
  example `5`) or the string `"auto"` to let Chronicle decide. Defaults to
  `"auto"`. Only honored on the Standalone path with `non_interactive: true`.
</ParamField>

<ParamField body="language" type="string">
  Output language. One of `us`, `uk`, `es`, `fr`, `de`, `it`, `pt`, `cn`, `in`,
  `ja`, `ko`, `ar`, `hi`, `bn`. Defaults to `us` (American English). Only
  honored on the Standalone path with `non_interactive: true`.
</ParamField>

### Response

A successful request returns `202 Accepted`. The workspace is inferred from your API key.

<ResponseExample>
  ```json Response theme={null}
  {
    "generation_id": "gen_123",
    "status": "generating",
    "poll_url": "/api/v1/presentations/generate/gen_123/status"
  }
  ```
</ResponseExample>

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

<ResponseField name="status" type="string">
  Current generation status
</ResponseField>

<ResponseField name="poll_url" type="string">
  Relative URL for checking generation status
</ResponseField>

***

## FAQs

<AccordionGroup>
  <Accordion title="Is generation synchronous?">
    No. Generation is asynchronous.
    The endpoint starts a generation job and returns a `generation_id`. Use that ID to check status.
  </Accordion>

  <Accordion title="What’s the difference between create and generate?">
    Use `POST /api/v1/presentations` to create from a template.

    Use `POST /api/v1/presentations/generate` to generate a presentation from a prompt.
  </Accordion>

  <Accordion title="Can generation ask follow-up questions?">
    Yes — by default. Chronicle can pause generation and return `awaiting_input` with a clarifying question.

    Set `non_interactive: true` on the request to skip this entirely. Chronicle will pick reasonable defaults and proceed silently. Required for automation tools that can't pause mid-workflow.
  </Accordion>

  <Accordion title="Do I need a template?">
    No. When `template_id` is omitted, Chronicle uses the Standalone flow — it generates a storyline outline first, then slides. This is the same path the product UI uses when you create a deck from a prompt without picking a template.

    Pass `template_id` when you want Chronicle to stamp out a deck that matches a specific template's structure.
  </Accordion>

  <Accordion title="When are the structured storyline params honored?">
    Only when `non_interactive: true` AND `template_id` is omitted (the Standalone path).

    Outside that combination, Chronicle ignores `narrative_type`, `rewrite_style`, `section_count`, and `language` — the template defines structure in template-mode, and the interactive flow lets users clarify their preferences in chat.
  </Accordion>

  <Accordion title="Can generation fail before it starts?">
    Yes. Chronicle can reject a generation request before processing begins, including when usage limits are exceeded.

    Handle these responses separately from authentication errors.
  </Accordion>

  <Accordion title="Can I attach files to ground generation?">
    Yes. Upload each file via [POST /uploads/create-target](/post-uploads-create-target) first, then pass the captured `download_url` (with `id`, `file_name`, and `type`) in the `attachments` array.
  </Accordion>
</AccordionGroup>

***

## Related posts

* [POST /uploads/create-target](/post-uploads-create-target)
* [GET /presentations/generate/:generationId/status](/get-generation-status)
* [POST /presentations/generate/:generationId/message](/post-send-followup-message)
* [API scope and rate limits](/api-scope-rate-limits)
