Format run completed but output is null: handle outcome degraded

A Sume Format webhook says completed, yet output is null. Outcome degraded means real media is in artifacts and your schema did not match. How to branch.

5 min readSume
All posts

Branch on outcome, not on status. A Sume Format webhook can say status: OK and still carry outcome: degraded. That means the run completed and was billed, real media sits in artifacts[], but output is null because the projection did not match your output_schema. output_error gives the reason.

The four outcomes

Read from docs.sume.com/formats/runs on 2026-10-05
outcomeMeaningDo this
okCompleted with outputUse output
degradedCompleted and billed; media in artifacts[]; output is nullRead output_error, then use primary_output_url or artifacts[]
errorThe run did not completeRead error.code
(canceled, skipped)No webhook is sentHandle on the call that caused it

Why a good video can have a null output

Sume builds output from what the run made and said. If you bind a strict schema, the result must fit it. When the video exists but the object does not fit, the run keeps the media and drops the object rather than discarding paid work. The billed amount in usage is still real.

A handler that does not lose the video

Route on event (always format.run.terminal), dedupe on request_id, then branch on outcome. The payload under payload is byte-identical to data from GET /v1/format-runs/{run_id}, so one handler serves a webhook and a poll.

def handle(event):
    p = event["payload"]
    if event["outcome"] == "ok":
        return p["output"]
    if event["outcome"] == "degraded":
        urls = [a["url"] for a in p["artifacts"]]
        print("schema miss:", p.get("output_error"))
        return {"fallback_urls": urls}
    raise RuntimeError(event["error"]["code"])

print(handle({"outcome": "degraded", "payload": {
    "artifacts": [{"url": "https://media.sume.com/artifacts/artf_x/full_video.mp4"}],
    "output_error": "schema mismatch"}}))

What a retry should and should not do

Do not re-run a degraded item just to get a clean output. The video is already made and billed, so a second run is a second charge for the same media. Fetch the receipt from result_url, take primary_output_url or the artifacts[] URLs, and store them.

If you do need the typed object, you can continue the earlier run as one more turn of the same conversation with previous_run_id, and ask for the missing fields. It is still a new run, so give it a new idempotency key and its own cap.

Read from docs.sume.com/formats/runs on 2026-10-05
Field on the receiptWhere it helps
primary_output_urlThe one URL you serve, when you set primary_output_key
artifacts[]All media the run made, also on a failed run
output_errorWhy the projection did not match your schema
usageWhat the run billed, also on a degraded run

Fix the schema, not the run

A degraded run points at a schema that asks for more than the Format can give. Loosen the required keys, or use primary_output_key so primary_output_url still resolves. The rules and failure modes are on the structured output page.

If the payload is over 1 MiB, payload is null, error.code is payload_too_large, and error.result_url is where you fetch it.

Related posts

More in Formats

All Formats posts

Written by Sume