Appearance
Video
- Video makes a clip with sound from a description, or animates an image.
- Talking avatars turn a photo and a voice into a lip-synced video.
Endpoints:
GET /v1/video/optionsPOST /v1/videoGET /v1/video/{id}GET /v1/video/{id}/files/{name}GET /v1/avatars/optionsPOST /v1/avatarsGET /v1/avatars/{id}GET /v1/avatars/{id}/files/{name}
Images you can use
Video and talking avatars take an image as an object in one of two forms:
| Form | Description |
|---|---|
{"key": "<storage key>"} | A finished image upload in this workspace (PNG, JPEG or WebP, up to 20 MB). |
{"generationId": "<id>", "file": "image-1"} | A file from a succeeded Images generation in this workspace. |
Video
Video models
id | Name | Note | Seconds | Resolutions | Aspect ratios (text to video) | End frame | Seed |
|---|---|---|---|---|---|---|---|
scene | Scene | Fastest and most affordable, with sound | 5–15 | 768P (default), 480P | 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 | yes | yes |
feature | Feature | Richer motion and expressions, with sound | 5–15 | 768P (default), 480P | 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 | yes | yes |
directors-cut | Director's Cut | Most cinematic camera moves, with sound | 3–15 | none | 16:9, 9:16, 1:1 | no | no |
Get video options
GET /v1/video/options
Response
200 OK
json
{
"models": [
{
"id": "scene",
"label": "Scene",
"note": "Fastest and most affordable, with sound",
"minSeconds": 5,
"maxSeconds": 15,
"resolutions": ["768P", "480P"],
"aspectRatios": ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"],
"endFrame": true,
"seed": true,
"credits": { "5": 320, "6": 380, "7": 440, "8": 500, "9": 570, "10": 630, "11": 690, "12": 750, "13": 820, "14": 880, "15": 940 }
}
],
"promptMax": 2000,
"maxImageBytes": 20971520,
"examples": [
"A paper boat drifting down a rainy city street at night, neon reflections in the puddles, slow tracking shot"
]
}models and examples are shortened above. credits gives the price for each length the model makes. seed: false means the model ignores the seed.
Credits
Free.
Example
bash
curl https://api.cinara.ai/v1/video/options \
-H "Authorization: Bearer $CINARA_API_KEY"Create a video
POST /v1/video
Starts making a video clip with sound.
Needs a verified phone.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | scene, feature or directors-cut. |
mode | string | no | text (default) or image. Any other value is text. |
prompt | string | yes | What happens in the clip. 3–2,000 characters. Naming well-known people is refused. |
seconds | integer | no | Length, within the model's range. Default: the model's minimum. |
resolution | string | no | One of the model's resolutions. Default: the model's first. Ignored by directors-cut. |
aspectRatio | string | no | Text to video only: one of the model's aspect ratios. Default 16:9. Image to video follows the image. |
seed | integer | no | 0–2147483647. Ignored by directors-cut. |
image | object | image mode | The first frame. See Images you can use. |
endImage | object | no | image mode on scene or feature: the last frame. |
Response
201 Created
json
{
"generation": {
"id": "3a8e5c1f-7b2d-4f9e-a6c4-0d3b8e1f5a72",
"module": "video",
"status": "running",
"input": {
"model": "scene",
"mode": "text",
"prompt": "A golden retriever puppy chasing bubbles in a sunny garden, playful, shallow depth of field",
"seconds": 6,
"resolution": null,
"aspectRatio": "9:16",
"seed": null,
"imageUrl": null,
"endImageUrl": null,
"image": null,
"endImage": null,
"fileName": "a-golden-retriever-puppy-chasing-bubbles-in-a-sun.mp4"
},
"output": { "stage": "queued", "stageLabel": "Creating the video" },
"credits": 380,
"error": null,
"created_at": "2026-09-15T19:40:13.902355+00:00",
"completed_at": null
},
"credits": 42366
}In image mode, input.image holds { "key": "<storage key>", "contentType": "image/png" } and input.imageUrl holds the same storage key.
Errors
| Status | error | Message |
|---|---|---|
| 400 | invalid_request | Choose a model |
| 400 | invalid_request | Upload the image first |
| 400 | invalid_request | That image isn't available any more |
| 400 | invalid_request | Choose an image |
| 400 | invalid_request | That image isn't finished uploading. Add it again. |
| 400 | invalid_request | Use a PNG, JPEG or WebP image |
| 400 | invalid_request | Describe the video |
| 400 | invalid_request | Keep the description under 2,000 characters |
| 400 | invalid_request | Scene makes 5 to 15 second videos |
| 400 | invalid_request | Choose 768P or 480P |
| 400 | invalid_request | Director's Cut makes 16:9, 9:16, 1:1 videos |
| 400 | invalid_request | Choose the image to animate |
| 400 | invalid_request | Director's Cut can't take an end frame |
| 400 | invalid_request | The seed must be a whole number from 0 to 2147483647 |
| 400 | invalid_request | Cinara doesn't make videos of well-known people. Describe the scene without naming them. |
| 402 | insufficient_credits | This needs 380 credits |
| 403 | phone_unverified | Verify your phone number to start creating. |
| 502 | generation_failed | The video couldn't start. Your credits were refunded. |
Credits
A fixed price per model and length, from credits in Get video options. Not adjusted afterwards. Refunded if the video can't be made.
The rule: max(10, ceil(rate × seconds ÷ 10) × 10), with a rate of 62.5 credits per second for scene, 125 for feature and 1,120 for directors-cut.
| Seconds | scene | feature | directors-cut |
|---|---|---|---|
| 3 | — | — | 3,360 |
| 5 | 320 | 630 | 5,610 |
| 10 | 630 | 1,250 | 11,210 |
| 15 | 940 | 1,880 | 16,800 |
Example
bash
curl -X POST https://api.cinara.ai/v1/video \
-H "Authorization: Bearer $CINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "scene", "prompt": "A golden retriever puppy chasing bubbles in a sunny garden, playful, shallow depth of field", "seconds": 6, "aspectRatio": "9:16"}'Animate an image made in Images:
bash
curl -X POST https://api.cinara.ai/v1/video \
-H "Authorization: Bearer $CINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "feature", "mode": "image", "prompt": "Snow starts falling and the sign flickers on", "seconds": 5, "image": {"generationId": "7f2c9a4e-1d6b-4e8a-b3c5-9a0e2d7f4b61", "file": "image-1"}}'Get a video job
GET /v1/video/{id}
Checks a video job, moves it forward, and returns it with its file once finished.
Response
200 OK
json
{
"generation": {
"id": "3a8e5c1f-7b2d-4f9e-a6c4-0d3b8e1f5a72",
"module": "video",
"status": "succeeded",
"input": { "model": "scene", "mode": "text", "prompt": "A golden retriever puppy chasing bubbles in a sunny garden, playful, shallow depth of field", "seconds": 6, "…": "…" },
"output": {},
"credits": 380,
"error": null,
"created_at": "2026-09-15T19:40:13.902355+00:00",
"completed_at": "2026-09-15T19:41:02.117698+00:00"
},
"files": [
{ "name": "video", "label": "Video", "contentType": "video/mp4", "size": 6219342, "url": "https://api.cinara.ai/media/1789544462/Jd2wL…/workspaces/…/video/…/video.mp4" }
],
"credits": 42366
}files holds one file, video, once the job succeeds.
Failures:
Video took too long and was stopped.This video couldn't be made from this request. Try a different description or image.The video couldn't be made.
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | Not found |
Credits
Free to read.
Polling example
bash
while :; do
RES=$(curl -s "https://api.cinara.ai/v1/video/$ID" -H "Authorization: Bearer $CINARA_API_KEY")
[ "$(echo "$RES" | jq -r .generation.status)" != "running" ] && break
sleep 10
done
curl -L "https://api.cinara.ai/v1/video/$ID/files/video" -H "Authorization: Bearer $CINARA_API_KEY" -o clip.mp4Download a video
GET /v1/video/{id}/files/{name}
Downloads the finished video (video) as an attachment.
Response
200 OK with the video and Content-Disposition: attachment; filename="<file name>-video.mp4".
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | File not found |
Credits
Free.
Example
bash
curl -L "https://api.cinara.ai/v1/video/3a8e5c1f-7b2d-4f9e-a6c4-0d3b8e1f5a72/files/video" \
-H "Authorization: Bearer $CINARA_API_KEY" -o clip.mp4Talking avatars
Avatar models
id | Name | Note | Aspect ratios |
|---|---|---|---|
monologue | Monologue | Natural gestures, most affordable | Follows the photo |
anchor | Anchor | Steadier head, faster to make | 16:9, 9:16, 1:1, 4:5, 5:4 |
Get avatar options
GET /v1/avatars/options
Response
200 OK
json
{
"models": [
{ "id": "monologue", "label": "Monologue", "note": "Natural gestures, most affordable", "aspectRatios": [], "creditsPerSecond": 562, "reservePadSeconds": 1.5 },
{ "id": "anchor", "label": "Anchor", "note": "Steadier head, faster to make", "aspectRatios": ["16:9", "9:16", "1:1", "4:5", "5:4"], "creditsPerSecond": 1000, "reservePadSeconds": 0 }
],
"maxSeconds": 60,
"scriptMax": 900,
"charactersPerSecond": 15,
"speechCreditsPerCharacter": 1,
"maxImageBytes": 20971520
}| Field | Description |
|---|---|
creditsPerSecond | Video credits per second of avatar video. |
reservePadSeconds | Extra seconds reserved, because the model's video can run past the speech. |
maxSeconds | Longest speech: 60 seconds. |
scriptMax | Longest script: 900 characters (about a minute). |
charactersPerSecond | The speaking rate used to estimate a script's length before it's spoken. |
speechCreditsPerCharacter | Speech credits for a typed script. |
Credits
Free.
Example
bash
curl https://api.cinara.ai/v1/avatars/options \
-H "Authorization: Bearer $CINARA_API_KEY"Create a talking avatar
POST /v1/avatars
Starts animating a photo so it speaks a typed script (in any voice the workspace can use) or uploaded audio.
Needs a verified phone.
With a script, the speech is made first, within this request, with Cinara Speech. Pronunciation rules aren't applied.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | monologue or anchor. |
attested | boolean | yes | Must be true: you have the right to use this person's photo and voice. |
image | object | yes | The photo. A clear, front-facing photo of one face works best. See Images you can use. |
source | string | no | script (default) or audio. Any other value is script. |
script | string | script source | What the avatar says. 1–900 characters. |
voiceId | string | script source | A library voice id, or a workspace voice's providerVoiceId. |
audio | object | audio source | {"key": "<storage key>"} of a finished audio upload. Up to 20 MB. Its length must be readable: MP3, WAV or M4A. |
aspectRatio | string | no | anchor: one of its aspect ratios. Default 16:9. monologue follows the photo. |
prompt | string | no | monologue: how the person moves, up to 300 characters; longer is refused. Default "A person speaking naturally to the camera". |
The speech can be up to 60 seconds. Naming well-known people in the script or prompt is refused.
Response
201 Created
json
{
"generation": {
"id": "c5f1a8d3-2e9b-4c7a-8d6e-1b4f0a7c3e95",
"module": "avatar",
"status": "running",
"input": {
"model": "anchor",
"image": { "key": "workspaces/3f6b2a1c-8d4e-4b7a-9c2d-5e1f0a9b8c7d/uploads/6b3e9d2a-4f1c-4a8e-b7d5-2c0e8a4f1b93/presenter.png", "contentType": "image/png" },
"source": "script",
"script": "Welcome to week three. Today we'll build our first playlist and share it with the class.",
"voiceId": "kindred",
"audio": null,
"seconds": 5.84,
"aspectRatio": "9:16",
"prompt": "",
"fileName": "welcome-to-week-three-today-we-ll-build-our-first.mp4",
"speechCredits": 88,
"attestedAt": "2026-09-15T20:05:40.311Z"
},
"output": { "stage": "queued", "stageLabel": "Animating the photo" },
"credits": 5930,
"error": null,
"created_at": "2026-09-15T20:05:40.402183+00:00",
"completed_at": null
},
"credits": 36436
}input.seconds is the speech's length.
Errors
| Status | error | Message |
|---|---|---|
| 400 | invalid_request | Choose a model |
| 400 | invalid_request | Confirm you have the right to use this person's photo and voice. |
| 400 | invalid_request | Keep the prompt under 300 characters |
| 400 | invalid_request | Upload the image first |
| 400 | invalid_request | That image isn't available any more |
| 400 | invalid_request | Choose an image |
| 400 | invalid_request | That image isn't finished uploading. Add it again. |
| 400 | invalid_request | Use a PNG, JPEG or WebP image |
| 400 | invalid_request | Choose a photo |
| 400 | invalid_request | Cinara doesn't make talking videos of well-known people. |
| 400 | invalid_request | Write what the avatar says |
| 400 | invalid_request | Keep the script under 900 characters (about a minute) |
| 400 | invalid_request | Choose a voice |
| 400 | invalid_request | Upload the audio first |
| 404 | not_found | That upload isn't finished. Upload the audio again. |
| 400 | invalid_request | Upload an audio file |
| 400 | invalid_request | Use an audio file under 20 MB (about a minute of speech) |
| 400 | invalid_request | Use an MP3, WAV or M4A file |
| 400 | invalid_request | Add something for the avatar to say |
| 400 | invalid_request | Keep the speech under 60 seconds |
| 400 | invalid_request | Choose 16:9, 9:16, 1:1, 4:5, 5:4 |
| 402 | insufficient_credits | This needs 6,620 credits (the reserve, checked before any speech is made) |
| 402 | insufficient_credits | This needs 7,180 credits (script source: the speech ran longer than estimated and the balance can't cover it; refunded) |
| 403 | phone_unverified | Verify your phone number to start creating. |
| 502 | generation_failed | The voice couldn't be made. Your credits were refunded; try again in a moment. |
| 502 | generation_failed | The avatar video couldn't start. Your credits were refunded. |
Credits
Two parts:
- Speech (script source only):
max(1, ceil(script characters × 1)). - Video:
max(10, ceil(creditsPerSecond × seconds ÷ 10) × 10), with 562 credits per second formonologueand 1,000 foranchor.
Reserved before any speech is made: video credits for the speech's length plus the model's reservePadSeconds, plus the speech credits. With a script, the length is first estimated as characters ÷ 15 seconds; for example, a 150-character script on monologue reserves 6,470 + 150 = 6,620 credits. Once the speech is made, the reserve follows its real length: the difference is charged or refunded.
Final: video credits for the delivered video's length plus the speech credits, never more than reserved. Refunded in full if it fails.
Example
bash
curl -X POST https://api.cinara.ai/v1/avatars \
-H "Authorization: Bearer $CINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anchor",
"attested": true,
"image": {"key": "workspaces/3f6b2a1c-8d4e-4b7a-9c2d-5e1f0a9b8c7d/uploads/6b3e9d2a-4f1c-4a8e-b7d5-2c0e8a4f1b93/presenter.png"},
"script": "Welcome to week three. Today we will build our first playlist and share it with the class.",
"voiceId": "kindred",
"aspectRatio": "9:16"
}'Get a talking avatar job
GET /v1/avatars/{id}
Checks a talking avatar job, moves it forward, and returns it with its file once finished.
Response
200 OK
json
{
"generation": {
"id": "c5f1a8d3-2e9b-4c7a-8d6e-1b4f0a7c3e95",
"module": "avatar",
"status": "succeeded",
"input": { "model": "anchor", "source": "script", "voiceId": "kindred", "seconds": 5.84, "aspectRatio": "9:16", "…": "…" },
"output": { "durationSeconds": 5.84 },
"credits": 5930,
"error": null,
"created_at": "2026-09-15T20:05:40.402183+00:00",
"completed_at": "2026-09-15T20:06:55.980417+00:00"
},
"files": [
{ "name": "video", "label": "Avatar video", "contentType": "video/mp4", "size": 2981023, "url": "https://api.cinara.ai/media/1789545915/Wn4hP…/workspaces/…/avatars/…/video.mp4" }
],
"credits": 36436
}output.durationSeconds is the delivered video's length. files holds video once the job succeeds.
Failures:
Avatar video took too long and was stopped.This photo couldn't be animated. Use a clear, front-facing photo of one face.The avatar video couldn't be made.
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | Not found |
Credits
Free to read.
Polling example
bash
while :; do
RES=$(curl -s "https://api.cinara.ai/v1/avatars/$ID" -H "Authorization: Bearer $CINARA_API_KEY")
[ "$(echo "$RES" | jq -r .generation.status)" != "running" ] && break
sleep 15
done
echo "$RES" | jq '{status: .generation.status, error: .generation.error, files: .files}'Download a talking avatar video
GET /v1/avatars/{id}/files/{name}
Downloads the finished video (video) as an attachment.
Response
200 OK with the video and Content-Disposition: attachment; filename="<file name>-video.mp4".
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | File not found |
Credits
Free.
Example
bash
curl -L "https://api.cinara.ai/v1/avatars/c5f1a8d3-2e9b-4c7a-8d6e-1b4f0a7c3e95/files/video" \
-H "Authorization: Bearer $CINARA_API_KEY" -o avatar.mp4