---
title: "Re-render a carousel from its plan"
method: POST
path: "/v1/carousel/render"
tags: ["Carousel"]
---

# Re-render a carousel from its plan

`POST /v1/carousel/render`

## Request

- Base URL: `https://apihub.co.il`
- URL: `https://apihub.co.il/v1/carousel/render`
- Auth: HTTP bearer

Renders slides again from a plan (`output.plan` of POST /v1/carousel) after you changed it: a word, a headline, a colour, the font, or one slide's `image_url` (your own picture; remove the field for a brand-colour card). No model call, no picture search or generation — only the render is charged. `only: [3]` renders just slide 3; it keeps its place in the carousel (the marker still says 3/7 and the layout matches the other slides). The shape is the plan's own `aspect` (a plan without one — made before the square — is 4:5); send `aspect` to render the whole carousel in the other shape (not together with `only`: a carousel has one shape; a picture is cropped to the new shape around its middle, or around `focus_x` / `focus_y` of its slide). The limits of the shape apply: 1:1 — headline ≤ 6 words and 44 characters, body ≤ 18 words and 120 characters; 4:5 — headline ≤ 8 words, body ≤ 25 words; at most 5 hashtags. A picture that is not already on our storage is downloaded first (public addresses only; JPEG, PNG or WebP). `swipe_cue: false` leaves out the swipe cue next to the marker — slides shown inside a video, where nobody swipes. Asynchronous like the carousel itself: poll GET /v1/executions/{id}.

**Billing:** The render only: one image unit per slide rendered · **Rate limit:** 20/min · **Asynchronous**

## Headers

- `Idempotency-Key` string
- `X-Tag` string
- `x-wait-ms` integer

## Request body

- object
  - `only` integer[]: Render only these slides (1-based), e.g. [3]; default: all
  - `plan` object, required: The plan of an earlier carousel (`output.plan`), with your edits: a word, a headline, a slide's `image_url`
    - `look` 'photo' | 'card' | 'split', required
    - `brand` object, required
      - `font` 'Heebo' | 'Rubik' | 'Assistant' | 'Frank Ruhl Libre' | 'Secular One'
      - `accent` string, required
      - `handle` string
      - `primary` string, required
      - `logo_url` string, uri
    - `aspect` '1:1' | '4:5': The slides' shape: 1:1 (1080×1080) or 4:5 (1080×1350). A plan without it is 4:5 — every plan made before the square existed.
    - `slides` object[], required
      - `alt` string: Alt text of the finished slide
      - `body` string
      - `role` 'hook' | 'point' | 'step' | 'myth' | 'fact' | 'before' | 'after' | 'story' | 'proof' | 'recap' | 'cta', required
      - `image` object
        - `url` string, nullable
        - `model` string, nullable
        - `author` string, nullable
        - `source` 'stock' | 'ai' | 'own' | 'none', required
        - `licence` string, nullable
        - `page_url` string, nullable
        - `provider` string, nullable
        - `licence_url` string, nullable
      - `button` string: The call-to-action button (last slide)
      - `kicker` string: A small label above the headline (a pill)
      - `number` integer: The item's number (a tip, a step)
      - `focus_x` number: Which part of a picture wider than its window stays: 0 its left edge, 0.5 the middle (default), 1 its right edge
      - `focus_y` number: Which part of a picture taller than its window stays: 0 its top, 0.5 the middle, 1 its bottom. Default: the middle (in the square photo look the picture's middle is brought into the clear part above the text). Set it when the crop cuts the subject.
      - `headline` string, required
      - `image_url` string, uri: The picture this slide is rendered with. Change it to swap the picture; remove it for a brand-colour card.
      - `stock_query` string: English stock search for this slide's picture
      - `stock_short` string
      - `wants_image` boolean: Whether this slide carries its own picture
      - `image_prompt` string: English prompt for a generated picture (no text in it)
    - `caption` string
    - `palette` string
    - `version` 1
    - `hashtags` string[]
    - `language` 'he' | 'en' | 'uk' | 'ru', required
    - `archetype` 'tips' | 'myths' | 'steps' | 'before-after' | 'story' | 'product', required
    - `image_style` string
  - `aspect` '1:1' | '4:5': Render the plan in this shape (1:1 or 4:5) instead of its own — the whole carousel, so leave `only` out. Default: the plan's `aspect` (a plan without one is 4:5). The text limits of the shape apply.
  - `swipe_cue` boolean: The swipe cue next to the slide marker ("Swipe", "החליקו"); false = the marker alone — slides shown inside a video, where nobody swipes

## Response `200`

Completed (or 202 while processing)

- object
  - `id` string: Execution id — stable across internal retries; use it with GET /v1/executions/{id}
  - `status` 'pending' | 'processing' | 'completed' | 'partial' | 'failed' | 'cancelled' | 'timeout'
  - `operation` string
  - `tag` string, nullable: Your X-Tag, if sent
  - `created_at` string, date-time
  - `completed_at` string, date-time, nullable
  - `output` object: Operation result (see each operation). While a Studio render is processing: `stage` (queued · transcribing · downloading · preparing · cleaning_voice · mixing_audio · rendering · finishing), `phase` (the engine's: download · prepare · voice · audio · encode · qa · upload, or null), `progress` (a percent, 0–100) and `progress_fraction` (0–1), `eta_seconds` (seconds left, never below 0) and `estimate_seconds`
  - `error` string, nullable
  - `usage` object
    - `credits_charged` number, nullable
    - `credits_reserved` number
    - `estimated_credits` number
    - `cost_source` 'provider_reported' | 'calculated' | 'estimated' | 'null', nullable
    - `provider_usage` object, nullable: Normalised consumption, e.g. { VIDEO_SECOND: 22.4 }
  - `balance` object
    - `available` number
    - `reserved` number

## Other responses

- `202`: Processing — poll GET /v1/executions/{id}
- `400`: Invalid input
- `402`: Insufficient credits / project budget
- `404`: Resource not found (or not yours)
- `429`: Rate limited
- `503`: Service temporarily paused

---

[API](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai.md) · [All operations](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/llms.txt) · [OpenAPI document](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/revisions/a8caa42835ce?raw)
