Dokumentasi
Tugas dan hasil
Create a job
POST /v1/generations
Authorization: Bearer cv_live_YOUR_KEY
Content-Type: application/json
Idempotency-Key: 7d1c0f6e-5b0a-4a33-9f2e-0c1b2a3d4e5f
{
"plan": "credits",
"model": "veo-3.1",
"params": { "prompt": "A paper boat on a rainy street", "aspect_ratio": "16:9", "duration": 8 }
}
The response is 201 with the job. A replayed request (same Idempotency-Key and body) returns 200 and the header Idempotent-Replayed: true. See Idempotency.
params takes the prompt and the options of the model (aspect_ratio, duration, resolution). Input images go in params.images as base64 (data) with the MIME type; the request body can be up to 45 MiB. GET /v1/models lists the parameters and the price table of every model.
Job states
| Status | Meaning | Can be cancelled |
|---|---|---|
pending | Accepted and waiting in the CheapVids queue (your limit of parallel jobs is used up) | Yes, refunded in full |
queued | Sent to the generator, waiting for a slot | Yes if the generator accepts, refunded in full |
processing | Being generated | No (409 not_cancellable) |
completed | Done, the result can be downloaded | No |
failed | Failed, refunded | No |
cancelled | Cancelled, refunded | No |
Each job produces exactly one result. For several variants of a prompt, create several jobs, each with its own Idempotency-Key.
While a job is not finished the response has next: { "action": "poll", "after_seconds": 5 }. Use GET /v1/generations/{id}?wait=60 (Long polling) or a webhook instead of polling in a tight loop. POST /v1/generations/{id}/cancel cancels a job that has not started running.
Download the result
CheapVids does not store the results of API jobs. It relays the file from the generator while you download, for a limited window after the job finishes.
output.urlof a completed job is a CheapVids URL:https://api.cheapvids.com/v1/generations/{id}/content?exp=...&sig=.... It works without an API key (for example in a<video>tag) for one hour. CallGET /v1/generations/{id}again to get a fresh URL.- You can also call
GET /v1/generations/{id}/contentwith your API key. Add?download=1for aContent-Disposition: attachmentresponse. Rangeis supported, one range per request (Range: bytes=0-1048575), so video players can seek.HEADreturns the total size inContent-Length.- The window is
results.api_ttl_hoursinGET /v1/account(24 hours by default) after completion, andresult_expires_aton the job. After it, the endpoint answers410 result_expired. Download as soon as the job is done. - If the generator no longer serves the file, you get
502 result_unavailable(retry after theRetry-Afterseconds).
Download limits
To keep the service fast for everyone, downloads are limited per account:
- a few streams at the same time (
429withRetry-After: 5when you are over), - a daily amount of bytes (
results.download.user_gib_per_day, withused_bytes_todayinGET /v1/account), - a number of downloads per result (
results.download.job_download_multipletimes the file size per day), - for signed URLs, a limit of requests per minute per IP address.
A download that hits a limit answers 429 rate_limited with Retry-After and details.scope set to bandwidth, job or ip. The bytes of one download count when the transfer runs, so a transfer that already started is never cut.

