Handing a Format to another team: the API key checklist
Before another workspace calls your Sume Format, check key scope, key type, the API tab, the spend cap and the webhook secret. Lists each 403/409.

Before another team calls your Sume Format over the API, check five things: the key carries formats:write, it is a user key and not a service-account key, it was created in the workspace that owns the Format if that is a team, the owner left the Format's API trigger on, and the run has a spend cap you chose. Each missing item has a distinct error, so you can test the hand-off with one dry call.
The facts are from Create a run and Errors and spend. I list the error for each gap so a contractor can diagnose their own first failure.
Gap by gap
Run this table top to bottom with the person who will hold the key. The status codes are the ones the docs give for each case.
| Gap | What the caller sees | Fix |
|---|---|---|
| Key predates the Formats API, so it lacks the scopes | 403 insufficient_scope, never a 404 | Mint a new key and rotate to it |
| Service-account key | 403 insufficient_scope, reason service_account_format_runs_unsupported | Use a user key |
| Team Format, personal key | 403 workspace_key_required, details.workspace_id names the workspace | Create the key in that team workspace |
| Format status inactive, or API trigger off | 409 format_inactive or format_api_trigger_disabled | The owner changes it on the Format's API tab |
| Shared Format, wrong workspace | 404, indistinguishable from an unknown handle | Accept the grant in the caller's workspace |
| Empty body | 400 invalid request: needs instruction, input, previous_run_id or attachments | Send at least one |
Who pays and who decides
Billing follows the key. A team Format's runs bill the team wallet and count against the team's generation concurrency, which is why a personal key is refused for it. The docs add that, in the past, a personal key produced runs that made a real video and then reported output_schema_unsatisfied with nothing harvested.
When you share a Format with another workspace, the owner still decides whether the Format accepts API calls. Its status and API-call trigger apply to every caller, including the workspaces you shared it with, and the caller's key lists only its own runs.
Set the money limits on purpose
A Format has a default generation spend cap of $400 when it never named one. A call can set generation_spend_cap_usd per run, up to $500, and zero is rejected. Tell the contractor which number to send, because a run that tries to spend past its cap fails with the generic format_run_failed.
Add an Idempotency-Key rule to the hand-off too. The docs scope a key to one Format and recommend deriving it from the item the run makes plus a version, so a retry never double-bills.
Results without polling
Give the caller the webhook options early. A format.run.terminal delivery needs a public HTTPS endpoint and a signing secret, and the caller verifies the signature over the raw body. Send a test delivery before the first real run so a wrong secret shows up on a free call. Canceled and skipped runs never deliver, so the caller still needs a status poll as a fallback.
Finish with one real run on a cheap input, and check three fields on the receipt: status, usage.debited_usd_micros, and output.
Sources
Related posts
More in Formats
- How many Format runs can one API key poll at once?
Read budgets per minute by Sume plan, turned into a count of Format runs you can poll at 5-second and 30-second intervals, and why a bulk queue saves writes.
- Is there an endpoint to list all Format runs? No, build an index
Sume lists runs per Format with a cursor, but there is no GET /v1/format-runs across Formats. Here is the small run index that fills the gap, and what to store.
- Make a partial Format result legal in your output_schema
Sume Format output_schema has no optional properties. Use nullable unions, SumeMediaFile refs and honest nulls so a run that makes 2 of 3 clips still returns.
- Re-run a Format on purpose: version the Idempotency-Key
How Sume Format idempotency works, why a fresh uuid per request defeats it, and how an order id plus a version number gives safe retries and deliberate re-runs.
Written by Sume