Sume /v1/videos says cancelled, /v1/jobs says canceled: guard it
The /v1/videos poll uses pending, in_progress and cancelled; /v1/jobs uses queued, processing and canceled. A small normalizer keeps your poller from hanging.

Two routes, two vocabularies
Sume exposes the same video job two ways. POST /v1/videos is shaped like the OpenRouter video API, with a polling_url and its own poll statuses. The same job is also visible at GET /v1/jobs/{id}/status with Sume's job vocabulary. Both are correct; they just do not spell things alike.
The trap is a poll loop whose terminal set came from one page and whose input came from the other. A job that ends canceled but is looked up as cancelled would never match and the loop would run to its deadline.
The two vocabularies (read 2026-10-05)
| Meaning | /v1/videos poll | /v1/jobs status |
|---|---|---|
| Accepted, waiting | pending | queued |
| Running | in_progress | processing |
| Done | completed | completed |
| Error | failed | failed |
| Stopped by request | cancelled | canceled |
A normalizer
Map every spelling to the jobs vocabulary at the edge and test against that. Run this as is:
const MAP = {
pending: "queued", in_progress: "processing",
cancelled: "canceled", canceled: "canceled",
queued: "queued", processing: "processing",
completed: "completed", failed: "failed",
};
export const normalize = (s) => {
const v = MAP[s];
if (!v) throw new Error("unknown Sume status: " + s);
return v;
};
export const isTerminal = (s) => ["completed", "failed", "canceled"].includes(normalize(s));
console.log(isTerminal("cancelled"), isTerminal("in_progress"));Why throw on unknown
An unknown status should stop the loop loudly, not spin. Sume's docs also mention a queue-shaped field (IN_QUEUE, IN_PROGRESS, COMPLETED) on the jobs status envelope; it maps one to one onto sume_status, so pick one field and stay on it.
On a timeout, do not resubmit the paid request. The job keeps running and billing; read it again from the polling URL.
Sources
Related posts
More in Developers
- Sume /v1/videos says pending, /v1/jobs says queued: map both
/v1/videos uses pending and in_progress; /v1/jobs uses queued and processing; cancelled vs canceled. A mapping table and a JS helper to normalize both.
- Sume webhook and status poll race: never move a job row backwards
A late poll can say processing after the webhook already said completed. A rank-guarded SQLite update keeps a Sume job row from going backwards.
- Sume webhook five-minute replay window: reject stale deliveries
Sume signs timestamp.raw_body and advises a five-minute replay tolerance. Reject stale timestamps, refuse an empty secret, and keep job_id as the dedupe key.
- Sume webhook retried 10 times and stopped: recover the job anyway
Sume tries a webhook up to 10 times, 30 seconds apart, 10s timeout each. After that the job is still terminal. Poll status_url or call redeliver to recover.
Written by Sume