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.

claude -p says Sume needs authentication after one refused write call
Claude Code 2.1.286 stopped headless runs flagging a server as unauthenticated after one refused call. Sume's scope refusal is a tool result, not a 401.

claude -p killed by timeout or systemd: the Sume job keeps running
A supervisor that kills claude -p does not cancel the Sume job it started. List jobs, then wait or cancel before retrying, or you pay twice.

Join two generated tracks without a gap: timeline audio concat
One Lyria generation too short? Join up to 20 Sume-hosted audio files into one gapless wav with timeline audio concat and read segment offsets.

Cline oversized MCP result cache: keep Sume job results small
Cline's SDK now caches MCP results over 16 MiB and gives a preview plus a cache URI. Keep Sume job output small with jobs_wait include_results.

Fit narration to a fixed slot: measure first, then set TTS speed
A 45-second cap or a 30-second slot decides your script. Render once with word timings, compute the speed ratio, and rewrite only if outside 0.6 to 1.5.

format_not_forkable 409 in the Sume API: what it means and the fix
Sume returns 409 format_not_forkable when the id you called names a built-in capability, not a Format card. How to tell, and which ids to call instead.

Gemini CLI untrusted tool output provenance: Sume results as data
Gemini CLI 0.60 and 0.61 release notes name fixes for untrusted tool output and indirect prompt injection. Keep Sume write tools behind scope and caps.

Gemini Omni Flash resolution: "4K" or "4k" on Sume
Sume accepts 4k as an alias of 4K for Gemini Omni Flash 1.1 and translates it to the lowercase token fal expects. Billed rate and Google's 4K caveat.

GPT Image 2.5 returns base64; Sume returns a URL: port the code
OpenAI's image API returns base64 data for GPT Image models, and Sume's returns hosted URLs. The three lines that change when you move a decoder over.

Idempotency keys for batch TTS: derive them from what you render
A retry loop that mints random keys pays twice. Hash the sentence, voice, model and settings into the key, and re-running a script returns the first job.

MiniMax H3 reference mix: why 9 + 3 + 3 fails the 12 cap
H3 and H3 Max allow 9 images, 3 videos and 3 audios, but only 12 inputs in total. A Python preflight counter and the cost of images past five.

What to save from a Sume run when batch results expire at 30 days
OpenAI keeps batch output 30 days, Anthropic 29, Gemini 6 weeks. Which Sume run receipt fields to store so your records outlive any vendor retention window.

STT words array has spacing tokens: filter type word before you count
Word counts and captions go wrong because the words array can include spacing items. Filter by type, keep timings, and compute speaking rate correctly.

Sume bulk items ignore on_active_run skip: allow is forced
Setting on_active_run skip or reject on a Sume bulk item does not stall the window, because the bulk controller runs every item with allow. What that changes.

Count Sume bulk webhooks to know the queue is done, and the trap
A Sume bulk queue has no webhook, so some teams count per-item deliveries. Canceled and skipped runs never deliver, so a pure counter can hang. Use a hybrid.

Sume image 400s name the valid values: retry in code
Sume's Image API 400 bodies carry details.supported, allowed, min and max. A tested error table and a small function that retries with a valid value.

Test MAI-Transcribe-2-Streaming's accuracy claim on your own audio
Microsoft says its streaming transcriber ranks first on Artificial Analysis. A 10-clip test on your own audio, with a word error rate script and Sume STT.

Transcribe two minutes of a long video: audio detach range, then STT
Streaming transcribers charge by the hour; you may only need one segment. Detach a range as 16 kHz mono wav, then run one STT job. Caps and codes included.

Reuse TTS word timestamps as caption words, skip a second STT
You already know what the voice said and when. Feed the TTS word timings to the caption job as `words` so brand names are never misheard by speech-to-text.

waitForRun maxTransientFailures: how many bad polls it absorbs
waitForRun absorbs 6 consecutive 429, 5xx or network read failures before it throws. How the streak resets, backoff works, and onTransientError fits in.

Which Lyria ran? job.model vs job.request.routed_model on Sume
On Sume's Music Router, job.model echoes what you sent and job.request.routed_model names the engine that ran. How to read both and pin a Lyria id.

YouTube 16:9 resolutions 240p to 8K and what Timeline renders
YouTube lists eight 16:9 resolutions from 426x240 to 7680x4320. Sume Timeline renders four of them: 1080p, 720p, 480p and 360p. Why the other four fall outside.

YouTube Live 1080p30 H.264 bitrate: 5 to 14 Mbps, GB per hour
YouTube Live recommends 5 to 14 Mbps for 1080p30 H.264, with 2 B-frames and a 2-second keyframe. The gigabytes per hour for each rung, and what Sume cannot set.

LinkedIn Live fails to process: use Baseline, not High or Main
LinkedIn says a Live stream that fails to process may need the Baseline H.264 profile, because High and Main add B-frames. Which a Sume render sets.

