Skip to content
Console

Get started

Queued jobs

Copy page

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
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"}'
Response — 202 (abridged)
{
"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
}
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.

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.

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.

JavaScript
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.

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 its error says 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.

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
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.