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

Bun 1.4.3 ERR_PROXY_TUNNEL: is it a Sume error or your proxy?
Bun 1.4.3 rejects fetch with ERR_PROXY_TUNNEL on a failed CONNECT. A Sume error always carries error.request_id; use it to tell the two apart.

Bun 1.4.3 fake timers: test a Sume poll loop with request timeouts
Bun 1.4.3 fixes advanceTimersByTime spinning with AbortSignal.timeout. Test a Sume job poll loop that honors next_poll_after_seconds without real waits.

Bun 1.4.3 fetch Content-Length check: send a Sume JSON body as bytes
Bun 1.4.3 rejects fetch when a declared Content-Length mismatches a stream body. For a Sume submit, skip the header and pass the encoded JSON.

Claude Code hook: swap Sume's download URL for a saved file
A PostToolUse hook with updatedToolOutput can fetch the signed link from assets_download_url, save the file, and show Claude only the local path.

nginx proxy_read_timeout is 60s, but Sume gives up at 10s
nginx waits up to 60 seconds for your app by default, yet a Sume webhook attempt times out at 10. Why raising proxy timeouts does not help and what to do.

Page on-call when a Sume webhook is exhausted: PagerDuty dedup_key
Send a PagerDuty Events API v2 trigger when Sume gives up on a webhook, using the job id as dedup_key so retries and redelivers never page twice.

Terraform and secrets: keep the Sume API key out of state
Terraform's sensitive flag hides a value from logs but still writes it to state. How to handle a Sume API key and webhook signing secret without that leak.

Compose 400: stack and overlay layout keys cannot be mixed
Fix compose_stack_takes_no_overlay_layout and its mirror: pick stack or overlay as operation, then send only the layout keys that belong to it.

Timeline 400: first slot must start at 0 and take no transition
Fix timeline_must_start_at_zero and transition_on_first_segment: start video[0] at 0, use source_in to skip, put fades on slot two, then plan for free.

video_inspect 400: frames program and transcribe flag errors
Fix video_inspect_frames_program_conflict, _required and video_inspect_transcribe_required: send at or fps, and transcribe true with its language options.

IVR phone menu prompts with TTS: 8 kHz mu-law WAV and cost per prompt
Make phone-menu prompts as 8 kHz mu-law or A-law WAV with Sume TTS. A 20-prompt menu bills 20 cents because each short job hits the 1-cent minimum.

Egress firewall for a Claude agent in CI: Sume hosts to allow
Claude Agent SDK v0.2.164 hardens CI egress firewalls. Which Sume hosts a render job needs: api.sume.com, mcp.sume.com and media.sume.com, and what each is for.

Omni takes JPEG and PNG: gate each reference image URL in Python
Google lists JPEG and PNG for Gemini Omni image input. Check each reference_image_urls entry with a HEAD request, then submit the clean list through Sume.

Vercel AI SDK chunkMs timeouts and a 55 s Sume jobs_wait
ai@7.0.136 stops chunkMs and firstChunkMs when the model response ends. stepMs still covers the step, so size it for a Sume jobs_wait slice of up to 55 s.

claude -p --permission-prompts none: Sume tools in CI
With --permission-prompts none, prompts nobody can answer are denied. Which Sume tools still run? Read-only OAuth ones do; paid ones need mcp:write.

Lint a Video Router request offline: reference limits in Python
Check reference_image_urls (10), reference_video_urls (3), reference_audio_urls (1-5) and the video_url rule in Python before POST /v1/video-router/generate.

Claude Code remote MCP backoff up to 30 s: retrying Sume safely
Headless Claude Code now backs off up to 30 s after remote MCP drops. A retried paid Sume call needs the same idempotency_key or you may pay twice.

MCP tools/list repeating a cursor: Claude Code 2.1.295 and Sume
Claude Code 2.1.295 stops asking a server for the same tools page up to 20 times. Sume's tools/list returns one page with no nextCursor, so it never loops.

Pick a Sume video model in code: audio refs, 1080p, 20 seconds
Filter GET /v1/video-router/models on reference_audios, resolutions and duration_seconds, then submit the survivor with reference_audio_urls (up to five).

Count queued and processing jobs with GET /v1/jobs before a wave
Page GET /v1/jobs with status=queued and status=processing, subtract from concurrency_limit, and submit only that many Seedance 2.5 or Omni clips.

claude -p --max-budget-usd does not cap Sume renders
Claude Code's --max-budget-usd is a client-side estimate of API spend in print mode. Pair it with max_spend_usd on every paid Sume call and leave headroom.

Claude Code 2.1.288: MCP calls that ran twice, and paid Sume calls
2.1.288 fixed MCP tool calls sometimes running twice when a remote result was over 16 MB or unparsable. Why every paid Sume call needs an idempotency_key.

Claude Code hooks on Sume tool calls: check the top-level guards
A Claude Code hook that gates paid Sume MCP calls should read the top-level idempotency_key, dry_run and max_spend_usd, and deny when input is unreadable.

Send a signed webhook.test with POST /v1/webhooks/test-deliveries
Point POST /v1/webhooks/test-deliveries at a new HTTPS endpoint to get a signed webhook.test before any video job runs, then check the sume-v1 signature.

