waitForRun or waitForJob? Pick by which Sume endpoint made the id
A Sume run id cannot be read as a job id. Which create endpoint made your id decides waitForRun or waitForJob, with a TypeScript example of each.

Use waitForJob when the id came from a generation endpoint such as POST /v1/image-1.0/generate or POST /v1/video-1.0/generate. Use waitForRun when the id came from a Format, Action, or Agent run. Sume says you cannot use a job id as a run id, or a run id as a job id, so a wrong pick shows up as a failed read, not as a slow one.
Both helpers ship in @sume-com/sdk 0.2.0. They look alike, but they poll different URLs and they take different options.
Decide by the create call
The table is from the Waiting for runs and jobs page, read 2026-10-09.
| Id came from | Surface | Poll path | Helper | Default timeout |
|---|---|---|---|---|
POST /v1/formats/.../runs | Format run | /v1/format-runs/{id} | waitForRun with family: "format" | 10 minutes |
| Action run | Action run | /v1/action-runs/{id} | waitForRun with family: "action" | 10 minutes |
| Agent run | Agent run | /v1/agent-runs/{id} | waitForRun with family: "agent" | 10 minutes |
POST /v1/image-1.0/generate, /v1/video-1.0/generate, Avatar routes | Generation job | /v1/jobs/{id} | waitForJob | 20 minutes |
subscribeFormatRun | Format run (create and wait) | /v1/format-runs/{id} | The helper itself | 20 minutes |
What differs in the code
family is required on waitForRun and the helper cannot infer it, because a run id does not show its surface. waitForJob has no such option. It also treats pollInterval as a floor: when next_poll_after_seconds in the status payload asks for longer, that wins. Pass client to both, since the module default has no base URL or key.
import { createSumeClient, generateVideoV1, waitForJob, waitForRun } from "@sume-com/sdk";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });
// Generation job: the id is request_id from the submit response.
const { data, error } = await generateVideoV1({
client,
headers: { "idempotency-key": crypto.randomUUID() },
body: { prompt: "Slow push-in on a ceramic mug", mode: "async" },
});
if (error) throw new Error(JSON.stringify(error));
const job = await waitForJob(data!.data.request_id, { client });
console.log(job.status, job.result.artifacts);
// Format run: you must say which family the id belongs to.
declare const runId: string;
const run = await waitForRun(runId, { client, family: "format" });
console.log(run.status, run.primary_output_url);What each one returns on failure
Neither helper treats a terminal failure as an exception. waitForJob resolves with the record from /v1/jobs/{id}, not from /result, because for failed and canceled jobs /result answers 409 job_not_completed and there would be nothing to hand back. Read status, result, and error from the record.
The helpers do throw on timeouts and request errors: SumeRunTimeoutError and SumeRunRequestError for runs, SumeJobTimeoutError and SumeJobRequestError for jobs. A timeout does not cancel the work. The job keeps running and keeps billing, so store the id, read it again later, or cancel it.
A quick check helps when you inherit code with a bare id. Look at where it was stored: an id saved from a /v1/jobs response is a job id, and an id saved from a *-runs response is a run id. If you cannot tell, read the id from each surface once, and expect a not-found from the wrong one. Do not guess a family in production code; keep the family next to the id in your own table.
If you can skip the wait, do. Both the runs page and the jobs page recommend webhooks for production, and the SDK has no event stream today: subscribe there means create, then poll.
Sources
Related posts
More in Developers
- Wan 3.0 says 30 fps MP4: check your Sume download with ffprobe
Alibaba says Wan 3.0 outputs 30 fps MP4. Sume's docs do not repeat it, so probe your download. A Python ffprobe script for fps, size, length and audio.
- Wan 3.0 duration -1 (smart length) vs Sume's whole seconds
Alibaba lets Wan 3.0 pick the length with duration -1. Sume's duration is a whole number from 2 to 30 for wan-3.0, so choose it before you pay for it.
- Wan 3.0 'Image 1' and 'Audio 1' prompt labels on Sume
Alibaba says to name references 'Image 1', 'Video 1', 'Audio 1' in the prompt. How Sume's input_references order maps to those labels, and a cheap test.
- Wan 3.0 reference file limits: pixels, ratio, MB and fps preflight
Alibaba lists per-file limits for Wan 3.0 reference images, videos and audio. A runnable Python check to run before you submit them to Sume.
Written by Sume