PricingAPI keys
  • Overview
  • Quickstart
  • Authentication
  • Overview
  • Format API
  • Create a run
  • Runs and results
  • Bulk runs
  • Editing a Format package
  • Structured output
  • Format catalog
  • Errors and spend
  • Cookbook
  • Embed a Format in your product
  • Waiting for runs and jobs
  • Agents
  • Agent Completions
  • Scheduled
  • Create a schedule
  • Advanced: run a schedule via API
  • Runs and results
  • Run webhooks
  • Safe automation
  • Best practices

Enterprise

Errors and spend

Every error the Formats API returns, by stage. The envelope, what to do per code, what a failed run carries, webhook delivery outcomes, credits and spend caps, and rate limits.

All errors on the API have the same envelope, and each code is a lowercase token that you can branch on. This page lists all the codes of the Formats surface in one place. It puts the codes in groups, by the time when they occur. The groups are: before a run exists, while you read it, when the run fails, and when a webhook delivery failed. Spend and rate limits are at the end.

The error envelope

json
{
  "error": {
    "code": "workspace_key_required",
    "message": "This Format belongs to a team workspace. Use an API key created in that workspace.",
    "request_id": "req_0123456789abcdef0123456789abcdef",
    "category": "auth",
    "stage": "auth",
    "retryable": false,
    "retry_after_seconds": null,
    "public_reason": "workspace_key_required",
    "next_action": "authenticate",
    "details": { "workspace_id": "org_…" }
  }
}
FieldUse it for
codeThe stable token to switch on. It matches ^[a-z0-9_]+$ and is never a sentence.
messageText for a human. It can change. Log it. Never match on it.
request_idThe API also sends it as the x-sume-request-id header. Give it to support.
retryable, retry_after_secondsTells you if the same request can succeed when you send it again, and how long to wait first.
next_actionauthenticate, fix_input, add_funds, retry_later, poll_status, inspect_events or contact_support.
category, stage, public_reasonLess specific labels for dashboards and alerts.
detailsCode-specific data: required_scope, workspace_id, violations[], index, status, scope, …. Each code below names its fields.

Branch on the HTTP status first. Then branch on code. A 4xx at create means that nothing ran and the API charged nothing. Thus, correct the call. Do not retry it. The most frequent and most expensive mistake is to retry a 403 insufficient_scope in a loop.

Errors at create

These errors apply to POST /v1/formats/{handle}/{slug}/runs and POST …/bulk-runs. Nothing runs, and the API charges nothing. A failed create releases its Idempotency-Key.

