Video

Video generation is asynchronous — you submit a job, then poll for the result. Renders take 30 seconds to several minutes depending on the model and length.

Two flavors of model

The catalog has two kinds of video model, each with a slightly different request shape:

  • Text-to-video — pass a prompt. Used for everything in the standard catalog (veo3, kling-2.1-pro, runway-gen4, etc.).
  • Image-to-video — pass a prompt AND an image_url (a publicly fetchable URL). Used by models with the -i2v suffix.

The endpoint URL is the same; only the body differs.

Submit a job

POST/v1/videosauth · sk-echo

Submit a render. Returns 202 with a job id; poll /v1/videos/{id} for the result.

import requests

resp = requests.post(
  "https://api.echotokens.me/v1/videos",
  headers={"Authorization": "Bearer sk-echo-..."},
  json={
      "model": "kling-2.5-turbo",
      "prompt": "A slow drone shot over an alpine meadow at golden hour.",
      "aspect_ratio": "16:9",
      "duration": "5",
  },
)
job = resp.json()
print(job["id"], job.get("status"))

Parameters

  • parameter
    model
    type
    string
    required
    required
    Video model id — see the catalog below.
  • parameter
    prompt
    type
    string
    required
    required
    Description of the desired video.
  • parameter
    image_url
    type
    string (URL)
    required
    optional
    Required for image-to-video models (-i2v). Must be a publicly fetchable URL.
  • parameter
    aspect_ratio
    type
    string
    required
    optional
    16:9, 9:16, or 1:1.
    default: 16:9
  • parameter
    duration
    type
    string (seconds)
    required
    optional
    Model-dependent. Most models accept "5" or "10".
  • parameter
    quality
    type
    string
    required
    optional
    Model-dependent. e.g. 720p, 1080p (only some models support a quality switch).

Response

response · 202
{
"id": "vid_01J...",
"status": "queued"
}
Poll GET /v1/videos/{id} every 5–10 seconds until status is "ready" or "failed".

Poll for the result

GET/v1/videos/{id}auth · sk-echo

Returns the job's current state. Once status is ready, the result_url is a signed link valid for 24 hours.

import time, requests

while True:
  r = requests.get(
      f"https://api.echotokens.me/v1/videos/{job_id}",
      headers={"Authorization": "Bearer sk-echo-..."},
  )
  status = r.json()
  if status["status"] in ("ready", "failed"):
      break
  time.sleep(5)

if status["status"] == "ready":
  print(status["result"]["url"])
  print("Cost:", status.get("cost_usd_cents"))
response · 200
{
"id": "vid_01J...",
"status": "ready",
"result": {
  "url": "https://api.echotokens.me/v1/assets/eyJ1Ij...",
  "duration_seconds": 5
},
"cost_usd_cents": 38
}
result.url points at our signed asset host with a 24h TTL. Video URLs support HTTP Range requests so a <video> element can seek without re-downloading.
we re-sign the URL on read

The portal's Generations history shows clips submitted weeks ago — we re-mint the signed URL with a fresh 24-hour TTL every time you fetch a job from /account/jobs/videos. From your code, just hold the most recent response for that job; the URL inside is good for another 24h from the time you got it.

Image-to-video

The -i2v model family requires an image_url field. The URL must be publicly fetchable — the upstream side-fetches the bytes. If your image isn't already on a public host, use the portal's video studio which uploads attachments to a short-lived signed URL on our host first.

resp = requests.post(
  "https://api.echotokens.me/v1/videos",
  headers={"Authorization": "Bearer sk-echo-..."},
  json={
      "model": "kling-2.5-turbo-i2v",
      "prompt": "The character turns and smiles, soft window light.",
      "image_url": "https://cdn.example.com/hero.png",
      "duration": "5",
  },
)

Model catalog

The live per-model pricing is on the pricing page — it's the source of truth and updates as we ship new models.

all video models
Loading model catalog…

catalog auto-syncs from the upstream every 6h · canonical pricing at /pricing

renders aren't cheap

A frontier text-to-video clip can run $0.10 – $2 depending on resolution and length. Check cost_usd_cents on the polled job before scaling out a batch. The usage page shows historical per-request cost.

try it in the studio
Video studio

Submit jobs, attach images for i2v models, and watch them render — including for-you reactions and re-submits — without writing the polling loop yourself.