Skip to main content
POST

Overview

Scenes lets you put a video together one scene at a time. Each scene has a type: Avatar and picture-in-picture scenes are spoken by the avatar itself: they take no voiceId. A narrated scene uses its own voiceSettings, or the top-level audio settings when it has none. Scenes play in the order you list them. A video scene plays a video at its own length and an image for 5 seconds; a narrated one lasts as long as its narration. Every mediaId, startFrameMediaId and endFrameMediaId must be a file of your own team’s library; any other ID is refused with 400 scenes.<i>.<field>: Media "<id>" not found. Avatar and voice IDs are not checked when the project is created: an unknown one makes that scene fail while the project processes.
When the project reaches completed, its render starts on its own: follow it with Get Project or the webhook.


Errors

Send an Idempotency-Key header to retry safely: if a request times out or answers 5xx, sending it again with the same key and body returns the first answer instead of creating (and charging) the project twice.

Credits and your own keys

  • Teams on Hooked’s keys (managed): 13 credits per project, plus 100 credits per started 15 seconds of speech in each avatar and picture_in_picture scene and each narrated video scene, plus the video model’s per-second price for each start_end_frame scene (for frameDuration seconds, or for the narration’s length when the scene is narrated). Before the project is created your balance is checked against an estimate (speech at about 2.5 words per second); the credits are taken while the project processes. A scene that fails gives its credits back, and so does a project that fails.
  • Teams on their own keys (BYOK): no credits are charged. The team needs these keys in Settings → AI keys: OpenRouter always; ElevenLabs when a video or start_end_frame scene is narrated (has a script); Google AI (Gemini) when any scene is avatar or picture_in_picture; Bria when any scene is picture_in_picture. Without them the request answers 402 missing_credentials and nothing is created.

What happens next

The project is created with status: processing. When every scene is ready it becomes completed and its render starts on its own; you do not call Render. Either:
  • poll Get Project with the projectId until data.video.status is COMPLETED (or the project is failed), then download data.video.url; or
  • pass webhook and wait for the COMPLETED (or FAILED) call described in Webhooks.

List Avatars

Avatars for avatar and picture-in-picture scenes

List Voices

Voices for narrated video scenes

Webhooks

Payloads and delivery rules

Get Project

Status of the project

Authorizations

x-api-key
string
header
required

Headers

Idempotency-Key
string

Makes the request safe to retry. 1-255 printable ASCII characters, one per operation (your job id, or a UUID you store), reused on every retry. Within 24 hours the same key with the same body answers with the first response and the header Idempotent-Replayed: true, without running or charging again. Keys are scoped to your team and the endpoint. 5xx answers and refusals before anything ran (401, 402, 403, 409, 429) are not kept. See Idempotency.

Required string length: 1 - 255
Pattern: ^[\x20-\x7E]+$

Body

application/json
scenes
object[]
required

The scenes, 1-50, played in the order they are listed. Every media and frame ID must be a file of your team's library (400 scenes.<i>.<field>: Media "<id>" not found. otherwise). A media that is not COMPLETED yet answers 400 scenes.<i>.<field>: Media "<id>" is not ready (status PROCESSING).

Required array length: 1 - 50 elements
name
string

Project name (max 100 characters). Generated from the scripts when omitted.

Maximum string length: 100
aspectRatio
enum<string>
default:ratio_9_16
Available options:
ratio_9_16,
ratio_16_9,
ratio_1_1
language
string

Language of the scripts as a 2-letter ISO 639-1 code (en, es, ...), used to transcribe the speech for the captions. Detected from the scripts when omitted.

caption
object

Burned-in captions.

audio
object

Voice settings for every narrated video / start_end_frame scene that does not send its own voiceSettings. All three fields are required when you send it.

content
object

Branding.

musicId
string

Background music ID from /v1/music/list or your own music. An unknown ID answers 400.

Maximum string length: 30
webhook
string<uri>

HTTPS URL on a public host, called when the video is ready or the project fails (max 500 characters). Requests are signed: verify the Hooked-Signature header (HMAC-SHA256 of ".") with the signing secret from Settings → Webhooks; Hooked-Event and Hooked-Delivery headers name the event and the delivery. No redirects are followed; 10 s timeout; 3 immediate attempts. See the Webhooks guide for the payload.

Maximum string length: 500
metadata
object

Any JSON object of your own (max 5 KB). Sent back in the webhook payload. The key automationId is reserved for dashboard automations and is removed.

Response

Project created with status: processing. Poll GET /v1/project/{projectId} or wait for the webhook: when the project is completed its render starts on its own.

success
enum<boolean>
required
Available options:
true
data
object
required
message
string
required