One Click Videos · Developers
Create a video
POST /api/v1/videos — give the Ava director a creative brief and receive a job ID.
The smallest useful brief
Provide video_idea and a whole-number video_length_sec from 5 to 300. A URL by itself is not enough: describe what happens, the subjects, the message and the tone.
curl --fail-with-body https://app.jemsu.ai/api/v1/videos \
-H "Authorization: Bearer $JEMSU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_idea": "A small paper boat drifts across a sunlit pond. Gentle ripples, a low camera angle and a peaceful ending.",
"video_length_sec": 10,
"speech": "no",
"music": "no",
"aspectratio": "9:16"
}'
Creative field reference
| Field | Values and type | How to use it |
|---|---|---|
video_idea |
string free text |
Required. What happens, who or what we see, the message, the tone. The director plans the shots, segments, images and models from this — there are no per-segment prompts to write. Also accepts videoIdea. |
video_length_sec |
integer 5–300 |
Required. Whole seconds; the director splits the video into segments. Also accepts videolength / veovideolength. |
mode / url |
string url | no-url / https URL |
url mode reads the page at url (text, images, brand). Default: url when a url is present, else no-url. |
speech |
yes | no default from audio_source |
no = ambient sound only (audio_source becomes none). |
audio_source |
string native | voiceover | voice_clone | voice_design | none |
Who speaks. Default: voiceover when a voice_script is sent, else native (people on screen speak, lip sync). |
voice_gender / voice_style |
string female (default) | male / ≤ 80 chars (default "clear and engaging") |
Off-screen narrator only — the director picks the TTS voice from gender + style (e.g. "warm and friendly"). |
voice_script_mode |
string dictate | assist | planner |
dictate = your voice_script word for word; planner = the director writes the script from the idea (default without a script). assist without a script falls back to planner. |
voice_script |
string the words spoken |
Also accepts voicescript. Paced at 2.0 words/s (narrator, cloned or designed voice) or 2.5 words/s (native) — a script that outruns the length fails QA. |
voice_clone_sample_url |
string public https audio ≤ 10 MB |
Required for voice_clone; re-hosted into your library. Also accepts voiceCloneAudioUrl. |
voice_design_description |
string ≤ 240 chars |
Required for voice_design: gender, age, accent, tone, pace. Also accepts voicedesigndescription. |
music / music_notes |
yes | no / string default no |
Also accepts background, music_only (→ yes), none (→ no) and music_instructions. |
captions |
yes | no default no |
Burned-in captions. |
caption_position / caption_color / caption_language |
integer / hex / lang 0–100 (60) / FFA500 / = video language |
Also accepts caption_highlight_color and captions_language. |
aspectratio / resolution |
string 9:16 (default) | 16:9 / 720p (default) | 1080p |
Also accepts aspect_ratio. 4k is not available on the director (→ 1080p with a warning). |
video_language |
string 2-letter code |
Also accepts language / voiceover_language. Default: your account language. |
logo_url / logo_position / logo_width |
https / string / integer topLeft (default) | topRight | bottomLeft | bottomRight / 50–1000 (200) |
Overlay logo; foreign hosts are re-hosted. Also accepts customlogo. |
video_model |
string seedance (default) | omni | grok | wan |
Pinned for the whole video; credits are reserved at this model's rate. Also accepts videogenerationmodel (veo = omni). |
image_model |
string gpt-image-2.5 (default) | nano-banana-pro | nano-banana | grok-imagine |
Also accepts imagegenerationmodel. gpt-image-2.5 = GPT Image 2.5 (OpenAI). |
image_source / image_sources |
string / array url_images | upload | ai_generated — or a list such as ["url_images", "upload"] |
Where the pictures come from: the page's own images (url mode only), your reference_images (the director generates the rest), or every image AI generated. Several sources combine — the page's images plus your uploads; reference_images always add upload. Default: upload with reference_images, else url_images with a page, else ai_generated. |
reference_images |
array ≤ 12 https URLs or { url, kind, name, description } |
Products, places, people that must appear; foreign hosts are copied into your library (≤ 10 MB each). Also accepts userphoto2 (a person) and saved_image_urls. |
segments |
array ≤ 10 hints |
Optional per-segment hints: { idea, reference_images: [≤ 10 https], continuation }. The director renders exactly these segments in order; several images per segment become that segment's references (reference-to-video). The classic segments[] shape (textPrompt / imagePrompt / motionPrompt / referenceImageUrls) is accepted too. |
notes |
string ≤ 4,000 chars |
Anything the producer must know: brand rules, must-show and do-not-show items. |
title |
string ≤ 80 chars |
Optional name for the job (defaults to the style's title or the first words of the idea). |
Style selection
Pass preset_style or my_style with an ID returned by the corresponding API. Do not send both. A style may supply defaults, but every resolved brief still needs a video idea and valid duration. Some product/dealership styles require a matching URL.
Successful response
| Field | Meaning |
|---|---|
| ok | Whether creation succeeded. |
| jobId | Store this value and poll the status endpoint. |
| conversationId | Associated creative brief conversation. |
| creditsReserved | Credits reserved for this job. |
| costSource | The pricing basis used for the reserve. |
| warnings | Optional messages about mappings, ignored fields or normalized values. |
Migrating older requests
Use video_idea, optional segments[].idea and notes. Classic per-segment instruction fields, video_mode and explicit legacy voice IDs are rejected with 422 classic_fields_unsupported. Its fields and hint explain what to change. A bare URL returns 400 video_idea_required.
The URL remains /api/v1/videos; the current implementation uses the Ava director. API path version and video pipeline version are separate.
Creating another video is a new billable action. There is no documented public idempotency-key contract. After an ambiguous network failure, inspect recent jobs and reconcile the request before retrying.
Voice, media and ordered segment hints
- Set speech, then choose audio_source. Native audio makes people on screen speak; voiceover uses an off-screen narrator; voice_clone uses your sample; voice_design uses your description. speech: no selects ambient sound with audio_source: none.
- For a narrator, set voice_gender and voice_style. Use voice_script_mode: dictate for your exact words, or planner to let the director write. assist without a script falls back to planner.
- Dictated narrator, cloned and designed voices are paced at 2.0 words per second; native speech is paced at 2.5. A script that outruns the requested duration fails validation.
- Combine image_sources when you need both page images and uploads. reference_images always adds upload. Media must be reachable public HTTPS images or audio, at most 10 MB each; foreign-host files are copied into your library.
- Up to 10 segments can pin the exact segment count, order, idea and references. Each hint accepts up to 10 reference images plus continuation. The director plans production within that structure. The classic segments[] object fields textPrompt, imagePrompt, motionPrompt and referenceImageUrls are also accepted.
The in-app Memory pickers are not available to API callers. Pass media URLs in reference_images, segment references, logo_url or voice_clone_sample_url.
A narrated video brief
curl --fail-with-body -X POST https://app.jemsu.ai/api/v1/videos \
-H "Authorization: Bearer $JEMSU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_idea": "A 20-second promo for a neighborhood bakery: warm morning light, sourdough out of the oven, a close-up of the crust, end on the shop sign.",
"video_length_sec": 20,
"speech": "yes",
"audio_source": "voiceover",
"voice_gender": "female",
"voice_style": "warm and friendly",
"voice_script_mode": "planner",
"music": "yes",
"music_notes": "upbeat acoustic",
"captions": "yes",
"aspectratio": "9:16",
"notes": "Never show prices. The sign reads BAKED DAILY."
}'
Example creation response
Illustrative 20-second response. Credit cost depends on the chosen model, duration and resolution; read the actual response for your job. The warnings example shows a mapped legacy alias.
{
"ok": true,
"jobId": "YOUR_JOB_ID",
"conversationId": "YOUR_CONVERSATION_ID",
"creditsReserved": 1440,
"costSource": "v2:pinned:seedance-2.0@720p@20s",
"warnings": [
"mapped videolength \u2192 video_length_sec"
]
}
creditsReserved is the pinned model’s rate multiplied by the requested seconds. costSource identifies the model, resolution and duration used for pricing. The final charge is reconciled after delivery; any difference is refunded.
Classic aliases that are mapped
Each alias mapping and ignored field appears in warnings. Canonical values are coerced leniently: for example, “true” becomes yes and “30” becomes 30. Values outside an allowed list are ignored with a warning; unresolved requirements return 422 brief_invalid.
| Classic input | Director field | Notes |
|---|---|---|
videoIdea |
video_idea |
|
videolength / veovideolength |
video_length_sec |
5–300 whole seconds |
voicescript |
voice_script |
|
music: background or music_only / none |
music: yes / no |
music_instructions maps to music_notes |
caption_highlight_color / captions_language |
caption_color / caption_language |
|
aspect_ratio |
aspectratio |
|
resolution: 4k |
resolution: 1080p |
Director output does not support 4K |
language / voiceover_language |
video_language |
|
customlogo |
logo_url |
|
videogenerationmodel |
video_model |
veo maps to omni |
imagegenerationmodel |
image_model |
|
voicedesigndescription |
voice_design_description |
|
voiceCloneAudioUrl |
voice_clone_sample_url |
|
userphoto2 / saved_image_urls |
reference_images |
userphoto2 becomes a person reference |
people_image_source / products_image_source |
image_source |
uploaded → upload; scraped → url_images; ai_generated stays unchanged. upload wins when sources differ. |
pipeline |
Accepted and ignored |
Every request uses the director |
Classic fields that are refused
Sending one of these fields with a value returns 422 classic_fields_unsupported. The suffix N represents a numbered legacy segment field.
Server-managed fields
These fields are silently stripped from requests and loaded styles; sending them does not change the account, job protocol or callback configuration: