Authentication

Sume Developer API requests are authenticated with workspace-scoped API keys created in the API Keys dashboard.

Send an API key

Use a server-side environment variable:

Then send either Bearer auth:

or the API key header:

Both forms are accepted by the current API. Use one consistently in each integration. The Sume CLI defaults to x-api-key and can use Bearer mode when configured.

Send exactly one. A request carrying both Authorization: Bearer and x-api-key is rejected with 401 unauthorized and the message Send only one API key credential. — neither header wins, and the second does not silently shadow the first. This bites gateways and fetch wrappers that add an Authorization header of their own on top of a client that already sends x-api-key; strip one of them rather than relying on a precedence rule that does not exist.

Scope

Sume resolves workspace, owner, and API key metadata from the key. Do not put workspace_id, owner_user_id, or user_id in public API request bodies.

Responses expose key metadata such as id, name, prefix, scopes, and last-used time, but never the full secret.

Scopes are fixed when a key is created and cannot be added later. Keys created before a scope existed do not carry it. In particular, actions:read and actions:write — required by Scheduled via the Actions API — are only minted on keys created after the Actions API-call trigger shipped. An older key returns 403 insufficient_scope on every Action run request; create a new key and rotate to it. The same footgun applies to formats:read / formats:write: a pre-Formats key calling a Format is 403 insufficient_scope, never 404 format_not_found. There is no API to patch scopes onto an existing key.

Server-side proxy pattern

Browser and mobile clients should call your backend. Your backend should attach the Sume API key.

Validate user input and enforce your own authorization before forwarding requests to Sume.

Rotation

Create a replacement key, deploy it to your server, verify GET /v1/me, then revoke the old key from the dashboard. If a key appears in logs or chat history, rotate it.

Safety rules

  • Keep API keys on trusted servers, CI secret stores, or local developer machines.
  • Do not place API keys in frontend JavaScript, mobile apps, support tickets, or screenshots.
  • Treat signed upload and download URLs as temporary secrets.
  • Rotate keys from the dashboard if a key is exposed.
  • Give agents read-only commands first; require explicit confirmation before write or paid generation commands.

Rate limits

Every API key gets a request budget per minute across all of /v1, set by the subscription plan of the workspace the key belongs to. Reads and writes have separate budgets, so a tight status-poll loop cannot 429 your own submits.

PlanWrites per minuteReads per minute
Free1204800
Pro30012000
Startup60024000
Scale120048000
EnterpriseContact salesContact sales

A read is any GET or HEAD — polling status_url, events_url, result_url, listing Formats or runs — plus the two POSTs that submit nothing: /v1/generation/admission-preview and the MCP endpoint itself. Everything else is a write: creating runs, cancelling, uploads. The plan number is the write number; reads get forty times that in their own bucket.

That multiple is sized for agents, not for a human watching one run. An agent harvest can hold twenty-odd jobs open and poll each of them, which is thousands of reads a minute against work that costs nothing — so reads are deliberately cheap and the write budget, the tier a plan actually buys, is left alone.

Enterprise is not self-serve. Until a contracted number is provisioned, an Enterprise key resolves to the Scale row above.

An MCP tool call spends the write budget for the run it creates, once — not for the JSON-RPC request that carried it. A jobs_status poll over MCP spends no write budget at all.

Read ratelimit-remaining rather than counting requests yourself, and back off on retry-after. The headers describe whichever budget the current request spent from, and a 429 names it in error.details.scope (read or write).

Request rate is not the same thing as generation capacity. How many generations run at once is governed separately by your plan's concurrency limit, reported on the generation_limits object; raising your request rate does not raise it.

Every response carries the current state:

HeaderMeaning
ratelimit-limitRequests allowed in the current window.
ratelimit-remainingRequests left in the current window.
ratelimit-resetSeconds until the window resets.
retry-afterSeconds to wait, sent on 429.

Unauthenticated requests are limited per client IP at the Free rate, and their read bucket is held at four times the write rate rather than forty — the agent-sized read budget is for callers who own the jobs they are polling, and widening the anonymous bucket would only widen the abuse surface.

The read multiple is a deployment setting (SUME_COM_API_RATE_LIMIT_READ_MULTIPLIER), so a self-hosted or preview deployment can differ. ratelimit-limit on the response is always the authority for the deployment you are talking to; the table above is the shipped default.

Common failures

StatusCommon causeNext step
401Missing, malformed, or revoked key.Check the header and create a new key if needed.
403Key is valid but not allowed to access the requested surface.Check workspace membership and key scope.
429Rate limit exceeded for your plan's requests-per-minute budget.Back off and retry after retry-after.