Poll a Sume job from a Node script: deadline, backoff and exit code
A short Node script polls a Sume job with getApiJobStatus, honors next_poll_after_seconds, and gives up at a deadline without cancelling the job.

Run the script with a job id and it polls getApiJobStatus until the job is terminal. It waits for the time that Sume asks for in next_poll_after_seconds, and uses its own doubling backoff, capped at 30 seconds, when the field is missing.
import { createSumeClient, getApiJobStatus } from "@sume-com/sdk";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY });
export async function waitForJob(id, { timeoutMs = 20 * 60_000 } = {}) {
const start = Date.now();
let backoff = 2;
for (;;) {
const { data, error } = await getApiJobStatus({ client, path: { id } });
if (error) throw new Error(`status read failed: ${JSON.stringify(error)}`);
if (data.terminal) return data;
if (Date.now() - start > timeoutMs) {
throw new Error(`job ${id} is ${data.sume_status}; it keeps running`);
}
const seconds = data.next_poll_after_seconds ?? backoff;
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
backoff = Math.min(backoff * 2, 30);
}
}
const job = await waitForJob(process.argv[2]);
console.log(job.sume_status);How to run it
Set SUME_API_KEY, install @sume-com/sdk, and run node poll.mjs <job_id>. It prints the final sume_status. On a deadline it throws and says the job keeps running: stopping the loop does not cancel anything on Sume's side.
Why it is written this way
The table lists the choices in the code.
| Choice | Reason from the docs |
|---|---|
Stop on terminal | The job envelope carries terminal; result_ready says when to fetch the result |
Use next_poll_after_seconds | The docs say to obey it when present |
| Throw on a failed status read | Generated operations resolve with error, they do not throw |
| Do not cancel at the deadline | A job is durable; cancel only on purpose with the cancel route |
Failed jobs return
The loop treats completed, failed and canceled all as terminal. Read sume_status after it returns; a failed job returns normally and carries a public error, so do not assume success.
Next step
After a completed job, fetch the output from result_url when result_ready is true. If you prefer to be told, use a signed webhook and keep this loop as the backup.
Sources
Related posts
More in Developers
- Poll hundreds of AI jobs without a thundering herd: jitter and budgets
Poll many Sume jobs without synchronized bursts: jitter, next_poll_after_seconds, per-plan read budgets, and the math on how much polling a plan can absorb.
- Polling 200 video jobs every 30 s is 400 calls a minute: do this
A poll loop copied to Sume's 30 s example turns 200 open jobs into 400 status calls a minute. Use next_poll_after_seconds, backoff, or a webhook plus sweep.
- Port a Kling 3 request to Sume motion control: three fields to remove
Sume Kling 3.0 Motion Control has a strict body. Moving from a Video Router kling-3 request means dropping model and reference urls and adding two fields.
- Portuguese speech to text API: Sume STT language_code pt or pt-BR
Transcribe Portuguese audio with Sume STT using language_code pt or pt-BR, then check the reported language and word times. $0.01 per audio minute.
Written by Sume