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

# Start Slideshow Generation

> Start async slideshow generation from your own slide copy, optionally styled on a Viral Library post.

Starts generating a slideshow in the background and returns its `slideshow_id` right away
with `202 Accepted`. Generation typically takes a few minutes.

Poll [Get Slideshow](/api-reference/get-slideshow) with the returned id until
`generation_status` is `complete` or `failed`. A complete slideshow can then be edited,
rendered, and posted like any other.

You write the words on every slide; Genviral plans the deck, sources or generates the images,
and lays out your copy unchanged.

## Image sources

* `auto` (the default) finds a matching image for each slide from its copy and
  `image_subject`, searching Genviral's curated image library first and Pinterest second.
* `pack` uses images from one of your [image packs](/api-reference/slideshow-packs).
* `ai_from_reference` is an opt-in premium mode that generates every slide image, using the
  slide images of one [Viral Library](/api-reference/get-viral-library-post) post as a style
  reference. Slide 1 is styled on the post's slide 1, slide 2 on its slide 2, and so on,
  cycling when your deck is longer. The reference guides look and composition only; its
  images and copy are never reused. Reading the reference counts against your Viral Library
  `get` rate limit.

To recreate a Viral Library post with Genviral-written copy and searched images, use
[Generate Slideshow](/api-reference/generate-slideshow) with `reference` instead.

## Credits

Credits are charged when generation starts, and `credits_charged` reports the charge. Each
generated image (`ai_from_reference`) is charged at the slideshow image rate; `auto` and
`pack` slides are not charged per image. If generation fails, credits for slides that were
not produced are refunded.

## Idempotency

`Idempotency-Key` is required and is scoped to the API key (or MCP grant) that sends it.

* Retrying with the same key and the same body returns the original `202` response, including
  its original `credits_charged`, and never starts or charges a second generation. The replayed
  `generation_status` is the status at start time; poll `GET /slideshows/{slideshowId}` for the
  current one.
* Reusing a key with a different body returns `409 idempotency_key_reused`.
* A request that is refused (for example `402` or `422`) does not consume its key, so you can fix
  the problem and retry with the same key.
* To try again after a generation finished with `generation_status: "failed"`, send a new key.

## Body Parameters

<ParamField body="slides" type="object[]" required>
  1 to 10 slides, in order.

  <Expandable title="Slide Object">
    <ParamField body="overlay_text" type="string" required>
      The exact on-screen words for this slide (1 to 500 characters). Rendered as written.
    </ParamField>

    <ParamField body="image_subject" type="string">
      What the slide's photo must show, as a short noun phrase such as `golden retriever puppy`
      (up to 80 characters). Leave it out to let the slide's copy guide the image.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="image_source" type="string" default="auto">
  `auto` (default), `pack`, or `ai_from_reference` (opt-in, charged per generated image).
</ParamField>

<ParamField body="reference" type="object">
  Required when `image_source` is `ai_from_reference`, and only accepted then.

  <Expandable title="Reference Object">
    <ParamField body="viral_post_id" type="string" required>
      A post `id` from [Search Viral Library](/api-reference/search-viral-library).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="pack_id" type="string">
  Image pack UUID. Required when `image_source` is `pack`, and only accepted then.
</ParamField>

<ParamField body="product_id" type="string">
  Optional product UUID the slideshow is for.
</ParamField>

<ParamField body="aspect_ratio" type="string" default="9:16">
  `9:16`, `3:4`, `1:1`, or `4:5`.
</ParamField>

<ParamField body="language" type="string">
  Optional language of your copy, such as `en` or `de`.
</ParamField>

<ParamField body="title" type="string">
  Optional display title for the slideshow (up to 200 characters).
</ParamField>

## Response

<ResponseField name="slideshow_id" type="string">
  The slideshow being generated. Poll it with Get Slideshow.
</ResponseField>

<ResponseField name="generation_status" type="string">
  `generating` or, when replaying a finished request, `complete`.
</ResponseField>

<ResponseField name="credits_charged" type="number">
  Credits charged for this generation.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://www.genviral.io/api/partner/v1/slideshows/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Idempotency-Key: 6c1f1f7e-2d0e-4f55-9a43-0d8a3b4f2a10' \
    --data '{
      "image_source": "ai_from_reference",
      "reference": { "viral_post_id": "7451234567890123456" },
      "slides": [
        { "overlay_text": "nobody warns you how quiet dinner gets when you cook for one" },
        { "overlay_text": "so I started making one-pan meals", "image_subject": "sheet pan dinner" },
        { "overlay_text": "now Sunday prep takes 40 minutes" }
      ],
      "aspect_ratio": "9:16"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "ok": true,
    "code": 202,
    "message": "Slideshow generation started",
    "data": {
      "slideshow_id": "2ab58bb0-0c39-45c0-a4d5-b6852f9d7fc0",
      "generation_status": "generating",
      "credits_charged": 3
    }
  }
  ```
</ResponseExample>

## Polling

```bash theme={null}
curl --request GET \
  --url https://www.genviral.io/api/partner/v1/slideshows/2ab58bb0-0c39-45c0-a4d5-b6852f9d7fc0 \
  --header 'Authorization: Bearer <token>'
```

Check `data.generation_status` every 10 to 15 seconds. When it is `failed`,
`data.generation_failure` holds a stable `code` and a short message.

## Error Responses

* `400 invalid_json` - request body is not valid JSON
* `400 invalid_request` - `Idempotency-Key` header is missing or longer than 255 characters
* `401` - authentication failed (missing/invalid/revoked token)
* `402 insufficient_credits` - not enough credits for this generation
* `403 product_not_accessible` - the product is not accessible to this key
* `404 viral_reference_not_found` - the Viral Library post does not exist
* `409 idempotency_key_reused` - this `Idempotency-Key` was already used with a different body
* `409 request_in_progress` - an identical request with this key is still being processed; retry shortly
* `422 invalid_payload` - body failed validation (see `issues`)
* `422 viral_reference_has_no_images` - the Viral Library post has no slide images to reference
* `422 pack_not_usable` - the pack is not accessible or has no images
* `429 rate_limited` - Viral Library `get` limit reached; wait `retry_after_seconds`
* `502 generation_enqueue_failed` - generation could not be started; retry with the same key
