Videos API

AI video generation

Create videos from text and images, track progress and download MP4 through the Videos API.

Back to documentation

Connection and authentication

Base URL: https://caheoai.com/v1

Authorization: Bearer $STALI_API_KEY

Set STALI_API_KEY in your environment. GET /v1/models checks authentication without creating a video.

read -r -s -p "STALI_API_KEY: " STALI_API_KEY
export STALI_API_KEY
printf '\n'
curl -fsS https://caheoai.com/v1/models -H "Authorization: Bearer ${STALI_API_KEY:?STALI_API_KEY}"

cURL commands use Bash; on Windows, use the PowerShell setup. Replace sample media URLs with your own provider-accessible files.

Creating a video is billable. Save the id from a successful response to track the same job.

If a job fails after an id is returned, refunds depend on provider results and reconciliation. A failed status does not confirm an immediate wallet refund.

Polling, downloading and cancellation do not create another generation. Successful cancellation does not automatically reverse a recorded charge.

Models and capabilities

ModelVendorDuration (seconds)Price / videoReference images, max.Aspect ratiosResolution
veo-3.1Google4 / 6 / 8$0.1818 / $0.1818 / $0.18181–316:9, 9:16720p / 1080p
google-omni-flashGoogle5 / 10$0.3636 / $0.36361–316:9, 9:16720p
grok-imagine-video-1.5xAIdocsUpgrade.video.grokDuration$0.4091 / $0.6818 / $1.021–316:9, 9:16, 1:1, 4:3, 3:4720p / 1080p
st1/seedance-2.0-1080pByteDance4–15 seconds (1s steps)Default 5s = $4.480–10auto / 21:9, 16:9, 4:3, 1:1, 3:4, 9:161080p
st1/seedance-2.0-720pByteDance4–15 seconds (1s steps)Default 5s = $1.820–10auto / 21:9, 16:9, 4:3, 1:1, 3:4, 9:16720p
st1/seedance-2.0-fast-720pByteDance4–15 seconds (1s steps, Fast 720p)Default 5s = $1.450–10auto / 21:9, 16:9, 4:3, 1:1, 3:4, 9:16720p
st1/seedance-2.5-1080pByteDance4–30 seconds (1s steps)Default 5s = $6.800–10auto / 21:9, 16:9, 4:3, 1:1, 3:4, 9:161080p
st1/seedance-2.5-720pByteDance4–30 seconds (1s steps)Default 5s = $2.770–10auto / 21:9, 16:9, 4:3, 1:1, 3:4, 9:16720p

Five main Seedance models (ByteDance, st1/ line): 2.0-1080p, 2.0-720p, 2.0-fast-720p, 2.5-1080p, 2.5-720p. Billed by the exact seconds you send. Veo / Omni / Grok keep fixed duration price tables.

One image via input_reference/images is the first frame (aspect auto). Use reference_image_urls or omni_reference_task_type=reference to guide content with a fixed aspect ratio.

veo-3.1 accepts only 4, 6 or 8. google-omni-flash accepts only 5 or 10. grok-imagine-video-1.5 accepts only 6, 10 or 15. Check seconds in the response.

Endpoints and parameters

POST /v1/videos — create a job

Send application/json. This endpoint reads JSON, not multipart/form-data; use URLs or image JSON supported by the model.

ParameterRequirementUsage
modelRequiredAn available video model ID; set it explicitly rather than relying on a default.
promptRequiredDescribe the subject, setting, action and camera movement.
secondsOptionalFollow the model table. veo-3.1 defaults to 8s; google-omni-flash to 10s; grok-imagine-video-1.5 to 6s.
aspect_ratioOptionalFor example 16:9 or 9:16 depending on the model. Keep it consistent with size.
sizeOptionalDimensions such as 1280x720 or 720x1280. Accepted sizes depend on the model.
images / input_referenceOptionalStarting/reference images via URL/JSON. The entire body is limited to 20 MB; provider image limits also apply.
reference_image_urlsOptionalreference_image_urls: reference images (reference mode; not locked as the first frame).
omni_reference_task_typeOptionalomni_reference_task_type: set "reference" when using reference images with a fixed aspect_ratio.
last_frameOptionalEnd frame for veo-3.1 or grok-imagine-video-1.5, with the same input_reference.
input_videoOptionalSource MP4 URL for google-omni-flash video-to-video.
resolutionOptionalSome models support 720p or 1080p (default 720p). Others may ignore it or derive from size.
generate_audioOptionalSome video models may ignore generate_audio / reference_audios.

GET /v1/videos/{id} — track progress

Include ?model= with the original model. Start with a 10-second polling interval and back off on 429. The JSON below is illustrative, not a live result.

  • queued: the job was accepted and is waiting.
  • in_progress: the provider is processing the job.
  • completed: the result can be downloaded.
  • failed: inspect error and keep the id for support.
{
  "id": "video_abc123",
  "object": "video",
  "model": "st1/seedance-2.0-720p",
  "status": "completed",
  "progress": 100,
  "seconds": "10",
  "size": "1280x720",
  "error": null
}

