Skip to main content
POST

Overview

Prompt to Video works like Script to Video, except that you send a prompt instead of a script. The model writes a script for the target duration, a voice reads it and each scene gets a visual from the chosen mediaType: Every media type also takes aspectRatio, language, musicId, audio, content.brandingLogo, webhook and metadata; all but motion-graphics take caption and addStickers. The field list on this page says which media types read each field. Talking characters. With mediaType: "ai-videos", one of the talking-fruit, talking-objects or talking-organs presets and presetSettings.characterMode: "speaking", the characters say the lines themselves with the video model’s own audio. There is no narrator, captions or stickers, so audio, caption and addStickers do not apply (voiceId is still required). speaking with any other media type or preset answers 400. The request returns a projectId right away. The video is generated and rendered in the background.

More request bodies



What happens next

  1. Keep the projectId.
  2. Either poll GET /v1/project/{projectId} until video.status is COMPLETED (or the project status is failed), or pass a webhook and wait for the call.
  3. Download the file from video.url (or data.url in the webhook).
The webhook receives:
A project that fails before it has a video sends "status": "FAILED" with videoId: null. See Webhooks for every payload.

Credits and your own keys

Teams on Hooked’s keys (managed): the project is priced from the target duration, the media type, the quality or model and the character mode, and the credits are taken up front. With mediaType: "media" your library files are used as they are and cost nothing on top of the narration, however many you send (the same as a gameplay background). If the balance is short, the request answers 402 INSUFFICIENT_CREDITS with creditsNeeded and creditsAvailable and nothing is created. If the project fails later, the credits are refunded automatically. Teams on their own keys (BYOK): no credits are charged. The team needs these keys in Settings → AI keys:
  • OpenRouter: always (script, images, video clips, captions).
  • ElevenLabs: for the voiceover. Not needed in speaking mode (ai-videos with a talking preset), where the video model speaks.
  • Gemini: when presetSettings.aiModel is gemini_omni_flash.
A missing key answers 402 missing_credentials with the list in missingProviders, before anything is created.

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.

Writing prompts

Say what the video is about, who it is for and the tone. “Three productivity habits for remote workers, friendly tone, aimed at busy professionals” works; “a video about stuff” does not. Set language for the video’s language, or write the prompt in it and leave language out.

Next Steps

Get Project

Follow the project until the video is ready

Webhooks

Payloads and delivery rules

List Voices

Pick a voice

Script to Video

Bring your own script

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]+$

Query Parameters

dryRun
boolean
default:false

true: only answer the price of this exact request, as { success: true, data: { dryRun: true, estimatedCredits } } with status 200. The request is validated like a real one (a 400 or 402 says the same), but nothing is created, queued or charged. estimatedCredits is exactly what the call without dryRun charges a managed team; a byok team is charged nothing. Do not send an Idempotency-Key with it.

Body

application/json
prompt
string
required

What the video is about, who it is for and the tone (1–4,000 characters). The script is written from it.

Required string length: 1 - 4000
voiceId
string
required

The narrator: a library voice from /v1/voice/list or one of your team's custom voices. An ID that is neither answers 400 (voiceId: Voice "<id>" not found.). Still required with characterMode: "speaking", where the characters speak with the video model's own voice and this voice is not used.

Required string length: 1 - 30
targetDuration
number
default:60

Length of the script to write, in seconds (a JSON number, 10–120). The project is priced from it.

Required range: 10 <= x <= 120
name
string

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

Maximum string length: 100
mediaType
enum<string>
default:ai-images

Where the visuals come from:

  • ai-images: one AI image per scene (presetSettings: preset, aiModel, characterIds, useCharacterReferenceImage).
  • ai-videos: one AI video clip per scene (presetSettings: preset, quality, aiModel, isContinuous, characterIds, characterMode, voiceProfile).
  • motion-graphics: an animated motion graphic that typesets its own copy (presetSettings: quality, motionStyleId, motionGuidelines; media optional as footage). No captions or stickers.
  • media: your own images and videos from the media library (media required). No presetSettings.
  • gameplay: a gameplay clip in the background (gameplaySettings). No presetSettings.
Available options:
ai-images,
ai-videos,
motion-graphics,
media,
gameplay
presetSettings
object

Visual settings for ai-images, ai-videos and motion-graphics; not used by media and gameplay. Each field says which media types read it.

gameplaySettings
object

mediaType: "gameplay" only: the background clip.

media
string[]

IDs of images or videos in your team's media library (max 50). Required for mediaType: "media" (send at least one); optional footage for motion-graphics; ignored for the other media types. An ID that is not in your library answers 400 (media: Media "<id>" not found). A media that is not COMPLETED yet (an import or upload in progress) answers 400 media: Media "<id>" is not ready (status PROCESSING).

Maximum array length: 50

Media ID from your library

aspectRatio
enum<string>
default:ratio_9_16

Vertical, horizontal or square.

Available options:
ratio_9_16,
ratio_16_9,
ratio_1_1
language
string

Two-letter ISO 639-1 code, e.g. en, es: the script is written and narrated in it. Detected from the prompt when omitted.

musicId
string

Background music: a track from /v1/music/list or your team's own uploaded music. An ID that is neither answers 400 (musicId: Music "<id>" not found.).

Maximum string length: 30
caption
object

Burned-in captions of the narration. Not used with motion-graphics (it typesets its own copy) or a speaking cast.

audio
object

Narrator voice settings (ElevenLabs). Any field you leave out keeps its default. Not used by a speaking cast.

addStickers
boolean
default:false

Add emoji/GIF stickers anchored to the captions. Not used with motion-graphics or a speaking cast.

content
object

Branding.

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). Stored on the project and sent back in the webhook payload. The key automationId is reserved for dashboard automations and is removed.

Response

Project created. Follow it with GET /v1/project/{projectId} or wait for the webhook.

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