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.

One TTS job with sentence segments vs one job per sentence
Sume TTS can return gapless sentence timings and per-sentence wav slices from one job. The price per character is the same; the jobs, keys and polls are not.

Sume API 503 codes: which ones are retryable and which are not
Four 503 responses look alike but differ in the retryable flag: deploy_draining, database_busy, provider_capacity_exceeded and any _not_configured code.

Parse the Sume error envelope into a Python dataclass and exception
Sume errors share one envelope: code, request_id, retryable, retry_after_seconds, next_action, category and stage. Turn it into a typed Python exception.

Sume ratelimit-reset: sleep until the 60-second window ends (Python)
Every Sume /v1 response carries ratelimit-remaining and ratelimit-reset. Stop at zero and sleep the reset seconds instead of eating a 429. A Python wrapper.

Does a second Sume API key raise your rate limit? No, here is why
Each Sume API key has its own bucket, but the workspace owner has an account bucket too. A second key spreads load without adding requests per minute.

Sume MCP rate limit: one write per run created, none per status poll
Over Sume's hosted MCP, a tool call spends one write for the run it creates, and a jobs_status poll spends none. The numbers per plan and a Python budget check.

Sume webhook 300-second tolerance: verify on receipt, not later
A queued Sume webhook fails the 300-second timestamp check if verified late. Verify at the edge, then queue the body. Python with a testable clock.

Swap in an AI-generated presenter: portrait first, then Recast
No photo of a real person? Generate a presenter portrait with Sume's image API, pass its URL to h3-max-recast, and poll the video job. Python included.

Verify a Sume TTS webhook in Python instead of polling
Get a signed job.completed callback when a voiceover finishes. A Python verifier with a 5-minute replay window that refuses an empty secret.

Wan 3.0 result URLs expire in 24 hours at Alibaba; fetch from Sume
Alibaba says a Wan3.0 result URL is valid for 24 hours. On Sume you download the finished video through the content endpoint with a Bearer key.

Wan 3.0 duration -1 is Alibaba's smart length; Sume wants 2 to 30 s
Alibaba's Wan3.0 guide lets duration be -1 for smart length. Sume's wan-3.0 takes whole seconds from 2 to 30, so send a number and know the cost.

Sume rate limit scope: /v1 and MCP count, OPTIONS preflights do not
The Sume limiter covers /v1 paths and the MCP route. CORS OPTIONS preflights are exempt, and reads and writes use separate buckets. What that means.

Deno KV: dedupe Sume webhooks with atomic check on a null versionstamp
Deno.serve and Deno KV: verify the Sume HMAC with crypto.subtle.verify, then claim job_id with kv.atomic().check({ versionstamp: null }) so retries commit once.

DynamoDB conditional put: dedupe Sume job_id webhook retries
A PutItem with attribute_not_exists(job_id) makes the first Sume webhook the only one that proceeds. Node sample with a two-state record and TTL.

One-hour Sume OAuth token in an OpenAI MCP authorization field
OpenAI does not store the MCP authorization token and wants it on every request. Sume's token lasts one hour with no refresh, so track expiry yourself.

Responses API mcp_list_tools cache and Sume write tools
OpenAI reuses an mcp_list_tools item instead of refetching. If it was captured under mcp:read, Sume write tools stay missing until you start fresh.

Free preview, paid run: a Cloudflare MCP server over Sume
Cloudflare lets one MCP server mix free and paid tools. Offer a free estimate tool backed by Sume dry_run, then a paidTool that starts the run.

Cloudflare paidTool pricing when a Sume run sits behind it
If a Cloudflare paidTool wraps a Sume Agent Completion, set the tool price above the run's generation_spend_cap_usd so one sale cannot lose money.

Graceful shutdown for a Node webhook receiver: 503 while draining
On SIGTERM, refuse new Sume webhooks with 503, finish the in-flight write, then exit. Sume retries non-2xx responses 10 times, so deploys lose nothing.

Wire an OpenAI mcp_approval_response to a Sume spend cap
When a person approves an mcp_approval_request, reuse the approved dollar amount as max_spend_usd on the Sume call so the approval and the cap match.

Compute Sume job headroom from generation_limits, not a hardcoded 4
Read generation_limits from each Sume submit response and size new work with max(0, concurrency_limit - active - queued). Python example, with the docs numbers.

MCP SEP-2260 server requests and Sume's tools-only hosted MCP
SEP-2260 lets servers send requests only while handling a client request. Sume's hosted MCP code has no sampling or elicitation requests, so nothing changes.

pino logs for Sume API calls: job_id, request_id, redacted keys
Log every Sume call with pino child loggers that carry job_id and the error request_id, and redact the Authorization header so keys never reach the log store.

GPT Image 2.5 custom size: 3840x2160 passes, 3840x1200 fails
Check a custom image_size for ChatGPT Image 2.5 on Sume before you send it: multiples of 16, 3840 max edge, 3:1 max ratio, 655,360 to 8,294,400 pixels.