GET /v1/videos/{id}/content — download MP4

Download only after completed. Send the same API key and ?model=; save the binary response as .mp4.

DELETE /v1/videos/{id} — request cancellation

Cancellation depends on the route and job state; some routes currently do not support DELETE. Cancellation does not guarantee a refund.

Pricing by duration

Prices follow this website’s current configuration, including applicable adjustments. Check them before creating a video.

Seedance duration pricing. Unit: VND per successful video. 4–15s or 4–30s is the supported duration range, not a flat package price. Choose seconds within the supported range; exact prices are listed below. Any fixed generation fee is already included.

st1/seedance-2.0-1080p

If seconds is omitted: 5s = $4.48.

Duration / SecondsPrice / video
4s$3.58
5s$4.48
6s$5.38
7s$6.27
8s$7.17
9s$8.06
10s$8.96
11s$9.86
12s$10.75
13s$11.65
14s$12.54
15s$13.44

st1/seedance-2.0-720p

If seconds is omitted: 5s = $1.82.

Duration / SecondsPrice / video
4s$1.46
5s$1.82
6s$2.18
7s$2.54
8s$2.90
9s$3.27
10s$3.63
11s$3.99
12s$4.35
13s$4.71
14s$5.08
15s$5.44

st1/seedance-2.0-fast-720p

If seconds is omitted: 5s = $1.45.

Duration / SecondsPrice / video
4s$1.16
5s$1.45
6s$1.74
7s$2.03
8s$2.32
9s$2.61
10s$2.90
11s$3.19
12s$3.48
13s$3.77
14s$4.06
15s$4.35

st1/seedance-2.5-1080p

If seconds is omitted: 5s = $6.80.

Duration / SecondsPrice / video
4s$5.44
5s$6.80
6s$8.16
7s$9.52
8s$10.88
9s$12.25
10s$13.61
11s$14.97
12s$16.33
13s$17.69
14s$19.05
15s$20.41
16s$21.77
17s$23.13
18s$24.49
19s$25.85
20s$27.21
21s$28.57
22s$29.93
23s$31.29
24s$32.65
25s$34.02
26s$35.38
27s$36.74
28s$38.10
29s$39.46
30s$40.82

st1/seedance-2.5-720p

If seconds is omitted: 5s = $2.77.

Duration / SecondsPrice / video
4s$2.22
5s$2.77
6s$3.33
7s$3.88
8s$4.43
9s$4.99
10s$5.54
11s$6.09
12s$6.65
13s$7.20
14s$7.75
15s$8.30
16s$8.86
17s$9.41
18s$9.96
19s$10.52
20s$11.07
21s$11.62
22s$12.18
23s$12.73
24s$13.28
25s$13.83
26s$14.39
27s$14.94
28s$15.49
29s$16.05
30s$16.60

Other video models

ModelDuration (seconds)Price / video
veo-3.14$0.1818
veo-3.16$0.1818
veo-3.18$0.1818
google-omni-flash5$0.3636
google-omni-flash10$0.3636
grok-imagine-video-1.56$0.4091
grok-imagine-video-1.510$0.6818
grok-imagine-video-1.515$1.02

Seedance bills by the seconds you send. Veo / Omni / Grok keep fixed duration price tables.

View all pricing

Integration examples

Each POST creates a billable video. Choose one example; example.com media URLs are placeholders and must be replaced.

import os
import time
from getpass import getpass
from urllib.parse import quote
import requests
from requests.adapters import HTTPAdapter

api_key = os.getenv("STALI_API_KEY") or getpass("STALI_API_KEY: ")
headers = {"Authorization": f"Bearer {api_key}"}
model = "st1/seedance-2.0-720p"
http = requests.Session()
http.mount("https://", HTTPAdapter(max_retries=0))
created = http.post("https://caheoai.com/v1/videos", headers=headers, json={
    "model": model, "prompt": "Cinematic sunset over ocean waves",
    "seconds": 5, "aspect_ratio": "16:9",
}, timeout=(10, 120))
created.raise_for_status()
video = created.json()
video_id = video["id"]
print(video_id, video.get("status"), flush=True)
job_url = "https://caheoai.com/v1/videos/" + quote(video_id, safe="")
for _ in range(120):
    if video.get("status") in ("completed", "failed"):
        break
    time.sleep(10)
    progress = http.get(job_url, headers=headers, params={"model": model}, timeout=(10, 60))
    progress.raise_for_status()
    video = progress.json()
    print(video_id, video.get("status"), flush=True)
if video.get("status") != "completed":
    raise RuntimeError(str(video))
content = http.get(job_url + "/content", headers=headers, params={"model": model}, stream=True, timeout=(10, 120))
content.raise_for_status()
with open("video.mp4", "wb") as output:
    for chunk in content.iter_content(chunk_size=65536):
        if chunk:
            output.write(chunk)

Error handling

HTTPCauseAction
400Invalid parameters or unsupported cancellation.Check JSON, seconds, images and model support.
401Missing or invalid key.Check authentication headers and active key.
402HTTP 402: check error.type, available balance, key limit or an outstanding undercharge.Read error.type: insufficient_balance → check available balance; api_key_monthly_limit → check or adjust the limit at Dashboard → Keys; outstanding_undercharge → reconcile the undercharge from earlier requests. See /docs/reference/errors.
403Request is not permitted.Check key permissions, model and content policy.
404Model or job not found on this route.Use the original id, key and ?model=.
409Job is not ready for this operation.Keep polling; download after completed.
413Request body exceeds the limit.Reduce body size; use URLs instead of large embedded media.
429Rate or concurrency limit exceeded.Back off and reduce concurrent jobs.
502Provider route response error.Keep the request ID; do not auto-repeat POST.

Do not automatically repeat POST after a timeout or network error: the first request may have been accepted. If you have an id, poll it; otherwise keep the request ID and check Usage or contact support before recreating.

Prompt design

These are creative guidelines, not a guarantee that a provider will reproduce every detail. Each model’s content policy still applies.

Write a clear prompt

  1. Define subject, setting and main action before effects.
  2. Set duration with seconds, not only in the prompt.
  3. Keep left/right positions and outfits consistent across shots.
  4. Prefer one clear camera movement per shot.
  5. Describe light sources, colors and materials.
  6. Avoid small text, logos or exact numbers in frame.
  7. Start with one short scene; change one factor at a time after reviewing.

Arrange reference images

  • Number Image 1, Image 2… in submission order.
  • State which image controls character, outfit or setting.
  • Use authorized, clear images with a consistent visual direction.
  • Match characters and composition in first/last frames for natural motion.
  • Stay within the model’s image limit; references do not guarantee exact reproduction.

Prompt template

确认生成。参数已确定:16:9 横屏,三个连续镜头组成一个完整视频,立即生成,无需再次确认或提问。
The reference images are colored-pencil character design sketches: use them only for design and outfits. Render the video as a photoreal 3D CG game cinematic with dramatic lighting.
Image 1 = PROTAGONIST: [character design].
Image 2 = ANTAGONIST: [opponent design].
Image 3 = ENVIRONMENT: [setting].
FIXED LAYOUT: altar in the background CENTER; protagonist on the LEFT; antagonist on the RIGHT. Nobody disappears, teleports or swaps sides.
LIGHTING: torchlight from the left wall, cool moonlight from the ceiling.
Action: well-choreographed, orbiting camera. No blood, no wounds, no gore.
Sound: heavy impacts, wind, no dialogue.
镜头1: camera pushes in, protagonist draws a weapon, antagonist raises claws.
镜头2: fast exchange, camera orbits.
镜头3: climax, both stay on their sides, protagonist lands ready.
Keep faces and outfits consistent. No text, no numbers, no subtitles, no watermark.

The template guides the scene. Shorten it if actions are missed; do not use prose instead of API parameters.

Describe non-graphic action

Avoid graphic detailSafer visual direction
blood, wound, gore, corpsesparks, black smoke, torn fabric only
Pool of bloodmurky grey mist, dark viscous puddle
Injury-causing attackglowing wisps of spirit-light, shadowy aura
Cut on skintearing only the fabric of the sleeve, no blood

Build a sequence

  1. Split the story into scenes with clear starts and ends.
  2. Reuse character descriptions, lighting and references.
  3. Download and review each scene before generating the next.
  4. Join scenes in an editor; each POST remains a separate billable job.

When results miss the mark

  • Missing actions: reduce events in one scene.
  • Swapped positions: specify left/right and stable composition.
  • Inconsistency: reuse references and identifying details.
  • Wrong duration: check seconds and fixed-duration models.
  • Rejected: review error and content policy; do not repeatedly resend the same request.

Review motion with a frame grid

ffmpeg -i clip.mp4 -vf "fps=1,scale=320:-1,tile=6x5" -frames:v 1 frame_grid.png

This ffmpeg command reads local clip.mp4 and creates a frame grid without calling the API. Install ffmpeg first.

Preflight checklist

  • Choose the correct model ID and supported duration.
  • Check pricing and balance before creating.
  • Keep keys server-side, out of public browser code.
  • Use JSON and provider-accessible media URLs.
  • Save id, model and request ID for tracking.
  • Poll the same id with ?model= and back off when limited.
  • Download after completed and verify the MP4 file.
  • Do not recreate automatically when acceptance is uncertain.
  • Review errors and costs in Usage; send the id to support if needed.
SupportTelegram groupWhatsAppViber