Get started
Queued jobs
Which endpoints answer 202 with a gen_… id, how to poll them, what each status means, and when a job is charged or refunded.
Work that takes longer than a request should wait is queued. The request answers 202 Accepted at once with a gen_… id, and you poll that id until the job finishes.
curl https://api.lumavox.ai/v1/images \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "A paper boat on a rain-soaked street"}'{ "id": "gen_a1B2c3D4e5F6g7H8", "status": "queued", "capability": "image", "prompt": "A paper boat on a rain-soaked street", "credits_micros": 4000000, "image": null, "error": null, "created_at": "2026-10-24T09:30:00.000Z", "finished_at": null}The queued endpoints
Section titled “The queued endpoints”| Submit | Poll | Scope | Result on success |
|---|---|---|---|
POST /v1/images |
GET /v1/images/{generation_id} |
image |
image |
POST /v1/videos |
GET /v1/videos/{generation_id} |
video |
video |
POST /v1/audio |
GET /v1/audio/{generation_id} |
tts |
audio |
POST /v1/skybox |
GET /v1/skybox/{generation_id} |
skybox |
skybox |
POST /v1/transcriptions |
GET /v1/transcriptions/{generation_id} |
stt |
transcript |
POST /v1/templates/{template_id}/generate |
the poll for the template’s capability |
the template’s capability | as that capability |
Every poll answers the same shape — the job, with its parameters, its status, and the result once there is one. The API reference has every field.
Statuses
Section titled “Statuses”status |
Means | What to do |
|---|---|---|
queued |
accepted, waiting to start | keep polling |
submitted |
handed to the provider | keep polling |
running |
being generated | keep polling |
succeeded |
finished — the result is on the response | stop; download it |
failed |
it did not produce anything; error says why |
stop; it was refunded |
moderated |
refused by the provider’s safety filter | stop; it was refunded |
succeeded, failed and moderated are terminal: a job never leaves them.
Polling
Section titled “Polling”Poll every couple of seconds for images and transcriptions. A video takes minutes, so poll it less often. Polls do not count against your rate limits — submits do.
const headers = { Authorization: `Bearer ${process.env.API_KEY}` };const RUNNING = ["queued", "submitted", "running"];
async function waitFor(capability, id, everyMs = 2000) { for (;;) { const job = await fetch(`https://api.lumavox.ai/v1/${capability}/${id}`, { headers, }).then((r) => r.json()); if (!RUNNING.includes(job.status)) return job; await new Promise((resolve) => setTimeout(resolve, everyMs)); }}
const job = await waitFor("images", "gen_a1B2c3D4e5F6g7H8");An id from another capability, or from another organisation, is a 404 — each poll reads only its own capability’s jobs. GET /v1/generations/{generation_id} reads any of them.
The result
Section titled “The result”On succeeded, the result is under the capability’s name — image, video, audio, skybox or transcript. Each carries:
url— a short-lived link to the file, made fresh on every response and never stored. Download it promptly; read the job or the asset again for a new one.asset_id— the same file in your library, kept until you delete it. Fetch it from there later.
The capability’s own page says what else its result holds — a video’s duration, a skybox’s preview, a transcript’s text.
Charged when accepted, refunded on failure
Section titled “Charged when accepted, refunded on failure”A queued job is charged when it is accepted, not when it finishes: the 202 response’s credits_micros is what was debited, in micro-credits (Conventions). Each capability’s endpoint says what its price depends on — megapixels for an image and each of its references, seconds and resolution for a video, characters for stored audio, one flat price for a skybox.
- A job that fails, or is refused by the safety filter, is refunded in full.
- A transcription is charged an estimate, then corrected to the audio’s measured length when it finishes.
- A job that stops reporting is settled for you. It ends
failed, is refunded, and itserrorsays it was not charged — within about six hours of when you submitted it.
Checking your balance before a batch is cheaper than learning from a 402: see credits and usage.
Some capabilities limit how much may be in flight. You may only have so many unfinished videos at once; over that, POST /v1/videos answers 429 and charges nothing.
Finding jobs again
Section titled “Finding jobs again”GET /v1/generations lists every job your organisation has submitted, newest first, in flight or finished — filtered to the capabilities your key holds. It is how you get back an id you lost: a submit that timed out on your side may still have been accepted.
curl "https://api.lumavox.ai/v1/generations?status=running&limit=50" \ -H "Authorization: Bearer $API_KEY"| Query | What it does |
|---|---|
capability |
one of image, video, tts, stt, skybox |
status |
one of the statuses above |
limit |
1 to 100 a page; 30 by default |
cursor |
the previous page’s next_cursor |
The answer is a page — data, and next_cursor, which is null on the last page (Conventions). Generations covers the listing in full.