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

Prove a Sume video retry is safe: same key, same job, one charge
A runnable test for a ported Sora worker: submit twice with one Idempotency-Key on /v1/videos, assert the same job id came back, and cancel before it bills.

Sume job statuses: three vocabularies and a Python normalizer
Ported Sora code checks one status word. Sume has pending, queued and IN_QUEUE depending on the route. A table, and a normalizer you can run with no network.

Timeout for AI video jobs: set a deadline in your worker, not HTTP
A Sora-era HTTP timeout of 10 minutes breaks on Sume: sync waits cap at 30 s while jobs run for minutes. Use a client deadline and a poll. Python example.

Callback or polling for a ported video worker: pick by job count
Replacing a Sora polling worker on Sume: when callback_url beats polling, when polling is enough, and one function that does both.

Split a long video into Shorts episodes: Python trim ranges
Generate back-to-back video trim ranges for a long vertical video with a tail rule, so no episode is a sliver. Respects the 1800 s source and 900 s output caps.

Test a Sume poll loop without waiting: inject sleep, assert delays
Unit test a job poll loop in milliseconds by injecting the fetch and the sleep. Assert that next_poll_after_seconds is obeyed and the 20-minute deadline holds.

Text-to-speech API with curl and jq: one shell script to an MP3
Call the Sume TTS Router from a shell: submit with curl, loop on the status URL with jq until terminal, then download the audio artifact to voiceover.mp3.

Sume timeline warnings are not failures: a gate for your season
A padded, looped, resampled or clamped clip comes back as a warning on a completed render. A Python allowlist gate stops those episodes before you publish.

Text-to-speech API in Node: submit, poll and save the MP3
A Node 18+ fetch example for the Sume TTS Router: submit with an Idempotency-Key, poll status_url, read the audio artifact and save an MP3 to disk.

TypeScript types for a Sume job status: narrow on sume_status
Type the Sume job envelope as a discriminated union on sume_status, so a switch covers queued to canceled and the compiler flags a missed case. Runs on Node 22.

User closed the tab mid-render: cancel the Sume job or let it finish?
Cancel works only before generation starts; after that you get 409 job_generation_already_started and the job bills. A tested tab-close handler.

Voice one script in six languages: Sume TTS loop and 409 guard
MAI-Voice-2.1 sells one voice across 23 languages. On Sume, set language per line, handle the 409 voice-language guard and price a six-language batch.

Webhook for an unknown job_id: park it, then reconcile on insert
A Sume job.completed webhook can name a job_id your database has not stored yet. Return 2xx, park the event in SQLite, and apply it when the insert lands.

Zed context_servers for the hosted Sume server: no header means OAuth
Add the hosted Sume server to Zed's settings.json context_servers with a url. With no Authorization header Zed runs the MCP OAuth flow, so start with mcp:read.

Check balance before bulk transcription: 402 and admission preview
A 402 insufficient_credits arrives before any provider work. Read GET /v1/balance and POST /v1/generation/admission-preview first and size the run.

Cancel a queued transcription job: what the 409 means
POST /v1/jobs/{id}/cancel works only before work starts. After that it returns 409 job_generation_already_started and the job finishes and bills normally.

Idempotency key for transcription: hash the request, avoid 409
Derive the Sume STT Idempotency-Key from a hash of audio_url, language and duration. A retry returns the same job. A changed body under that key is a 409.

List your transcription jobs: GET /v1/jobs by type, status, cursor
GET /v1/jobs?type=speech_to_text pages 100 jobs at a time, newest first. Join on each row's idempotency_key, not array position, to rebuild a batch.

Node fetch worker pool: submit transcription jobs with retry-after
A 30-line Node 18+ worker pool that posts Sume STT jobs, sleeps for retry-after on 429, and sends an Idempotency-Key per clip. Tested against a stub.

Poll many transcription jobs without a 429: next_poll_after_seconds
Poll Sume job status with the next_poll_after_seconds the API sends, back off on 429 with retry-after, and stop on a terminal status.

Python asyncio semaphore: submit transcription jobs with a cap
Run Sume STT submits through asyncio.Semaphore and asyncio.to_thread, honor retry-after on 429, and keep one Idempotency-Key per clip. Tested code.

Sume STT mode sync: transcribe a short clip in one request
Send mode sync with wait_timeout_seconds up to 30. A short clip answers 200 with the finished job. A longer one answers 2xx with the queued job to poll.

Transcribe 10,000 short clips: queue capacity and wave size by plan
10,000 five-second clips cost $8.33 on Sume STT. How fast they finish depends on plan concurrency and queue capacity: 6, 24, 48 or 120 accepted jobs.

Unit test a transcription retry loop with a fake 429 in Python
Test your Sume STT retry code without calling the API: inject the POST and sleep, return a 429 with retry-after, and assert the same key is sent twice.

