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.

If a lip-sync job fails on Sume, is the reserved money refunded?
Yes. Sume reserves the price at admit, captures on completion and refunds on failure. For a 5-second H3 Max lip-sync at 768p the reservation is $0.50.

Verify a Sume job webhook in Python, and refuse an empty secret
A Python verifier for Sume job webhooks: HMAC SHA 256 over timestamp.body, a 5-minute window, rotation-safe, and a hard refusal when the secret is empty.

A one-file Python CLI that replaces a Sora script, on Sume
One argparse script, standard library only: prompt, model, seconds, resolution and aspect flags in, mp4 out, with an idempotency key derived from the arguments.

Video model fallback chain in Python with one key per model
A Python chain that tries Gemini Omni, Wan 3.0 and Seedance 2 on Sume in order, stops on 401 or 402, and uses a separate idempotency key for each model.

Check a callback_url is public HTTPS before you submit a Sume video
Sume's callback_url must be public HTTPS. A Python pre-check rejects http, embedded credentials, unresolvable hosts and private addresses before you pay.

A tiny Node proxy so a browser can order a 4K Omni clip safely
Sume keys are server-side only. A short Node proxy exposes POST and GET routes for one 4K Gemini Omni Flash 1.1 clip, with an Idempotency-Key and pinned fields.

Which login is my agent using? mcp_health auth_source on Sume MCP
Call mcp_health on the hosted Sume server to see the auth source of your session, then tools_list and account_me. Read-only OAuth and API-key sessions differ.

Debug a Sume webhook signature mismatch offline: a diagnosis script
Saved a failing Sume webhook? This Python script tells you if it was a stale timestamp, an empty secret, a mutated body or the wrong secret. Self-test included.

MAI Flash 429 and spend limits vs Sume queued jobs and idempotency
OpenRouter's MAI-Voice-2.1-Flash returns 429 on rate limits and has spend limits. Sume accepts jobs into queued status. See an idempotent double submit.

Use Decimal, not float, to reconcile Sume video costs to the cent
Sume bills list x 1.25 and rounds each video job up to the cent. Python Decimal with ROUND_CEILING reproduces the bill exactly, where floats drift by a cent.

MCP_TIMEOUT is a 30-second startup wait, not a Sume job limit
In claude -p, MCP_TIMEOUT is the wait for MCP servers to connect, 30 seconds by default. It does not limit a video job; Sume's jobs_wait does that.

Sume CLI quickstart: create an avatar video, follow it with jobs
Install the Sume CLI, log in, create a paid avatar video, and follow the job with sume jobs status, result and events. Why Image and Video have no CLI command.

How many jobs_wait calls does a long video job need? 50 s slices
At the default 50 s slice a 10-minute render needs up to 12 jobs_wait calls, at the 55 s cap up to 11. Write the call budget into the agent instruction.

Transcribe 1,000 twenty-second clips: pack 20 per file, then run STT
1,000 clips of 20 s cost $10.00 on Sume STT if billed one minute each, but $4.00 if you pack 20 clips per file with Timeline audio.

Submit 60 Gemini Omni 4K jobs on a Pro plan: pace in waves of 24
A Pro workspace holds 24 accepted generation jobs (4 running, 20 queued). Pace 60 Omni 4K submits in waves with asyncio and retry queue_full safely.

Port a reference-image video prompt to Sume with <IMAGE_REF_0> tags
How to move a prompt that leaned on input images to Sume: when to use image_url as the first frame, and when to name each reference with IMAGE_REF tags.

Avatar create 400: removed name and file fields and their replacements
Old avatar model-run requests that send name or file return 400 with details.fields listing replacements: avatar_handle and input.image_url. Fix both at once.

Avatar photo 400 unsupported_image_type: PNG, JPEG, WebP, GIF only
Sume's avatar photo preflight accepts four image content types. An HTML page, AVIF or HEIC answer returns 400 unsupported_image_type and no job is created.

Avatar photo 413 image_too_large: 16,384 px and 100 MP limits
A Sume avatar photo over 16,384 px on a side, or over 100,000,000 pixels, returns 413 image_too_large before any job exists. Downscale it first.

Avatar photo image_not_fetchable: 404, timeouts and the 15 s limit
Sume gives an avatar photo host 15 seconds for fetch and body read. A non-2xx status or a timeout returns 400 image_not_fetchable. How to fix it.

Avatar photo 400 invalid_image: under 64 px or a 6:1 aspect ratio
Sume rejects an avatar photo that is not decodable, is under 64 px on a side, or is more than 6:1. The 400 invalid_image error reports width, height and reason.

Handle avatar photo errors in Python: read details.suggested_input
A stdlib Python handler for Sume avatar photo errors: branch on error code, print the suggested input, and never echo a private URL. Refuses an empty API key.

Avatar photo URL redirects: five hops, then image_not_fetchable
Sume follows up to five redirects for an avatar photo and re-checks every hop. A redirect to http or a private address returns 400 image_not_fetchable.