Statuserror.codeMeaningWhat to do
400invalid_requestOne of these conditions is true. The body names none of instruction / input / previous_run_id / attachments. The body names both output_schema and response_format. input is not an object, has more than 64 top-level keys, or is more than 2 MiB. generation_spend_cap_credits is 0 or above the platform maximum. model is not in the catalog. A bulk body has bad concurrency or items. A webhook URL is not public HTTPS. The communication aliases do not agree.Read message and details.
400unknown_parameterA top-level field that the API does not know. This also applies to thread_id. details.errors[].suggestion names the field that you probably intended.Rename the field, or remove it.
400output_schema_invalidThe schema is not in the supported subset. details.violations[] lists each { path, rule, message }.Correct each violation. Refer to Supported schemas.
400invalid_attachmentAn attachments[] item is bad, or the attachments go above the media budget. attachments[] shares this budget with input URLs.Refer to Attachment errors.
400attachment_not_foundasset_id is unknown in this workspace.Upload it, or use a URL.
400previous_run_format_mismatchprevious_run_id names a run that started on a different Format.Continue it on that Format.
400previous_run_not_resumableThat run left nothing to continue. details shows previous_run_status, has_thread, and artifact_count.Start a new run.
401unauthorizedThere is no key, a malformed key, a revoked key, a key for the other host, or two credentials at the same time.Correct the header.
402insufficient_creditsThe workspace does not have enough credits for the run. details.required_credits and details.available_credits give the numbers. next_action is add_funds.Add credits: upgrade the plan, or buy credits for the team. If you retry before you add credits, you get the same answer.
402organization_wallet_not_provisionedThe organization workspace has no credits provisioned yet. details is the same as for insufficient_credits.An admin must add credits to it.
403insufficient_scopeThe key does not have formats:write (details.required_scope), or it is a service-account key (details.reason: service_account_format_runs_unsupported).Mint a new key with the scopes. You cannot add scopes to a key that you already have.
403workspace_key_requiredThe Format is a team Format, and the key is a personal key. details.workspace_id names the workspace. For a team key from a different workspace, the API uses its grant to make the decision (the run starts, or 404).Create a key in that workspace, or ask its owner for a grant.
404format_not_foundThe handle or slug is unknown, or the Format is archived. Or the Format is not in the workspace of your key. Or it is a team Format, and your workspace has no accepted grant for it (a pending or revoked grant gives the same result).Examine the address and the key. For a shared Format, ask the owner for a grant.
404previous_run_not_foundprevious_run_id is unknown or not yours.Examine the id.
409format_inactiveThe owner workspace set the Format to Inactive. This applies to all callers, and also to the workspaces that the owner shared it with.Owner workspace: Format page → API tab → Status Active.
409format_api_trigger_disabledThe owner workspace disabled the API call trigger. This applies to all callers, and also to the workspaces that the owner shared it with.Owner workspace: Format page → API tab → API call trigger On.
409format_run_in_progresson_active_run: "reject" is set, and a run is already in progress.Wait, or remove reject.
409format_not_forkableYou addressed a built-in capability, not a Format.Call a Format by Sume, or call your own Format.
409previous_run_not_terminalThe run that you want to continue is still in progress.Poll the run. Then call again.
409idempotency_conflictYou already used that Idempotency-Key with a different body. For bulk runs, details.queue_id names the original queue.Correct how you derive your keys. Do not retry without a change.
409idempotency_key_in_useA different request with the same key is in progress. retryable: true.Wait approximately one second. Then send the request again.
413payload_too_largeThe request body is more than 4 MiB (details.limit_bytes).Make input smaller. Send media by URL.
415unsupported_media_typeYou did not send the body as application/json (details.received_content_type).Set Content-Type: application/json.
413attachment_too_largeAn image is more than 30 MB, or a set is more than 500 MB.Resize.
429rate_limitedNo write budget remains for this key. error.details.scope is write.Wait for retry-after. Refer to Rate limits.
502attachment_fetch_failedSume could not fetch an attachment (details.index). The status is 5xx, but the cause is your input: next_action is fix_input.Make sure that the URL is public.
503studio_agent_upstream_unavailableAn outage on the Sume side.Retry at a later time with the same Idempotency-Key.
4xx/5xxformat_run_failed_to_startThe run could not start, and no more specific code is applicable.Read message. Retry one time. If the error occurs again, contact support with request_id.

A 202 never changes to one of these errors at a later time. After you get a receipt, failures arrive on it as status: "failed".

Errors while reading

These errors apply to GET /v1/format-runs/{run_id}, /status, /result, /events, POST …/cancel, POST …/webhook/redeliver, GET /v1/format-run-queues/{queue_id}, and the Format reads.

Statuserror.codeMeaningWhat to do
401unauthorizedThe same as above.Correct the header.
403insufficient_scopeReads need formats:read. Cancel and redeliver need formats:write.Mint a new key.
404format_run_not_foundThe run id is unknown, or a different owner has the run.Examine the id and the key. A run that you cannot see gives the same result as a run that does not exist.
404format_run_queue_not_foundThe queue is unknown, or a different owner has it.The same as above.
404format_not_foundThe same as above.The same as above.
409run_not_completedYou sent GET …/result before the run was terminal. details.status is the current status. retry_after_seconds gives a recommended time for the next poll.Poll status_url. Then read result_url.
409webhook_not_configuredYou sent redeliver for a run created without a webhook_url.There is nothing to redeliver.
409run_not_terminalYou sent redeliver while the run is still in progress.Wait for the terminal receipt.
429rate_limitedNo read budget remains (details.scope: read).Wait for retry-after. The run continues.
503studio_agent_upstream_unavailableAn outage on the Sume side.Retry. The run continues.

