Run create 503 studio_agent_upstream_timeout: the run may exist
A 502 or 503 on a Sume run create can mean the run already exists and is spending. Retry with the same Idempotency-Key and the original run is replayed.

Most 503 responses mean nothing happened, so a retry is harmless. One does not. On a run-create route, Sume documents that a 503 can also mean the control plane that owns Format and run state did not answer in time. In that case error.public_reason is studio_agent_upstream_timeout, retryable is true, and details.retry_with_idempotency_key is set. The run may already exist, and it may already be spending.
Two 503s that look alike
The code studio_agent_upstream_unavailable means the control plane is unreachable or not configured. That is a Sume-side condition, and the API key is not at fault. Re-issuing the key will not help.
The timeout variant is different. The request reached the control plane, which may have created the run before the reply was lost. If you retry without a key, you can start a second run and pay for both.
The rule: always send a key on run create
Send Idempotency-Key on every run create and retry with the same value. A replay returns the existing run rather than a second one. You can set the key as the header or as an idempotency_key body field, up to 255 characters. Derive it from your own business id, so a restarted worker computes the same key.
KEY="order-8823-lc-v1"
for attempt in 1 2 3 4; do
code=$(curl -sS -o /tmp/run.json -w '%{http_code}' \
-X POST "https://api.sume.com/v1/formats/acme/live-commerce/runs" \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"instruction":"Make the 9:16 spot"}')
case "$code" in 200|201|202) break;; 502|503) sleep $((attempt * 5));; *) break;; esac
done
cat /tmp/run.jsonWhat a replay looks like
If the first attempt did create a run, the second call returns that run, not a new one. If you sent the same key with a different body, you get a 409 idempotency_conflict, which tells you the key was already used. Do not rotate the key to get past it.
If you ran without a key and cannot tell whether a run exists, list your runs with GET /v1/formats/{handle}/{slug}/runs and check for one created in the last minutes before you retry. Cancel any duplicate at POST /v1/format-runs/{run_id}/cancel.
Sources
Related posts
More in Developers
- Sume run webhook outcome degraded: status OK but output is null
A Sume run webhook can say status OK and still carry output null. Branch on outcome (ok, degraded, error), not status, and dedupe on the envelope request_id.
- First MCP call: Runway whoami vs Sume account_me and mcp_health
Runway says verify its dev MCP with whoami. On Sume, call mcp_health for endpoint and auth source, then account_me for the workspace; both are read only.
- Runway polls at 5s with jitter; Sume gives next_poll_after_seconds
Runway says poll at 5 seconds or more with jitter and backoff. Sume returns next_poll_after_seconds, so your loop can obey the server instead of guessing.
- One Idempotency-Key for an Omni 360p draft and 720p final: it 409s
Reusing the draft's Idempotency-Key on the 720p final returns 409 idempotency_conflict. Key naming that keeps draft and final jobs apart, with a Python helper.
Written by Sume