require_approval never with tool_names for Sume read tools
Use the object form of require_approval to skip approval only for Sume read tools like account_me, and keep every paid tool on the approval path.

Recraft V4 on Sume returns WebP only: convert to PNG with Pillow
Recraft V4 on Sume lists webp as its only output format at $0.05 per image. Download the file and convert to PNG or JPEG with Pillow in six lines.

NATS JetStream: use job_id as Nats-Msg-Id for Sume webhooks
Verify the sume-v1 signature, then publish the raw event to JetStream with job_id as Nats-Msg-Id. Node receiver sample, plus why the consumer must still dedupe.

Dart Shelf: verify a Sume webhook with package:crypto HMAC-SHA256
A Dart Shelf server that reads the raw body, checks the sume-v1 HMAC with package:crypto in constant time and exits at boot when the signing secret is empty.

ASP.NET minimal API: raw body and FixedTimeEquals for Sume webhooks
Take HttpRequest, not a bound model, in an ASP.NET minimal API. Read the raw body, verify sume-v1 with FixedTimeEquals and refuse an empty signing secret.

OpenAI charges no per-call MCP fee, but Sume paid tools bill
OpenAI bills tokens for MCP tool imports and calls with no per-call fee. A Sume paid tool still spends credits, so preview and cap each call.

Sinatra: request.body.read and secure_compare for Sume webhooks
A Sinatra route that reads the raw Rack input, rewinds it, checks the sume-v1 HMAC with secure_compare and aborts on an empty signing secret.

MCP step-up scopes (SEP-2350) vs Sume's mcp:write re-consent
The MCP 2026-07-28 draft adds step-up scope accumulation. On Sume today, getting from mcp:read to mcp:write means a new consent and a new token.

Firestore create() with job_id as document id for Sume webhooks
Name the Firestore document after the Sume job_id and call create(). ALREADY_EXISTS marks a retry. Node Admin SDK sample, plus a claim state for crashes.

Estimate a Sume TTS bill in Python before you submit: count characters
Sume TTS is $0.0475 per 1,000 characters, spaces and punctuation included. A small Python function prices a script and flags ones near the limits.

defer_loading and tool search for Sume's MCP tools
Set defer_loading: true on the Sume MCP tool so OpenAI tool search loads definitions on demand, then use tools_list and tools_schema for details.

Prisma upsert on a unique job_id for Sume webhook retries
Dedupe Sume job webhooks with a Prisma model keyed on job_id and an upsert that updates nothing, after verifyWebhook. TypeScript route handler for Next.js.

systemd restart: finish Sume jobs with sume jobs watch, never resubmit
A systemd unit that restarts a finisher and resumes stored Sume job ids with sume jobs watch and download, so a crash never pays for a second job.

Find the timestamp of a phrase in a recording with Sume STT words[]
Every Sume STT job returns words[] with start and end seconds. A short Python function finds where a phrase is said, so you can jump to or cut the exact moment.

Verify a Sume webhook signature in Python for a finished TTS job
A short Python verifier for Sume job webhooks: HMAC SHA-256 over timestamp.body, the sume-v1 header, a five-minute replay window, and no empty secret.

Starlette: await request.body() to verify a Sume webhook signature
Read raw bytes with await request.body(), check the sume-v1 HMAC with compare_digest, then parse JSON. A Starlette route that refuses an empty secret.

Which ID to store from a Sume call: id, generation_id or request_id
Sume returns an id, a generation_id, a request_id and an error request_id. Store the job id and keep the req_ error id in logs only. Here is where each appears.

RabbitMQ prefetch: set it to your Sume concurrency_limit
Set channel.prefetch to the workspace concurrency_limit so each RabbitMQ message holds one Sume video job until it is terminal. Node sample.

MongoDB updateOne upsert with $setOnInsert for Sume job_id
Use a unique index on job_id and updateOne with upsert and $setOnInsert so only the first Sume webhook delivery starts work. Node driver sample.

A/B test three voices on one line: parallel Sume TTS jobs in Python
Submit the same 300-character line to three voices at once with one Idempotency-Key each, poll with backoff and compare the files. The test costs $0.04275.

React Router resource route for Sume webhooks: request.text() first
In React Router or Remix, a resource route with only an action can verify a Sume webhook: read request.text(), check the HMAC, then JSON.parse and store job_id.

MySQL: INSERT IGNORE or ON DUPLICATE KEY UPDATE for Sume job_id
Dedupe Sume job webhooks in MySQL with a job_id primary key. Why ON DUPLICATE KEY UPDATE with a counter beats INSERT IGNORE, and what affectedRows tells you.

Ktor receiver for Sume webhooks: receiveText, HmacSHA256, isEqual
A Ktor route that reads the raw body with receiveText, checks the sume-v1 HMAC with MessageDigest.isEqual, and refuses to start when the secret is empty.

Poll 40 Sume jobs without bursts: jitter, retry-after, next poll hint
Watch many Sume jobs in asyncio: stagger the first poll, sleep next_poll_after_seconds with jitter, and back off on a 429 retry-after from the status route.