A 429 or 503 in a poll loop is temporary. If you stop the loop, the run and its credits do not stop. Thus, back off and poll again.

When the run itself fails

A run that could not finish comes back with status: "failed", error: { code, message }, and usually output_error with more data. artifacts[] still lists all the media that the run generated. output still holds the partial result that satisfied your schema, if there is one. A failure never gets a pointer: primary_output_url is null. Thus, if (run.primary_output_url) stays a safe test for "the deliverable exists".

error.codeMeaningWhat to do
unattended_blockedThe run stopped at a gate that it could not pass without a person. No avatar matched the brief, or an input was missing that the run asks for in chat. message is text that you can show to a user.Correct the input or the brief. Retry with a new Idempotency-Key.
output_schema_unsatisfiedThe run finished, but its result did not match your output_schema, or the result referenced media that the run did not produce. The data is in details.rejected_urls[] or details.violations[], with a harvested count by media type.Compare details.harvested with the requirements of your schema. Usually, the schema asks for a file that the Format never makes. Change that field to nullable, or change the instruction.
deliverable_missingThe Format declares that it produces media (io.output_kind), but this run made no media.Retry. If the error occurs again, the input is not what the recipe expects.
primary_output_missingThe result satisfied your schema, but the primary_output_key that you named is empty. output holds the partial result.Continue the run to fill the gap, or retry.
agent_reported_failureThe accepted return_format_output of the run said that the run did not deliver. The cause is an explicit-fail payload, or media slots that report failed / stand-in. Or the primary is not the declared deliverable of the Format (audio or a still under a video key). output holds the ledger of what the run made. primary_output_url is null.Read details.reason and output. The clips on output are real, and a retry does not generate them again. Continue the run, or re-fire it with a new Idempotency-Key.
incomplete_assemblyThe run reached its time limit before all its generation jobs finished. Thus, the delivered media is not all the media that the run used credits for. details.pending_job_count and details.pending_jobs[] name the unfinished jobs. When your schema permits it, the partial ledger is on output.Continue the run with previous_run_id. The finished clips are on the thread, and the continuation does not generate them again.
output_extraction_failedThe projection could not run. details.reason: harvest_unavailable means that the media was not readable while the run finalized. In that case, status stays completed, and the receipt fills in on the next read. details.reason: harvest_threw means that the harvest of the host crashed after the run finished. In that case, the run is failed, and details.thrown holds the frame that threw and the build. If the ledger of the run holds none of the declared media of the Format, the run reports deliverable_missing, not this code.harvest_unavailable: read the run one more time. Then retry with a new key. harvest_threw: this is a host defect. Report the run id. The clips on the thread are real, and a retry does not generate them again.
mcp_unavailableThe per-turn Sume MCP tools that this run needed did not attach. Thus, the host failed the run before the model started, and did not run a turn without tools (#7378). details.retryable is true and details.charged is false. No generation ran, and there is no charge.Retry with a new Idempotency-Key. If the error occurs again, the cause is the tools, not your request.
provider_unavailableThe provider stream of the model stopped, and all its reconnects failed before the run produced its deliverable. Your input did not cause this error. details.retryable is true.Retry with a new Idempotency-Key. The finished clips are on the thread, and the retry does not generate them again.
provider_credits_exhaustedThe account of Sume at the model provider used all of its credit, thus the run stopped. The cause is on the Sume side. It is not your Sume balance and not your input. details.retryable is false.Do not re-fire immediately. When Sume reports that the provider account is restored, retry with a new Idempotency-Key.
format_run_failedThe generic failure.Read message. A run that tried to use more credits than its cap also gets this code. Thus, compare usage.cap.counted_credits with usage.cap.limit_credits before you raise the brief.

This set of codes is open, and new codes can appear. Thus, handle the codes that you know, and use a fallback for all other codes. Retry a failed run with a new Idempotency-Key. The old key is bound to the receipt that you already have. When the failure left clips, it is better to continue the run than to start a new run.

On a webhook, the same run arrives with status: "ERROR", outcome: "error", and an error.code that is the same as payload.error.code. A run that completed but could not fill your schema arrives as status: "OK", outcome: "degraded". It has real media and output: null.

Webhook delivery failures

A delivery outcome never changes the run. The webhook_delivery block on each receipt tells you the result:

webhook_delivery.statusMeaningWhat to do
retryingAn attempt failed. next_attempt_at is the time of the next attempt. For HTTP 429/503 from your endpoint, the API obeys Retry-After up to one hour.Nothing, unless last_status_code shows a problem on your side.
failed, exhaustedTen attempts failed because of a refusal, a timeout (10 s each), or a redirect. Or the URL failed re-validation. last_status_code and last_error tell you which cause.Read the receipt from result_url. Correct the endpoint. To replay, send POST …/webhook/redeliver.
Envelope with payload: nullThe receipt was more than 1 MiB. error.code is payload_too_large, and error.result_url gives the address to fetch it. status still shows the real outcome of the run.Fetch result_url. A handler that always reads payload as an object will throw on your largest runs.

For the full delivery rules, refer to Runs and results.

Credits and spend

A run uses credits from the workspace of the key. Two gates apply, at different times:

GateWhenOn failure
WalletAt create. The workspace must have enough credits for the run.402 insufficient_credits (next_action: add_funds), or 402 organization_wallet_not_provisioned. Nothing ran.
Spend capDuring the run. The run cannot use more credits than its effective cap.The run ends as failed. usage.cap shows how near to the cap the run got.

The cap is the control that you own. Each Format has a cap in credits (generation_spend_cap_credits on the Format, or the platform default when the Format never set one). generation_spend_cap_credits on the request names the ceiling of this run, up to the platform maximum. The API accepts a value above the cap of the Format, runs null at the platform maximum, and rejects 0. A production long-form run needs a much larger cap than a single-scene retry, which needs only a fraction of it. For details, refer to Spend caps.

Metered generation (video, image, avatar, voice, timeline work) uses credits at the rates on the API rate card. The receipt shows this amount as usage.cap.counted_credits. This value increases while the run is in progress. It counts reserved and captured credits, and it settles when the run terminates.

This value does not include the LLM turn of the agent. Thus, it is not the total credits of the run: that is usage.debited_credits. It is also a receipt value, not an invoice: GET /v1/usage and GET /v1/balance are the billing records. usage is null when the API could not read the credits. This is different from 0.

Generation that finished before a cancel or a failure keeps its credits. If a later step fails, the credits of the generation that finished do not come back. A 4xx at create, an idempotent 200 replay, and a skipped run use no credits.

Rate limits

Each key has a per-minute request budget for all of /v1. The plan of the workspace sets this budget. Reads and writes have separate budgets. Reads get forty times the write number, thus polls cannot block your own creates.

PlanWrites per minuteReads per minute
Free1204800
Pro30012000
Startup60024000
Scale120048000
EnterpriseContracted (Scale until provisioned)Contracted

A read is a GET of all types: the receipt, status_url, events_url, result_url, and the Format and run lists. A write is all other requests: create calls for runs and queues, cancel, and redeliver.

Each response holds the current state. A 429 names the budget that it came from:

HeaderMeaning
ratelimit-limitThe number of requests permitted in the current window, for the budget that this request used.
ratelimit-remainingThe number of requests that remain in that window.
ratelimit-resetThe number of seconds until the window resets.
retry-afterThe number of seconds to wait. The API sends it on 429. error.details.scope is read or write.

Use the headers to set your pace. Do not count the requests yourself. The request rate is not the generation capacity. The workspace's concurrency limit, set by what it topped up in the last 28 days, controls how many generations run at the same time. If you increase your request rate, this limit does not increase.

Getting help

Each response has x-sume-request-id, and each receipt has request_id. When you contact support, include these values, the run id, and the error.code. Do not send API keys, signing secrets, or raw media URLs.

Next

  • Create a run: the create contract, with the 401 / 403 / 404 dialect in detail
  • Runs and results: polls, webhooks, webhook_delivery, and how to continue a failed run
  • Structured output: schema rules and each output_error
  • Authentication: keys, rotation, and the full rate-limit notes

On this page

  • The error envelope
  • Errors at create
  • Errors while reading
  • When the run itself fails
  • Webhook delivery failures
  • Credits and spend
  • Rate limits
  • Getting help
  • Next