Sume API errors and rate limits: codes, 429s, and when to retry
Sume API errors share one envelope with a stable code and a request id. Reads and writes have separate per-minute budgets; queue_full is not a rate limit.

Every Sume API error comes back in one JSON envelope: a stable lowercase code to branch on, a human-readable message, and a request_id that is safe to share with Sume support. Rate limits are per API key and per minute, with separate budgets for reads and writes, and a 429 queue_full means generation capacity is full, not that you sent too many requests.
The codes and limits below come from Sume's Errors and rate limits page and the Formats Errors and spend reference.
What does a Sume error response look like?
Branch on the HTTP status first, then on code. The envelope carries more than the code:
codeis the stable token toswitchon, matching^[a-z0-9_]+$.messageis written for a human and may change: log it, never match on it.request_idis also sent as thex-sume-request-idheader.retryableandretry_after_secondssay whether resending the same request can succeed, and how long to wait first.next_actionisauthenticate,fix_input,add_funds,retry_later,poll_status,inspect_events, orcontact_support.
{
"error": {
"code": "workspace_key_required",
"message": "This Format belongs to a team workspace. Use an API key created in that workspace.",
"request_id": "req_…",
"category": "auth",
"stage": "auth",
"retryable": false,
"retry_after_seconds": null,
"public_reason": "workspace_key_required",
"next_action": "authenticate",
"details": { "workspace_id": "org_…" }
}
}Which status codes does the Sume API return?
A 4xx at create means nothing ran and nothing was charged, so fix the call instead of retrying it. The docs call retrying a 403 insufficient_scope in a loop the most common and most expensive mistake.
The Formats API adds its own codes, such as workspace_key_required and format_not_found; Errors and spend lists every one.
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request or bad_request | Request body, query, path, or headers are invalid. |
401 | unauthorized | API key is missing or invalid. |
402 | insufficient_credits | Balance is not sufficient for the requested generation. |
404 | not_found | Resource does not exist in the current workspace. |
409 | job_not_completed, job_not_cancelable, or job_generation_already_started | The job operation is not valid for the job's current status. |
413 | payload_too_large | Request body exceeds the configured API limit. |
415 | unsupported_media_type | The request body was not application/json. |
429 | rate_limited | Too many requests in the current window. |
429 | queue_full | Workspace generation concurrency plus queue capacity is full. |
503 | provider_not_configured or provider_capacity_exceeded | A runtime dependency is unavailable or at capacity. |
What are the Sume API rate limits per plan?
Every key has a per-minute request budget across all of /v1, set by the workspace's plan. Reads and writes have separate budgets, and reads get forty times the write number, so polling cannot starve your own creates. A read is any GET, such as a receipt, status_url, or a list. A write is everything else: creating runs and queues, cancel, redeliver.
Every response carries ratelimit-limit, ratelimit-remaining, and ratelimit-reset (seconds until the window resets) for the budget the request spent from. A 429 adds retry-after, in seconds, and names the budget in error.details.scope as read or write. Pace on these headers rather than counting requests yourself.
| Plan | Writes per minute | Reads per minute |
|---|---|---|
| Free | 120 | 4800 |
| Pro | 300 | 12000 |
| Startup | 600 | 24000 |
| Scale | 1200 | 48000 |
| Enterprise | Contracted; Scale until provisioned | Contracted |
Is 429 queue_full a rate limit?
No. queue_full means Sume cannot accept another paid generation job for the workspace until an existing queued or processing job finishes or is canceled. A full concurrency limit by itself is not an error: Sume accepts valid jobs as queued while queue capacity remains. Raising your request rate does not raise your plan's concurrency limit either. Video job concurrency and queueing covers admission in detail.
When should I retry, and how?
Back off on 429, and use retry-after when present. Do not retry unsafe submit requests without an idempotency key. By code:
- A
429or503inside a poll loop is transient. Abandoning the loop does not stop the run or its spend, so back off and poll again. provider_capacity_exceededand503 studio_agent_upstream_unavailable: retry later with the same idempotency key.provider_not_configured: do not retry aggressively; check catalog and runtime status.409 idempotency_key_in_useis retryable: wait about a second and resend.402 insufficient_credits: top up first. Retrying without doing so returns the same answer.image_not_fetchableorinput_media_unreachable: check that the input media is a public HTTPS image URL, then retry.
What does a failed job or run report?
Failed jobs expose public error metadata: category, stage, retryability, retry-after seconds, public reason, and next action. Categories include validation, auth, quota, queue, generation_unavailable, generation_rejected, generation_timeout, runtime_unavailable, worker_timeout, and internal.
On the Formats API, a 202 never turns into a create error later. Failures arrive on the receipt as status: "failed" with an error.code such as unattended_blocked, output_schema_unsatisfied, deliverable_missing, or format_run_failed, and primary_output_url is null. Treat the set as open, and retry a failed run with a new Idempotency-Key.
When you write to support, quote the request id, the run or job id, and the error.code. Do not send API keys, signing secrets, signed URLs, raw media URLs, or private workspace or user ids.
Sources
Related posts
Written by Sume