Format run webhook_delivery status: what each value means
A Format run receipt carries webhook_delivery with six statuses: not_armed, pending, retrying, delivered, failed, exhausted. Read them to decide on a redeliver.

Every receipt for a Format run created with a webhook_url carries a webhook_delivery block, and its status is one of not_armed, pending, retrying, delivered, failed or exhausted. Only the last two mean Sume gave up; the first four need no action from you, and none of them ever changes the run itself.
That last point is the one to hold on to. Ten refused attempts leave you with a failed delivery and a run that is still completed, with its output waiting at result_url.
The six values
not_armed is the one people misread. It means the URL is stored and nothing is scheduled yet because the run is still going. A support dashboard that flags not_armed as broken will light up on every healthy run in flight.
| Status | Meaning | Your move |
|---|---|---|
| not_armed | URL stored, run still going | Wait |
| pending | Armed, next_attempt_at is when the next attempt is due | Wait |
| retrying | An attempt failed, another is scheduled | Check last_status_code only if it points at your endpoint |
| delivered | Your endpoint answered 2xx | Nothing |
| failed | Sume gave up | Read the receipt from result_url, fix the endpoint, redeliver |
| exhausted | Sume gave up after the attempts ran out | Same as failed |
Fields that explain a failure
The block also reports attempts against max_attempts (10), last_attempt_at, last_status_code and last_error. last_error is Sume's transport error, never your response body. A success is any 2xx within 10 seconds; redirects are not followed, so a 3xx is a failed attempt, and the URL is validated again at delivery time.
Retries back off with the longer of exponential delay (30 seconds times 2 to the power attempt minus 1, with jitter) and your Retry-After on a 429 or 503, capped at one hour. The signing fingerprint is on the block too, as signing_secret_fingerprint, which you compare with the one on the dashboard's Webhooks tab when signatures fail.
def delivery_action(receipt):
block = receipt.get("webhook_delivery")
if block is None:
return "no webhook registered, poll status_url"
status = block["status"]
if status in ("not_armed", "pending"):
return "wait"
if status == "retrying":
code = block.get("last_status_code")
return f"retrying, last status {code}"
if status == "delivered":
return "done"
return "fetch result_url and redeliver after fixing the endpoint"
Replay once the endpoint is fixed
POST /v1/format-runs/{run_id}/webhook/redeliver with formats:write and an empty body re-sends the current receipt with a fresh timestamp and signature. It does not consume one of the ten automatic attempts. You get 409 webhook_not_configured when the run had no URL and 409 run_not_terminal while it is still running.
A canceled or skipped run never delivers, so webhook_delivery will not move for them. For those, read the receipt that the cancel call or the create response already returned.
Sources
Related posts
More in Developers
- frame_images needs frame_type: first_frame or last_frame on Sume
Each frame_images entry on POST /v1/videos needs a frame_type. What the two values mean, how supported_frame_images limits them, and a pre-check.
- Gemini CLI settings.json httpUrl, timeout and includeTools for Sume
Gemini CLI's MCP entry takes httpUrl, headers, a 600000 ms timeout and includeTools. Set up Sume's hosted server with a read-only tool list and one credential.
- Gemini Live Translate transcripts as subtitles: you supply timing
Google's Live Translate can return input and output transcripts, but the page lists no word times. To burn subtitles, time each line, then send cues to Sume.
- Gemini Omni edit 400: aspect_ratio is not supported, framing is kept
Sending aspect_ratio with a video_url edit on gemini-omni-flash-1.1 returns a 400 on Sume. Why the output keeps the source framing and what to send.
Written by Sume