IN_QUEUE or queued? Two status fields on a Sume job, do not mix
GET /v1/jobs/{id}/status returns sume_status and a queue-shaped status that map one to one. Which to poll, and how /v1/videos values differ.

The status endpoint on Sume jobs returns two ways to say the same thing, and the jobs page says never to mix them. sume_status is queued, processing, completed, failed or canceled. A queue-shaped status field uses IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED and CANCELED, and maps one to one onto sume_status for clients ported from other queue APIs. They never disagree. Poll on the booleans terminal and result_ready, or on sume_status, and pick one.
There is a third vocabulary for video submitted through /v1/videos, and it is the one that surprises people.
Three vocabularies side by side
From the jobs and video pages, read 2026-10-03.
| Surface | Values |
|---|---|
| GET /v1/jobs/{id}/status, sume_status | queued, processing, completed, failed, canceled |
| GET /v1/jobs/{id}/status, queue-shaped status | IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELED |
| GET /v1/videos/{jobId} poll | pending, in_progress, completed, failed, cancelled |
Which one should I poll on
Use terminal for the loop and result_ready for the fetch. A boolean cannot be misspelled, and it does not change when the vocabulary differs between routes. Use sume_status when you need the label, for display or for a switch on completed versus failed versus canceled.
Do not compare strings across surfaces. A check for "canceled" will miss "cancelled" on a /v1/videos poll, and a check for "queued" will miss "pending". If your code reads both routes, normalize once at the edge and keep a single internal enum.
A small normalizer
After normalizing, the rest of the pipeline never needs to know which route produced the job. The same job is readable at both GET /v1/videos/{jobId} and the jobs endpoints.
- Map
pending,queuedandIN_QUEUEto your internal queued state. - Map
in_progress,processingandIN_PROGRESSto running. - Map
completedandCOMPLETEDto done,failedandFAILEDto failed. - Map
cancelled,canceledandCANCELEDto canceled.
Why the result route is separate
GET /v1/jobs/{id}/result is only for completed jobs and answers 409 job_not_completed otherwise, so read the failure off the job record, not off the result route. On failure, read GET /v1/jobs/{id} and its job.error, which carries the public category and next action.
Where this goes wrong in practice
The typical bug is a dashboard that counts jobs by status string. It works for a month on one route, then a second route is added and a bucket named cancelled appears next to one named canceled. Counts drift and nobody notices.
A normalizer at the boundary fixes that, and so does a rule that no code outside it reads a raw status. Add a test that feeds one value from each vocabulary through it.
Limits
The docs do not say whether the queue-shaped field will gain values, so keep a default branch in your normalizer for any unknown string. Treat unknown as non-terminal unless terminal says otherwise.
Sources
Related posts
More in Developers
- Quota job error vs 402 insufficient_credits: where each appears
A 402 insufficient_credits means the submit was refused; a quota job category means an accepted job later failed. How to tell them apart and what to do next.
- Read a completed Sume /v1/videos poll response, field by field
What id, generation_id, polling_url, status, unsigned_urls and usage.cost mean on a finished Sume video job, and which to store.
- Read capabilities from the Video Router models list before you pin
GET /v1/video-router/models returns capabilities per model. Why the docs say to read them instead of assuming one envelope, and what differs by model.
- Read job events for a stuck narration take: a snapshot, not a stream
GET /v1/jobs/:id/events lists job.created, queued, started, generation.submitted and the terminal event. A pull snapshot for debugging a TTS or music take.
Written by Sume