Seedance 2.5 in 16:9, 9:16 and 1:1: one idempotency key per ratio
Fan one prompt out to three aspect ratios on /v1/videos, derive a separate Idempotency-Key for each ratio, and rerun the script without paying twice.

HappyHorse 1.1 [Image 1] tags vs Sume's <IMAGE_REF_0> in prompts
HappyHorse reference-to-video counts images from [Image 1]; Sume's Omni counts from <IMAGE_REF_0>. How to map a prompt without an off-by-one.

Omni Flash defaults to 720p and 16:9: set both on every request
Google's Omni docs default to 720p and 16:9; Sume's Auto defaults to 720p and 8 seconds. Why to send resolution, ratio and duration every time, with prices.

Stop a Seedance 2.5 batch on SumeInsufficientCreditsError
Submit a batch with createVideoGeneration and one idempotency key per item. On a 402, stop the loop, top up, and rerun the same script without paying twice.

Claude Code closes ws MCP messages over 16 MiB: Sume sends URLs
Claude Code 2.1.295 closes a websocket MCP connection on a message over 16 MiB. Sume hosted MCP returns media.sume.com URLs for results, not file bytes.

Find exhausted Sume webhook deliveries and redeliver them in Python
Page GET /v1/jobs for completed and failed jobs, keep webhook_delivery.status exhausted, and call POST /v1/jobs/{id}/webhook/redeliver for each.

Omni reference videos: read Sume capabilities, not Google's note
Google's Omni page says multi-video reference is unsupported; Sume's docs list up to three reference clips. Read the catalog entry before you send them.

claude -p --max-turns exits with an error: Sume job in flight
When --max-turns ends a CI run, a Sume job may still be rendering. Keep the job id in the output, resume with jobs_wait, and never repeat the paid create.

Vidu task states mapped onto Sume job statuses in Python
Map Vidu task states (created, queueing, processing, success, failed) to Sume queued, processing, completed and failed so an old poller keeps working.

MCP tool description length: Claude Code 16,384 vs Sume
Claude Code 2.1.295 raised the tool-search description cut from 2,048 to 16,384 characters. What that means for a Sume MCP connection, and how to check it.

Claude Code 2.1.295 MCP changes: a checklist for Sume
Three MCP changes in Claude Code 2.1.295 (Oct 8) and what each means for a connection to Sume's hosted server. A short table to run through after upgrading.

Resume a Sume job wait after SumeJobTimeoutError in TypeScript
A 30-second Seedance 2.5 clip can outlast one waitForJob call. Call it again with the same job id on timeout or a transient read error. Never resubmit.

Vidu 24-hour and FLUX 3 signed result links: copy the file first
Vidu result URLs last 24 hours and FLUX 3 signed URLs about 2 hours, or about 10 minutes by another line. Stream the Sume clip to disk and keep the job id.

A Sume webhook receiver in a Cloudflare Worker with verifyWebhook
verifyWebhook uses WebCrypto, not node:crypto, so it can run in a Worker. A fetch handler that refuses an empty secret, checks the signature, returns 204.

Sume webhook retries: 10 attempts, 270 seconds of gaps, then poll
How long does Sume keep retrying a job webhook? Ten attempts, a 30 second default gap and a 10 second timeout, worked out in seconds, plus a Python dedupe.

Sume webhook delivery statuses: pending to exhausted, and your move
A Sume job webhook has six delivery states, from pending to exhausted. What each means for your receiver, where to read it, and when to redeliver or poll.

Route Sume job webhooks: handle job.canceled, answer 204 to the rest
Sume sends job.completed, job.failed and job.canceled; run webhooks use another name. A TypeScript router that handles each and returns 204 for the rest.

Verify a Sume webhook in Python with the standard library only
Check the sume-v1 HMAC in Python without a package: raw body, timestamp window, two signatures during rotation, and a refusal of an empty secret. 20 lines.

Express route for a Sume webhook: raw body, verifyWebhook, 204
In Express, express.json() breaks the Sume signature check. Mount express.raw on the webhook route only, call verifyWebhook, and return a fast 2xx. TypeScript.

Sume webhook signature fails: compare the secret fingerprint first
Webhook signature mismatch? Compare x-sume-webhook-secret-fingerprint with the dashboard before touching code. It is the one value safe to paste in a ticket.

Python httpx 429 handler for Sume: retry-after, then ratelimit-reset
A small async Python wrapper for the Sume API that waits on retry-after, falls back to ratelimit-reset, and never retries a POST that lacks an Idempotency-Key.

Sume 415 unsupported_media_type: read details.received_content_type
A 415 from the Sume API means the body was not sent as application/json. Which client defaults cause it, how to read the details field, and the one-line fix.

Fresh Idempotency-Key per proxy call: why a Sume retry bills twice
If your server proxy mints a new Idempotency-Key on every request, a browser retry becomes a second paid Sume job. Forward the client's key instead; TypeScript.

Korean ad with an English brand name: set Sume TTS language to ko
Send a Korean script with language set to ko; the default is English. A brand name in Latin letters is read by the chosen language, so listen and fix it.