waitForJob for a 30-second Seedance clip: TypeScript SDK example

With @sume-com/sdk, submit a seedance-2.5 job through generateVideoRouter and let waitForJob poll it for up to 20 minutes. Idempotency key, onStatus, errors.

5 min readSume
All posts

Call generateVideoRouter with mode: "async" and an idempotency key, then pass the returned job id to waitForJob from @sume-com/sdk. The helper polls for you, with a 20-minute default timeout, a 2-second floor on the interval, and a server-suggested delay when next_poll_after_seconds asks for more.

Generated operations resolve with { data, error, response } and do not throw on an API error, so check error before you read data.

What the helper does

waitForJob resolves with the job record from /v1/jobs/:id, for any terminal status. A failed job is a result you read, not an exception. It throws SumeJobTimeoutError if the timeout wins, and SumeJobRequestError if a status read fails for good. Both carry the job id.

Transient 429 and 5xx reads do not end the wait. The job still runs and bills, so the helper backs off and polls again.

waitForJob defaults and behavior (read 2026-10-07)
OptionDefaultNote
timeout20 minutesThrows SumeJobTimeoutError, job keeps running
pollInterval2 secondsA floor, server hint wins when longer
signalnoneAborts the wait
onStatusnoneCalled on every status read

Run it

Install with npm install @sume-com/sdk. The package needs fetch and WebCrypto, so Node 18 or later works. Save the file as clip.mjs.

import { createSumeClient, generateVideoRouter, waitForJob } from "@sume-com/sdk";

const client = createSumeClient({ apiKey: process.env.SUME_API_KEY });
const { data: sub, error } = await generateVideoRouter({
  client,
  headers: { "idempotency-key": "mug-orbit-ts-001" },
  body: {
    model: "seedance-2.5",
    prompt: "Slow orbit around a ceramic mug on a desk",
    duration: 30,
    resolution: "720p",
    mode: "async",
  },
});
if (error) throw new Error(JSON.stringify(error));

const job = await waitForJob(sub.data.request_id, {
  client,
  onStatus: (status) => console.log(status),
});
console.log(job.status, job.result?.artifacts?.[0]?.url);

Two cautions

The client sends x-api-key only. If a wrapper adds an Authorization header too, the API rejects the request with 401. Keep the key on the server: there is no browser-safe variant.

After a timeout, store the job id. Read it later with getApiJob, or cancel it with cancelApiJob before generation starts.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume