Carousels
Give this prompt to your AI agent. The agent does the task for you.
Read https://thirds.ai/docs/api-reference/carousels and help me choose the right thirds.ai endpoint and write a request. Check the fields and credentials in this reference.
Render selected pages of one saved template version as images, poll each slide, retry failed slides, and download a ZIP of the files that succeeded.
See all API resources or read API keys and requests.
Endpoints
createCarousel
POST /v1/carousels
Create a carousel
Render selected pages of one saved template version as images, in the requested order. Creates one normal image job per page. The ledger reserves one credit per job, settles it on success, and releases it on failure. A successful PDF of the same pages still costs one credit through POST /v1/pdf.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
Idempotency-Key | header | Yes | {"type":"string","minLength":1,"maxLength":255,"pattern":"^[ -~]+$"} |
Request body: application/json, CarouselCreate.
| Status | Meaning | Body |
|---|---|---|
| 201 | The carousel was created, or an earlier request with the same idempotency key and body is replayed. | application/json: Carousel |
| 400 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 409 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 413 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 415 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 429 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 503 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
getCarousel
GET /v1/carousels/{id}
Get a carousel's status
Returns the carousel with each member's own state and, once any member has succeeded, a signed archive_url for the ZIP of every succeeded file.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
id | path | Yes | {"type":"string","pattern":"^carousel_[0-9a-f]{32}$"} |
| Status | Meaning | Body |
|---|---|---|
| 200 | The carousel's current status. | application/json: Carousel |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
retryCarousel
POST /v1/carousels/{id}/retry
Retry a carousel's failed members
Creates one new job for every member whose last attempt failed or that never reached a job. A queued, running, or already succeeded member is left untouched.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
id | path | Yes | {"type":"string","pattern":"^carousel_[0-9a-f]{32}$"} |
| Status | Meaning | Body |
|---|---|---|
| 200 | The carousel after retry, with a new job for each member that was retried. | application/json: CarouselRetry |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 429 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
getCarouselArchive
GET /v1/carousels/archive/{token}
Download a carousel's ZIP archive
Stream a ZIP of one carousel's succeeded members, in requested order with numbered filenames such as 01-cover.png, plus manifest.json recording that order and any failed pages. The link carries its own authority, so no other credential is read.
Authentication: no credential required.
| Parameter | Location | Required | Rule |
|---|---|---|---|
token | path | Yes | The signed archive link. {"type":"string"} |
| Status | Meaning | Body |
|---|---|---|
| 200 | The ZIP archive of succeeded members plus manifest.json. | application/zip: {"type":"string","format":"binary"} |
| 403 | The link is genuine but its time is over. | application/json: ErrorEnvelope |
| 404 | The link is not valid, or the carousel has no succeeded member to archive. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | An internal error occurred. | application/json: ErrorEnvelope |
Schemas
CarouselCreate
| Field | Required | Description and type |
|---|---|---|
template_id | Yes | TemplateId |
version | No | Omitted to use the template's latest version at creation time. {"type":"integer","minimum":1} |
data | No | Template data applied to every selected page. Omitted to use an empty object. {"type":"object"} |
format | Yes | {"type":"string","enum":["png","jpeg","webp"]} |
pages | Yes | 1 to 100 different canvas data-thirds-page ids in output order. {"type":"array","items":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z][A-Za-z0-9_-]{0,63}$"},"minItems":1,"maxItems":100} |
Schema rules: {"type":"object","additionalProperties":false}.
CarouselMember
| Field | Required | Description and type |
|---|---|---|
position | Yes | {"type":"integer","minimum":0} |
page_id | Yes | {"type":"string"} |
name | Yes | {"type":"string"} |
width | Yes | {"type":"integer","minimum":1} |
height | Yes | {"type":"integer","minimum":1} |
state | Yes | {"type":"string","enum":["queued","running","succeeded","failed"]} |
error | Yes | {"type":["object","null"],"properties":{"code":{"type":"string"}},"required":["code"],"additionalProperties":false} |
download_url | Yes | {"type":["string","null"]} |
Schema rules: {"type":"object","additionalProperties":false}.
Carousel
| Field | Required | Description and type |
|---|---|---|
id | Yes | {"type":"string","pattern":"^carousel_[0-9a-f]{32}$"} |
template_id | Yes | TemplateId |
version | Yes | {"type":"integer","minimum":1} |
format | Yes | {"type":"string","enum":["png","jpeg","webp"]} |
created_at | Yes | {"type":"string","format":"date-time"} |
state | Yes | {"type":"string","enum":["queued","running","complete","partial","failed"]} |
members | Yes | {"type":"array","items":{"$ref":"#/components/schemas/CarouselMember"}} — CarouselMember |
archive_url | Yes | A signed ZIP download link, present once any member has succeeded. {"type":["string","null"]} |
Schema rules: {"type":"object","additionalProperties":false}.
CarouselRetry
Schema rules: Carousel.
Shared errors, headers, and authentication schemes are in shared types and security.