Which Sume key scope starts a Format, schedule or agent run
formats:write starts a Format run, actions:write a schedule run, agent_completions:write an agent run. Older keys lack them, and service keys can't start some.

Three scopes start three kinds of agent work on Sume: formats:write starts a Format run, actions:write starts a schedule (Action) run, and agent_completions:write starts an Agent Completion. Each has a matching :read scope for reading runs. Keys created before a scope shipped do not have it, and you cannot add scopes to an existing key.
The usual cause of a 403
A 403 insufficient_scope on a create almost always means the key, not the body. The docs say the same for Format runs and schedule runs: an older key fails each run request, and the fix is to create a new key in the dashboard and rotate to it. Service-account keys cannot create Format runs or Action runs, and fail with the same code and a reason in details.
Three scopes, three starts
Here are the three side by side, so you can pick the right key before you wire up a job.
| Work | Start endpoint | Needs | Overlap setting | Spend cap |
|---|---|---|---|---|
| Format run | POST /v1/formats/{handle}/{slug}/runs | formats:write | on_active_run: allow, skip, reject; default allow | Format cap, default $400; per run up to $500 |
| Schedule run | POST /v1/actions/{action_id}/runs | actions:read and actions:write | on_active_run: skip or reject; default skip | Default $1.00; a run can only lower it |
| Agent Completion | POST /v1/agent/completions | agent_completions:write | Not applicable | Required on every request |
Defaults that differ
The defaults point in different directions, which is the second trap. A Format run defaults to allow, so two calls run side by side. A schedule defaults to skip, so a second start while one is running is recorded as skipped. The docs warn not to copy a scheduled body into a Format call for that reason.
Check a key before you deploy
The script below tests a key before a deploy. It sends a Format run with a body that cannot start a run, and reads only the status code: a 403 means the key lacks the scope, and a 400 means the scope is present and the empty body was refused. The documented empty-body rule is that {} is 400 invalid_request, so nothing runs and nothing is charged.
import json, os, urllib.error, urllib.request
req = urllib.request.Request(
"https://api.sume.com/v1/formats/sume/sume-product-commercial/runs",
data=b"{}",
method="POST",
headers={
"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "scope-probe-1",
},
)
try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
body = json.load(e)
print(e.code, json.dumps(body)[:300])Reading the probe
Read the output as a probe, not a run. A 400 is the good answer here. If you see 403, create a new key with the scopes you need, keep the old one until the cutover, and then revoke it.
Habits
Keep one key per job type, name it for the job, and rotate it on a schedule you can remember. A key with only formats:write cannot start a schedule, and that is the point.
Sources
Related posts
More in Agents
- Why the Sume API hides a schedule's instructions text
GET /v1/actions returns the cron, model, cap and schema of a Sume schedule but not its instructions text. Read and edit instructions in the dashboard.
- Agent Completion 400: generation_spend_cap_usd has no default
Your POST to /v1/agent/completions returns 400? generation_spend_cap_usd is required and has no default. Add it, and pick a number from a real run.
- assets_download_url MCP tool: a short-lived link for an uploaded asset
The hosted MCP tool assets_download_url returns a short-lived signed URL for a first-party asset. Use it only when asked, and never echo the URL in a report.
- Captions drift after cutting pauses: burn them on the final render
Cut pauses first, then caption. Word times from the original clip no longer match once silence is gone. Run Sume video-captions on the trimmed render.
Written by Sume