Avatar photo URL rejected: http, a port, a password or localhost
Sume refuses an avatar image_url that is not public HTTPS: no http, port, user:password or localhost. It fails on validation, with no fetch. Fix and retry.

Avatar video 404 "Avatar was not found": handle from another workspace
A talking-video request with an unknown handle, or one from another workspace, returns 404 not_found and no job. Check the handle and the key's workspace.

Detect a clip's language before dubbing with Sume STT
Run Sume STT with no language hint and read language_code and language_probability from the result. A short Python check that gates a dub on a confident answer.

GPT Image 2.5 cost calculator in Python: token grid, checked vs Sume
A short Python function reproduces Sume's GPT Image 2.5 prices from the token grid, $0.0074 at low and $0.2635 at max for 1024x1024. Table to check it.

Idempotency-Key per shot: rerun one failed AI video shot in Python
One key per shot, derived from project, shot number and revision: a retry returns the same Sume job, a changed prompt gets a new key. Python key helper inside.

Omni Flash 3-second video reference: trim a clip's last 3 s first
Gemini Omni Flash 1.1 on Sume takes up to 3 video references, each at most 3 s. Trim the tail of a finished clip for $0.02, then cite it as VIDEO_REF_0.

One Sume probe, eight platform limits: a Python preflight
Check one video inspect probe against Truth Social, Odysee, ArtStation, Linktree, Spotlight, Reels, TikTok API and Shorts limits in under 30 lines of Python.

Stitch three STT chunks: add each range start to word times
Sume STT times count from each chunk's own start, so add the chunk's range start to every word and sentence. A short Python function that does it.

Transcribe a MAI-Voice-2.1 clip with Sume STT: Python audio_url run
Host a MAI-Voice-2.1 or Flash clip at a public HTTPS URL and Sume STT returns text, word times and sentences for 1 cent a minute. A 25-line Python run.

Avatar video 400: script must include at least one word
A Sume talking-video request with an empty or whitespace-only script returns 400 invalid_request, with no job or ledger entry. Guard blank template fields.

Derive a Sume idempotency key from tenant, order, Format slug, version
Hash stable ids, not a random UUID, so a retry reuses the key. A failed run needs a new key, and a changed body with the same key returns 409.

job_id, request_id, Idempotency-Key: which one goes in which column
Your Idempotency-Key is the unique key before submit, job_id or run_id is the poll key, and request_id dedupes webhooks and goes into support tickets.

Move from polling to Sume webhooks in three steps, keeping the poll
Add webhook_url to submits, verify sume-v1 signatures, dedupe on job_id, and keep a slow poll for canceled and skipped runs. Roll it out one route at a time.

Python Sume webhook handler that accepts the webhook.test event
Verify the sume-v1 signature over timestamp.body, refuse an empty secret, and accept webhook.test, which has no job_id. Stdlib Python, runs offline.

Read Sume rate limit headers with curl: remaining, reset, retry-after
Run curl -D - on any /v1 route to read ratelimit-limit, ratelimit-remaining, ratelimit-reset, and retry-after on a 429. Anonymous reads are 4x Free writes.

Submit Sume jobs from Go with a bounded pool and idempotency keys
Bound a Go worker pool to your workspace in-flight headroom, send a stable Idempotency-Key per item, and stop treating a full queue as a crash. Stdlib only.

Sume SDK error classes: HTTP status, class and action in TypeScript
Map 401, 402, 403, 404, 409, 429 and 5xx to the SumeApiError subclass and the right action, and read code, requestId, retryable and retryAfterSeconds.

Sume SDK retries: which requests it repeats and how long it waits
createSumeClient retries 408, 429 and 5xx up to maxRetries (default 2), honours retry-after up to 60 seconds, and replays a POST only with an Idempotency-Key.

Sume TTS has no SSML field: speed, emotion, pronunciation dictionary
Moving an SSML voice script to Sume TTS? The request takes plain transcript text, so use speed 0.6 to 1.5, volume, emotion and a pronunciation dictionary id.

Test a Sume webhook receiver: stale timestamp and rotated secret
Two tests every receiver needs: a delivery older than 300 seconds must be refused, and a header with two sume-v1 entries must verify when either secret matches.

TTS word timings to karaoke captions: map words[] to text
Sume TTS returns words[] with start and end; captions take words as text, start, end. A short Python map skips speech-to-text and burns your exact script.

TypeScript exhaustive switch over a Sume run's terminal status
A run ends as completed, failed, canceled or skipped, and the last two send no webhook. Use a never check so a new status fails the build.

What to store from a Sume result: job and run artifact columns
Store artifact id, durable media.sume.com URL, type and content type for jobs, and size, width, height, duration and sha256 for runs. SQLite schema included.

Which fields to keep from a Sume submit response
Keep the job id, status_url, result_url, events_url, cancel_url, the sync flags and next_poll_after_seconds. Use generation_limits for pacing only.

Which API key scope does each Sume webhook endpoint need?
The signing secret needs account:read, rotate and test deliveries need account:write, redeliver needs jobs:write or formats:write. Map each call to a key.