Promoat.Partner API

Videos

Scene videos

Your character acts the script out across several clips — walking, showing, doing — instead of one static talking head. Same face throughout, delivered as one continuous vertical video, with a voice or silent.

What you get

With mode: "scenes" (alias moving_scene) your character acts across several clips, merged into one 9:16 video. Three ways to run it:

ModeHowUse it for
video_mode: "reference"Default. A realistic photo of your character (Image 1) plus up to 3 scene photos of your real place, product or prop.Your actual shopfront, your actual product, the same face every clip.
video_mode: "text"Narration only — no photos or frames are used.Cheapest; atmosphere and b-roll style stories.
voice_mode: "none"A silent 5–60 s video; set target_seconds.You add your own music or voice later.

For a straight to-camera update, talking head is simpler.

The request

POST/api/partner/v1/videos

Same endpoint and shared fields as talking head (character_id, voice_id + script or audio_url — recordings are now allowed on scenes — resolution, language, voice_settings, expected_credits, client_request_id). Scene-specific fields:

FieldTypeDescription
mode"scenes" requiredOr "moving_scene".
video_ideastring ≤2000The video's intent ("a barista giving a behind-the-scenes tour of the roastery").
scene_photosarray[{ "url": "https://…", "role"?: "setting" | "product" | "prop", "caption"?: "≤200 chars" }]. Merged with legacy scene_elements, de-duplicated; the first 3 are kept (more → SCENE_PHOTOS_TRUNCATED warning; at most 12 raw items). Setting a role skips auto-labelling.
scene_promptstring ≤400Extra direction for the look of the scenes.
scene_linesstring[] 1–15One line per clip (each ≤600), usually from POST /videos/scene-plan.
video_mode"reference" | "text"Default reference. Text mode ignores scene photos and frames (with a warning).
voice_mode"voice" | "none"Default voice. none makes a silent video.
target_secondsnumber 5–60Required with voice_mode: "none". The brief is your script, else scene_lines, else video_idea.
first_frame_asset_iduuidA realistic photo made with POST /images/first-frame and kind: "moving_scene". A talking-head frame here → 400 FIRST_FRAME_KIND_MISMATCH. Supplying one drops the first_frame line.
languagestringOptional: the spoken language (name or code).
topic / audiencestringsAccepted but no effect (FIELD_IGNORED); put the brief in video_idea / scene_prompt.

Scene photos and roles

Scene photos put your real place, product or prop into the video (reference mode only). Each one can say what it is; leave role out and we label it for you.

roleUse it forExample caption
settingWhere the video happens — your shop, clinic, kitchen."our shopfront on Main Street"
productWhat you sell — shown and handled as the hero object."the 250 g retail bag"
propSomething the character uses or holds."the espresso tamper"
  • Up to 3 photos are used. More → the first 3, with a SCENE_PHOTOS_TRUNCATED warning.
  • A photo we can't fetch safely while the job runs is dropped, not fatal: the job continues, carries a SCENE_PHOTO_DROPPED warning (field scene_photos[i]), and is re-priced with the photos actually used — never above the reserve.
  • Public https URLs of still images (JPEG, PNG, WebP, GIF or HEIC). Text mode ignores them, with a warning.
Ignored here

Captions (use_dynamic_captions) are a talking-head add-on and are ignored on scenes. fast, narration_mode and other legacy tuning fields are accepted and ignored with a FIELD_IGNORED warning.

Plan the clips first (free)

POST/api/partner/v1/videos/scene-plan

Instant and free. Splits a script into clip lines you can show, edit, and send back as scene_lines.

FieldTypeDescription
video_typestring requiredtalking_head | scenes | moving_scene | normal_video.
scriptstring ≤4000 requiredThe text to split.
audio_duration_secondsnumber ≤60.5Length of your recording, if any. Required (5–60) with voice_mode: "none".
voice_mode"voice" | "none"Default voice.
languagestringSpoken language.
POST /videos/scene-plan — free
curl -X POST https://platform.promoat.ai/api/partner/v1/videos/scene-plan \
  -H "Authorization: Bearer $PROMOAT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_type": "scenes",
    "script": "Ever wondered how we roast our beans? Come on, I will show you.",
    "language": "en"
  }'
Response
{
  "scenes": [
    { "index": 0, "line": "Ever wondered how we roast our beans?", "seconds": 3.1 },
    { "index": 1, "line": "Come on, I will show you.", "seconds": 2.2 }
  ],
  "max_words_per_scene": 33
}

Errors: 400 INVALID_BODY, INVALID_SCRIPT, INVALID_DURATION, INVALID_VOICE_MODE.

Limits

Checked up front

Voiced audio: 1 s to 59.5 s (AUDIO_TOO_SHORT / AUDIO_TOO_LONG); 1–5 s is billed as 5 s. Scripts ≤4,000 characters. Silent videos: target_seconds 5–60. A rejected request starts nothing and charges nothing.

What it costs

Per second of output, by resolution:

ResolutionReference modeText mode
480P5 / s2.5 / s
768P8 / s4 / s
1080P16 / s8 / s

Worked examples, 15 s at 768P:

LineReference, 2 scene photosText modeSilent (voice_mode none)
generation12060120
first_frame4—4
reference_allowance6——
transcription11—
Total13161124

With voice_id + script a tts line is added and the length is estimated with headroom; you pay the lower of the reserve and the measured price. Get the exact quote with POST /videos/estimate (same body, free).

Full example

Queue a scene video (reference mode)
curl -X POST https://platform.promoat.ai/api/partner/v1/videos \
  -H "Authorization: Bearer $PROMOAT_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: roastery-tour-v1" \
  -d '{
    "mode": "scenes",
    "character_id": "CHARACTER_ID",
    "audio_url": "https://your-cdn.com/audio/roastery-15s.mp3",
    "video_idea": "a barista giving a behind-the-scenes tour of a small coffee roastery",
    "video_mode": "reference",
    "scene_photos": [
      { "url": "https://your-cdn.com/shots/storefront.jpg", "role": "setting", "caption": "our shopfront" },
      { "url": "https://your-cdn.com/products/retail-bag.jpg", "role": "product", "caption": "the retail bag" }
    ],
    "scene_prompt": "warm morning light, handheld feel",
    "resolution": "768P",
    "language": "en",
    "expected_credits": 131
  }'

# → { "workflow_id": "partner_h3v_…", "status": "queued", "credits_reserved": 131,
#     "credits_quoted": 131, "job_type": "multi_scene_video", "resolution": "768P",
#     "price_table_version": "2026-09-30", "warnings": [], "duplicate": false }
A silent 15 s video
{
  "mode": "scenes",
  "character_id": "CHARACTER_ID",
  "voice_mode": "none",
  "target_seconds": 15,
  "video_idea": "a slow morning in the roastery, beans pouring, steam rising"
}

Scene jobs take longer than talking heads — budget about 25 minutes and show phase / progress from the status endpoint meanwhile. Fix a single clip afterwards with Video edits.

Try it

Try itPOST/api/partner/v1/videos/scene-planfree
Add your API key in the sidebar to enable this.
Try itPOST/api/partner/v1/videos/estimatefree
Add your API key in the sidebar to enable this.
Try itPOST/api/partner/v1/videoscharges the quoted amount (real video job)
Add your API key in the sidebar to enable this.
Try itGET/api/partner/v1/jobs/{workflow_id}/statusfree
Add your API key in the sidebar to enable this.