Prompt to video

Turn a topic into a rendered video in six calls. Every step is a plain JSON POST — no streaming, no
SDK. This replaces the retired /gpt/* flow.

📘

Before you start

These endpoints need LLM access on your account. Without it they return 409 with a message
explaining why. Chapter and script generation are also rate limited to 5 requests per minute and
60 per hour per account.

1. Create an outline

An outline is a stored resource. Create it from a topic:

curl --request POST \
     --url https://apis.elai.io/api/v1/outline \
     --header 'Authorization: Bearer API_TOKEN' \
     --header 'Content-Type: application/json' \
     --data '{"prompt": "A short introduction to caring for cats"}'

prompt is trimmed and must be 8–400 characters. To build an outline from a video you already
have, send {"videoId": "..."} instead — send one or the other, never both.

This call counts against your account's video creation limit.

2. Generate chapters

curl --request POST \
     --url https://apis.elai.io/api/v1/outline/OUTLINE_ID/generate-chapters \
     --header 'Authorization: Bearer API_TOKEN' \
     --header 'Content-Type: application/json' \
     --data '{"prompt": "A short introduction to caring for cats"}'

Returns the outline with drafts[], each carrying a chapter of {title, points[]}.

3. Review and edit (optional)

This is the step the old API had no equivalent for — you can change the structure before any video
exists:

curl --request PATCH \
     --url https://apis.elai.io/api/v1/outline/OUTLINE_ID \
     --header 'Authorization: Bearer API_TOKEN' \
     --header 'Content-Type: application/json' \
     --data '{"chapters": [{"title": "Feeding", "points": ["Wet vs dry", "Portion size"]}]}'

🚧

Send chapters or drafts, not both

They both write to outline.drafts, so sending both is rejected. The request must also change at
least one of status, chapters, drafts or quizSettings. Unknown fields are rejected with 400.

4. Expand chapters into a script

curl --request POST \
     --url https://apis.elai.io/api/v1/outline/OUTLINE_ID/generate-script \
     --header 'Authorization: Bearer API_TOKEN'

No request body. Every chapter-bearing draft gets a voice-over written into drafts[].speech.

❗️

This is destructive

Re-running replaces drafts[].speech. Chapter ids are preserved. If the outline has no chapters
yet, you get 400 — generate or save chapters first.

5. Build the video

curl --request POST \
     --url https://apis.elai.io/api/v1/outline/OUTLINE_ID/video \
     --header 'Authorization: Bearer API_TOKEN' \
     --header 'Content-Type: application/json' \
     --data '{"templateId": "TEMPLATE_ID"}'

All fields optional — omit them and you get the default template, no brand kit, and the root folder.
mode selects the slide shape:

modeResult
video (default)Concrete slides, ready to render
storyStory-mode slides with empty header / sub-header / list / image placeholders to fill in the story editor first

This call also counts against your video creation limit.

6. Render

curl --request POST \
     --url https://apis.elai.io/api/v1/videos/render/VIDEO_ID \
     --header 'Authorization: Bearer API_TOKEN'

❗️

Render accepts work, it does not complete it

This returns {"accepted": true} immediately, before validation runs. Success and failure both
arrive later: subscribe to the video_ready and video_error webhooks,
or poll GET /videos/{videoId} until status is ready.

Errors you should handle

CodeMeaning
400Invalid body — prompt length, both chapters and drafts, unknown field, or no chapters to script
404Outline does not exist in your account
409LLM access unavailable, or the model could not ground the chapters in the source
429Rate limit (5/min, 60/hour) or your video creation limit. Read the X-RateLimit-* response headers