TypeScript SDK: createVideoGeneration, then poll for 'cancelled'

The @sume-com/sdk video functions return {data, error, response} and never throw. An 18-line loop passes an Idempotency-Key and handles the British spelling.

4 min readSume
All posts

Call createVideoGeneration with a body and an Idempotency-Key header, then poll getVideoGeneration and treat completed as success and failed or cancelled as the end. The generated functions in @sume-com/sdk resolve to { data, error, response } and do not throw on an HTTP error, so check error yourself. The /v1/videos route spells it cancelled, while /v1/jobs uses canceled.

Which function does what

Four generated functions cover the video route. They take a client from createSumeClient, which sends the key as x-api-key; never add an Authorization header as well.

SDK video functions (@sume-com/sdk 0.2.0 source, read 2026-10-07)
FunctionRouteUse
createVideoGenerationPOST /v1/videosSubmit, 202
getVideoGenerationGET /v1/videos/{id}Poll status
getVideoGenerationContentGET /v1/videos/{id}/contentDownload; 409 job_not_completed or job_failed
listVideoGenerationModelsGET /v1/videos/modelsRead capabilities

The loop

It type-checks against the SDK source. The header is passed through headers, which the SDK's retry rule looks for: it retries a POST on 408, 429 or 5xx only when an Idempotency-Key is present. The 15-second delay is a placeholder; a real worker should back off and cap the total wait.

import { createSumeClient, createVideoGeneration, getVideoGeneration } from "/tmp/sume-com-blog-trend-100/packages/sdk/src/index.ts";

const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });

const created = await createVideoGeneration({
  client,
  body: { model: "wan-3.0", prompt: "a kite over a salt flat", duration: 10, resolution: "720p", aspect_ratio: "16:9" },
  headers: { "Idempotency-Key": "kite-0001" },
});
if (created.error || !created.data) throw new Error(`submit failed: ${created.response?.status}`);

for (;;) {
  await new Promise((r) => setTimeout(r, 15_000));
  const polled = await getVideoGeneration({ client, path: { id: created.data.id } });
  const status = polled.data?.status;
  if (status === "completed") break;
  if (status === "failed" || status === "cancelled") throw new Error(`ended as ${status}`);
}

Other choices

The 0.2.0 npm package does not ship a waitForJob helper, as a linked post explains, so a polling loop like this one is the thing to write yourself.

The loop above is a sketch: it has no timeout and no AbortSignal. Add both before it runs unattended.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume