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.

Branch on outcome. A run can complete, bill you and produce real media, then fail to project that media into your output_schema. The envelope status is then still OK, output is null, output_error gives the reason, and outcome is degraded. A handler that reads only status cannot tell ok from degraded.
Events and outcomes
Each run family sends one terminal event, and the outcome is in status and payload.status, not in the event name.
| Field | Values | How to use it |
|---|---|---|
| event | action.run.terminal, format.run.terminal, agent.run.terminal | Route by family |
| status | OK or ERROR | Binary, do not stop here |
| outcome | ok, degraded, error | Branch on this |
| request_id | Equals run_id | Dedupe key, stable across retries |
| created_at | Delivery build time | Order deliveries |
def route(event: dict) -> str:
outcome = event["outcome"]
if outcome == "ok":
return "ship"
if outcome == "degraded":
return "review artifacts: " + str(event["payload"].get("output_error"))
return "retry or alert"
print(route({"outcome": "degraded", "payload": {"output_error": {"code": "x"}}}))
Dedupe and share one handler
Dedupe on the request_id of the envelope. The nested payload.request_id is a correlation id, and it differs between a webhook and a poll read. The webhook payload is the same receipt that GET /v1/{family}-runs/{run_id} returns in data, so one handler can serve both. Details are on the run webhooks page.
Check the docs before you ship
Sume's limits and field names change faster than blog posts do. Read the linked docs pages for the current request fields before you ship, and send a dry_run or a low spend cap on your first real call.
Sources
Related posts
More in Developers
- 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.
- Save a 30-second Wan 3.0 clip to Cloudflare R2 from Node
Fetch a finished Wan 3.0 render from Sume and write it to Cloudflare R2 with the AWS S3 client. Shows the R2 endpoint config and the 30 s price at three tiers.
Written by Sume