What did one transcription job cost? GET /v1/usage by job_id
Read GET /v1/usage?job_id= and sum data.summary.debited_usd_micros to see what one Sume STT job really cost. Holds and refunds are not counted as spend.

Word timestamps to video frame numbers at 29.97 fps in Python
Sume STT words[] carry start and end in seconds. Convert them to frame indexes with exact 30000/1001 math so cuts do not drift on long timelines.

Clamp video duration when swapping Sora for a Sume video model
Each Sume video id has its own seconds range, so old Sora code can ask for a length a model rejects. Clamp per id before you submit; Python table of limits.

Does my Short have audio? Check probe.has_audio before captions
Transcribing a silent clip returns inspect_source_has_no_audio. Probe has_audio first with a frames:false video inspect, then caption only clips with a voice.

Fall back to a second image model after three 502s: a Python breaker
Sume returns 502 when an image job fails inside the wait budget. Count them, switch to a second model id after three, and use a new idempotency key per model.

Go net/http client for Sume images: handle 200 and 202 on a model swap
A Go program that posts to Sume /v1/images with the model id from an env var and branches on 200 versus 202, so a gpt-image-1 swap is not a rebuild.

gpt-image-1 returns 404 model_not_found on Sume: which id to send
gpt-image-1, gpt-image-1.5 or gemini-2.5-flash-image sent to Sume /v1/images return 404 model_not_found. Ids to send instead, plus a lookup.

How Sume TTS splits a script into sentence ids (. ! ? only)
Sume's script source cuts sentences at periods, exclamation and question marks only, keeps every character, and numbers them sent_000000. Examples and traps.

Ktor webhook route for an AI video job: receiveText and HMAC SHA-256
A Ktor route reads the raw body with call.receiveText(), checks Sume's sume-v1 HMAC over timestamp.body in Kotlin and returns 401 when the secret is empty.

Log Sume ratelimit-remaining on every Python urllib response
A urllib handler that logs ratelimit-remaining and ratelimit-reset on each Sume response, warning under 10 percent. It also sees 429 replies.

MATLAB webwrite and weboptions: generate an AI video and save the MP4
A MATLAB script posts a Wan 3.0 job to Sume with webwrite, polls the job status with webread and saves the finished clip with websave.

NestJS raw body controller to verify an AI video webhook signature
Enable rawBody in NestFactory, read req.rawBody in a controller and check Sume's sume-v1 HMAC before you act on a job.completed video event.

One Sume API key per service: what it isolates and what it does not
Sume request budgets are per key and reads and writes are already separate. A key per service isolates revocation and scope, not generation capacity.

OpenAI images.generate to Sume /v1/images: field by field map
Move a gpt-image-1 images.generate call to Sume POST /v1/images: which fields carry over, which return 400, and why size becomes image_size. Python mapper.

Pin the image model id on the queue row so a swap can't break old jobs
Store the Sume model id on each queued render row at enqueue time, then re-point only rows still carrying a retired id. Python sqlite3 sample for gpt-image-1.

Postgres SKIP LOCKED poll table for AI video jobs with next_poll_at
Track Sume video jobs in one Postgres table with next_poll_at, claim due rows with FOR UPDATE SKIP LOCKED and reschedule from next_poll_after_seconds.

pytest: fail CI when a configured image model id isn't in Sume's list
A pytest that reads your image model ids and checks each against GET /v1/images/models, so a retired id such as gpt-image-1 fails CI before it fails a customer.

Python pre-flight for a Short: catch Timeline schema errors offline
A Python check for a Sume Timeline body: even width and height, allowed fps, 1 to 1800 seconds, fade limits and start order. Run it before the plan call.

Redis sorted set scheduler for AI video job polling in Python
Keep video job ids in a Redis ZSET scored by next-poll time, claim due ids with ZREM so no two workers poll one job, reschedule by next_poll_after_seconds.

Stitch four voice takes into one 3-minute Short with audio.parts
Timeline audio.parts joins up to 20 gapless narration slices inside one render, no re-synthesis. Build a 180-second Short from four takes, with the math.

Sume SDK idempotencyKey: null sends no key, so POST retries stop
subscribeFormatRun mints a UUID Idempotency-Key by default. Pass null and the create call carries no key, so the SDK will not retry it on a 429 or 5xx.

Preview Sume TTS sentence ids, lengths and job cost before you submit
A short Python script that splits a script like Sume's source API, groups sentences under 20,000 characters and prices each job at $0.0475 per 1,000 characters.

Sume webhook fails the 300-second window: find the clock drift
A valid Sume signature still fails if your server clock is more than five minutes off. Tell drift from a bad secret with a small Python check.

SvelteKit +server.ts endpoint for an AI video webhook: request.text()
A SvelteKit POST handler reads request.text(), verifies Sume's HMAC over timestamp.body with node:crypto and returns 401 for bad or missing signatures.