Developers
Building on the Sume API: keys and hosts, jobs and runs, polling, webhooks, idempotency, errors and rate limits, the SDK, the CLI, and MCP auth.
Start with Sume API quickstart: your first video generation call in five steps

Go client for a Sume bulk queue: transient polls and exit status
Create a Sume bulk queue from Go, poll the status_url with a doubling gap, treat 429 and 503 as transient, and exit 1 on failed items. Standard library only.

URL or QR code in an AI avatar video: say it, caption it, or link it
An avatar clip cannot reliably carry a QR code or a long URL. Three Sume-supported options: spoken words, authored caption cues, or the text beside the video.

unittest the spreadsheet-row to Sume bulk item builder, no network
A pure function that turns a spreadsheet row into a Sume bulk item, with four unittest cases for trimming, price format, a spend cap in range and blank SKUs.

Cancel a Format run: cancel_effect canceled vs no_op, and the bill
Cancel is idempotent. cancel_effect says canceled or no_op, a canceled run never sends a webhook, and generation that finished is still billed.

Retiring a webhook endpoint: Sume runs already carrying it still POST
Any run created with a webhook_url can POST when it ends, even after you decommission the endpoint. Retries run 10 times, and the receipt holds the real result.

A job id is not a run id: poll image and video generation via /v1/jobs
Image and video generate routes create jobs, not runs. Poll GET /v1/jobs/:id/status until terminal is true. waitForRun is for run ids only.

Node 22 script: create a Sume bulk queue and poll it to the end
Dependency-free Node 22 ESM script: POST a bulk queue from items.json, back off the poll, survive 429 and 503, and exit non-zero when any item failed.

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.

Bash: split a TSV into 100-row Sume bulk queues with jq and curl
A short shell script that cuts a product TSV into 100-row chunks, builds each bulk body with jq, and posts it under a chunk-named idempotency key.

Transcribe a file from your own bucket: what Sume STT audio_url needs
Sume speech-to-text takes a public HTTPS audio_url, preferably on media.sume.com. How to get a private recording ready, and what a neighbouring API rejects.

Sweep Format runs for failed webhook deliveries, then redeliver
Sweep in Python: read each run's webhook_delivery, redeliver only failed or exhausted ones, and leave the rest alone. Uses formats:read, formats:write.

Format run cap headroom: usage.cap limit, counted and remaining
usage.cap on a run receipt splits the spend-cap check into limit, counted and remaining USD micros. Read it to see how close a run is to failing.

Route Sume run webhooks by event: format, action and agent terminal
Run webhooks use one terminal event per family: action.run.terminal, format.run.terminal, agent.run.terminal. Route on event, then branch on outcome.

Format run stuck on processing: stalled or slow? Read events_url
A Format run can show processing for a long time. The last at value on events_url is the progress clock: if it stops moving for minutes, the run is stalled.

Omni draft grid: four 360p variants, then one final. What it costs
Google's Draft Room idea, run through the Sume API: four 8-second 360p drafts that change one thing each, then a 1080p final. Total $2.70, with a script.

Cut hold music from a call recording before STT: one concat job
Drop a hold-music stretch with one Sume timeline audio concat job that reuses the file twice via source_in and duration, then send the result to STT.

Sume media tools: which wait for a 200 and which always return 202
Video inspect defaults to sync; trim, filter, detach, compose and timeline to async; frames is always 202. The 30 s wait and where each result is read.

Caption design colors: hex, rgb(), rgba() or transparent only
Sume caption design colors take hex, rgb(), rgba() or transparent. Other CSS syntax is rejected at request time, so a bad color costs nothing.

Sume status vocab: a job is completed, a resource is ready
Sume lists three status vocabularies: job, resource, webhook delivery. Only jobs say completed; resources say ready, so a check on the wrong one never matches.

SHA-256 the batch body into the Sume idempotency key for bulk chunks
Derive each bulk chunk's Idempotency-Key from a hash of its items so replays reuse the queue and edited rows get a new key instead of a 409 conflict.

GET result_url returns 409 run_not_completed: poll status_url first
A 409 run_not_completed from result_url means the Format run is not terminal. Read details.status, poll status_url with backoff, then fetch the result.

TypeScript union for Sume bulk queue items, checked with Deno
Model queue items by status so run_id and error are typed per case: null while queued, null for a child that never started, and an exhaustive switch.

Chapter timestamps for narrated audio from concat segment offsets
Join one TTS file per chapter with timeline audio concat, then turn the returned segments[] start offsets into mm:ss chapter lines with a short Python script.

Alt text for a 30-image gallery in one Sume Agent Completion
One Agent Completion call can take up to 30 images and return an alts array under an object schema. Python stdlib script with the cap, poll and limits.

Add an object to a set spot in a photo: box to words in Python
Sume has no bounding-box field. Turn a 0-1000 box into placement words for an Ideogram 4.5 edit, and into pixels for a mask, with a short Python helper.

