Skip to main content
POST
/
v1
/
videos
/
generations
Video Generations
curl --request POST \
  --url https://kymaapi.com/v1/videos/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "<string>",
  "prompt": "<string>",
  "duration": 123,
  "image_url": "<string>",
  "idempotency_key": "<string>",
  "extra": {}
}
'
{
  "id": "<string>",
  "status": "<string>",
  "estimated_cost": 123,
  "charged_amount": {}
}
Async endpoint. The request returns immediately with a job_id; the actual generation runs in the background and is charged on success only. Billed per second of generated footage.

Request body

model
string
required
One of: kling-2.5-pro, kling-3-pro, kling-3-pro-audio, seedance-2-pro, seedance-2-fast. See Video Generation.
prompt
string
required
Text prompt describing the desired video. Maximum 4000 characters.
duration
number
default:"5"
Clip length in seconds. Range 1–10. Each second is billed at the model’s per-second rate.
image_url
string
HTTPS URL of a starting frame. When present, Kyma routes the request to the model’s image-to-video variant — the image becomes the first frame and the prompt drives the motion. Optional; all five models accept it.
idempotency_key
string
Client-supplied key (≤128 chars) to make the request safe to retry. Repeated POSTs with the same (api_key, idempotency_key) pair return the same job — no duplicate charge, no duplicate generation.
extra
object
Pass-through model-specific parameters (e.g. seed, aspect_ratio). Forwarded to the underlying provider unchanged.

Response

202 Accepted for new jobs, 200 OK if the same idempotency_key is replayed.
{
  "id": "v3a9c8b2e1d0a4b6c7d8e9f0",
  "object": "video.job",
  "status": "pending",
  "model": "kling-3-pro",
  "created_at": "2026-04-26T10:00:00.000Z",
  "completed_at": null,
  "output": null,
  "error": null,
  "estimated_cost": 0.7560,
  "charged_amount": null
}
id
string
Job ID. Use it to poll GET /v1/jobs/{id}.
status
string
One of: pending, processing, succeeded, failed, refunded, expired.
estimated_cost
number
Hold amount placed at submit time (USD) — per_second_usd × duration. Refunded if the job fails.
charged_amount
number | null
Final billed amount once the job succeeds. null until then.

Poll for the result

GET /v1/jobs/{id}
Same response shape. Poll every 2–5 seconds until status is succeeded, failed, refunded, or expired. Most clips complete within 1–3 minutes; the runner times out at 10 minutes.
{
  "id": "v3a9c8b2e1d0a4b6c7d8e9f0",
  "object": "video.job",
  "status": "succeeded",
  "model": "kling-3-pro",
  "created_at": "2026-04-26T10:00:00.000Z",
  "completed_at": "2026-04-26T10:02:18.840Z",
  "output": {
    "url": "https://blob.vercel-storage.com/.../clip.mp4",
    "metadata": {
      "videos": [{
        "width": 1920,
        "height": 1080,
        "duration": 5,
        "content_type": "video/mp4"
      }]
    }
  },
  "error": null,
  "estimated_cost": 0.7560,
  "charged_amount": 0.7560
}
The output.url points to a Vercel Blob URL hosted by Kyma — the original upstream URL is rehosted so it remains stable after the upstream TTL expires.

Errors

Statuserror.codeWhen
400invalid_modelModel is not a supported video model
400invalid_promptMissing prompt or > 4000 chars
400invalid_durationduration is outside 1–10
401auth_errorMissing or invalid API key
402insufficient_balanceHold could not be placed
413invalid_requestRequest body > 25 MB
429rate_limitedTier limit exceeded
500db_error / provider_errorInternal failure — hold is fully refunded
When status becomes failed or refunded, no charge is made and the held funds are returned to your balance via a hold_release ledger entry.

Examples

Cinematic hero clip

curl -X POST https://kymaapi.com/v1/videos/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3-pro",
    "prompt": "an architectural fly-through of a glass-and-steel tower at sunset, cinematic anamorphic look",
    "duration": 5
  }'

Talking-head with native audio

curl -X POST https://kymaapi.com/v1/videos/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3-pro-audio",
    "prompt": "a barista pulling an espresso shot, the machine hisses, ambient cafe murmur",
    "duration": 5
  }'

Image-to-video

curl -X POST https://kymaapi.com/v1/videos/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-pro",
    "prompt": "the camera pulls back as the subject begins to walk forward",
    "image_url": "https://example.com/frame-1.jpg",
    "duration": 5
  }'

Idempotent retry

curl -X POST https://kymaapi.com/v1/videos/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-fast",
    "prompt": "a phone notification slides in from the right, soft chime, clean UI background",
    "duration": 5,
    "idempotency_key": "campaign-spring-asset-7"
  }'
Replaying this exact request returns the same job — no new charge.