Bluesky link card thumbnail: 1,000,000 bytes, any image type
The thumb on a Bluesky link card is optional, accepts image/* and is capped at 1,000,000 bytes. Make a 1280x720 preview with Sume and shrink it under the cap.

Bluesky avatar and banner: 1,000,000 bytes, PNG or JPEG
Bluesky's profile record caps avatar and banner at 1,000,000 bytes each, PNG or JPEG only. How to size a GPT Image 2.5 output and check the bytes in Pillow.

A holiday ad brief as one JSON file that drives every Sume call
Keep one JSON brief with the product, offer, date and ratios, and have a script read it for each Sume call so every asset says the same thing.

Run sume doctor --agent --json as a CI preflight and keep the output
sume doctor --agent --json checks local CLI readiness without calling the API. Run it before job steps, fail on bad JSON or a nonzero exit, and keep the file.

Check for a newer Sume CLI release in CI without auto-upgrading
sume update --check reports whether a newer GitHub Release exists and changes no files. Run it on a schedule, log it, and bump your pinned tag by pull request.

Authenticate the Sume CLI on a CI runner without a browser login
On CI, skip sume login: install the CLI, run sume auth setup with an API key from a secret, and confirm with sume auth status before any job step.

Docker Compose: make a Sume webhook receiver refuse an empty secret
Use ${SUME_COM_WEBHOOK_SIGNING_SECRET:?message} in compose.yaml so docker compose stops before the receiver starts, and check again in the app code.

Forward verified Sume webhooks to Kafka, keyed by job_id
Verify the sume-v1 signature, refuse an empty secret, then produce each job event to Kafka with job_id as the key so retries land in one partition.

A Sume webhook arrives before your database knows the job: park it
If job.completed lands before your submit handler stored the job id, keep the verified event in a parked table, answer 2xx, and reconcile when the id is saved.

Stream Sume job progress to a browser with SSE and Node polling
Sume has no SSE or WebSocket job stream, so relay it: a small Node endpoint polls the status route and pushes text/event-stream messages to EventSource.

Removed OpenAI video ids: the exact list and a script to find them
OpenAI removed the Videos API and five sora-2 model ids on 2026-09-24. The exact ids from its deprecations page, and a Python script that finds them in a repo.

Verify a Sume video download against checksum_sha256 in Python
Stream a finished Sume artifact to disk, hash it with hashlib, and compare to checksum_sha256 from the job result. Skips cleanly when the field is null.

Check Sume artifact size, width and duration before you download
Read size_bytes, width, height and duration_ms from the job result and reject an unexpected artifact before spending bandwidth. Node 18 TypeScript sample.

Count Sume job replays with idempotency_hit after a client retry
A Sume job submit returns data.idempotency_hit. Log it after a retried video submit to prove the second call replayed the first job, not a new one.

Makefile targets to submit, watch and download a Sume video job
Three make targets: curl submits to video-router with an Idempotency-Key, sume jobs watch waits, sume jobs download saves it. Rerunning submit never pays twice.

TTS 400: Provide exactly one of transcript_source or transcript
This 400 means the TTS body had both transcript and transcript_source, or neither. Send exactly one, plus a voice, and re-run.

TTS 400 asking for voice.id or avatar_id / avatar_handle: the fix
The TTS call needs a voice: set voice.id, or a top-level avatar_id or avatar_handle. Without one the request is rejected before any audio is made.

Lyria 3.5 section markers: how to write [0:00 - 0:10] Intro prompts
Lyria 3.5 accepts timestamped section markers like [0:00 - 0:10] Intro: in the prompt, written in the lyric language. Sume's router uses the same idea.

How many video jobs fit in the queue on Thanksgiving week, by plan
Free accepts 6 generation jobs, Pro 24, Startup 48 and Scale 120. A wave of 75 percent of the free queue space keeps you clear of queue_full on Nov 23.

Tag Sentry events with the Sume job id and error category in Python
When a Sume job fails, set sume.job_id and sume.error_category with sentry_sdk.set_tag so one search finds the event, the job and the retryable flag.

Sume STT takes 10 minutes per request: a 90-minute file is 9 jobs
Sume speech-to-text caps a request at 600 seconds of audio, so a 90-minute recording is nine requests at up to $0.10 each, $0.90 in total.

Generate a Python client from the Sume OpenAPI JSON
Point openapi-python-client at the live Sume OpenAPI document, regenerate on each release, and keep a thin wrapper for polling, retries and the data envelope.

curl --fail-with-body: keep Sume's error envelope in shell scripts
curl --fail drops the response body on a 4xx. --fail-with-body (curl 7.76.0+) keeps it, so a script can read Sume's error code and retryable flag.

Mastodon media focal point: x and y from -1 to 1, 16:9 crops
Mastodon preview images are never cropped by the server, so apps crop them using a focal point from -1.0 to 1.0. How to compute it from a pixel in a Sume image.