Idempotency-Key from an order id and version, never a fresh uuid
A fresh uuid per request makes Idempotency-Key do nothing. Derive it from the order id plus a version you bump only to re-run. Scope: one Format, 255 chars.

List every Format run: no GET /v1/format-runs, page per Format
GET /v1/format-runs does not exist. List runs per Format with limit, next_cursor and has_more, or keep your own index of the data.id you stored at create.

sume jobs cancel needs --confirm-submit, and only queued jobs cancel
Sume CLI cancel is a write: sume jobs cancel <job_id> --confirm-submit. It works only before generation starts; later: 409 job_generation_already_started.

Cancel a wrong video job after a Sora port: only before it starts
Ported prompts on the wrong model burn money. Sume cancels a video job only before generation starts; later you get 409 job_generation_already_started.

jq one-liner: export Sume bulk queue items to CSV by index
Turn the bulk queue receipt from a curl poll into CSV rows of index, status, run_id and error code with jq, then paste them next to your SKU column.

Set your Format run timeout from expires_at, not a guess
A non-terminal Format run receipt carries expires_at, the deadline after which Sume force-finalizes it as failed. Derive your wait from it and read queue.state.

Python preflight for a Sume bulk body: count, keys, bytes, caps
Check a Sume bulk-run body offline before the POST: 1 to 100 items, concurrency 1 to 16, 64 input keys, 2 MiB input, 4 MiB body and a spend cap in range.

Check an Omni edit's length with video-inspect before a timeline join
An edit should follow the source length. Confirm it with a probe-only video-inspect call before the clip goes into a Timeline render, with a Python read.

Check an Omni edit kept the rest of the clip: video-frames pairs
Compare stills from the source and the edited clip at the same timestamps with video-frames on Sume. A script that submits both extracts, plus what to look for.

Validate Wan 3.0 reference limits in Python before submitting
wan-3.0 takes 10 images, 5 videos (15 s total, 16 fps minimum) and 5 audios (15 s total). A short Python check catches an over-limit manifest early.

mask_url on ChatGPT Image 2: not listed, only the 2.5 rows take it
Sume lists mask_url only on ChatGPT Image 2.5 Flare and Sunburst. Sending it to ChatGPT Image 2 is rejected. What to do for a masked edit on the older row.

Omni Flash 4K, 10 seconds: a webhook-mode /v1/videos request body
One curl body for gemini-omni-flash-1.1 at 4K, 16:9, 10 seconds with audio and a callback_url, plus what the docs say the submit reserves and what it cannot.

Download a Sume video with curl: send the key to /content
The docs' curl call for GET /v1/videos/{id}/content sends the API key and follows redirects. A short script saves the MP4 and prints the 409 reason on failure.

Luma Ray3.2 API: the docs page still lists ray-2 and ray-flash-2
Luma says the Ray3.2 API is live. The docs page I read on Oct 7 lists only ray-flash-2 and ray-2. How to check before you code, and Sume's gap.

Gemini Omni Flash edit on Sume: a Python preflight for bad fields
A 29-line Python preflight for Sume video-router edit requests on gemini-omni-flash-1.1: catches the fields the docs say it rejects before you pay for a job.

Python CI guard: fail the build on retired Veo, Imagen, Sora ids
Twenty-three lines of standard-library Python scan a repo for Veo 2/3, Imagen 4 and sora-2 ids with their shutdown dates, and exit 1 when one is found.

Python urllib: POST /v1/images, 200 or 202, after Imagen 4 Fast
imagen-4.0-fast-generate-001 ended Aug 17. A stdlib Python call to Sume's image route that reads the status code, then polls the job when the answer is 202.

Codex 0.160.0 MCP status for one server: confirm Sume with mcp_health
Codex 0.160.0 adds single-server MCP status discovery with thread connection reuse. Confirm the Sume session itself with mcp_health and tools_list.

Cursor project .cursor/mcp.json or global ~/.cursor/mcp.json for Sume?
Put a URL-only Sume entry in .cursor/mcp.json to share it with a repo, and keep any API key in an env variable in the global file, not in git.

Deno: time out a Sume video submit, then retry with the same key
A fetch that times out may still have created a job. A 20-line Deno submit retries only 408, 429, 5xx and timeouts, always with one Idempotency-Key.

HappyHorse 1.1's five aspect ratios vs the Sume video catalog
HappyHorse 1.1 on Cloudflare takes 16:9, 9:16, 1:1, 4:3 and 3:4. Which Sume video models cover all five, and which do not.

Python guard: refuse a Short over 180 s before the render bills
A 20-line Python check that blocks a Shorts render over 180 seconds and prices the Sume Timeline minutes (10 cents each) before you submit.

Python urllib: honor retry-after on a Sume 429, back off without it
A stdlib retry for GET calls that sleeps for retry-after when the 429 carries it and for a capped exponential delay when it does not, with jitter.