Webhook endpoint down: redeliver a Sume video job after the retries
Sume retries a job webhook 10 times, 30 seconds apart. If your receiver was down longer, POST /v1/jobs/{id}/webhook/redeliver re-sends the terminal payload.

If your webhook receiver was down when a Sume video job finished, call POST /v1/jobs/{id}/webhook/redeliver with a key that has jobs:write. Sume re-sends the job's real terminal payload, job.completed, job.failed or job.canceled, with a fresh timestamp and a fresh sume-v1 signature, and it works after the automatic attempts are used up.
Automatic delivery tries 10 times, 30 seconds apart, with a 10 second timeout per attempt, so an outage of about five minutes or more can exhaust it. OpenAI's video guide, read 2026-10-08, documents video.completed and video.failed webhooks but I found no redelivery route there.
What redeliver does and refuses
The redelivery does not consume one of the automatic 10 retries. It answers 409 when the job is still running or when it was created without a webhook_url, and 404 for a job you cannot see.
| Situation | Result |
|---|---|
| Job finished, receiver was down | payload re-sent with new timestamp and signature |
| Automatic attempts exhausted | redelivery still works |
| Job still running | 409 |
| Job created without webhook_url | 409 |
| Job from another workspace or member | 404 |
| Key lacks jobs:write | refused; create a key with the scope |
Redeliver a batch after an outage
Find the affected job ids from your own table, or from the jobs list, and redeliver each one. Your handler must dedupe on job_id, since the same terminal event may have arrived once already. Set SUME_API_KEY and pass the ids on the command line.
import os, sys, urllib.error, urllib.request
KEY = os.environ["SUME_API_KEY"]
def redeliver(job_id):
req = urllib.request.Request(
"https://api.sume.com/v1/jobs/" + job_id + "/webhook/redeliver",
method="POST", headers={"Authorization": "Bearer " + KEY})
try:
with urllib.request.urlopen(req) as res:
return res.status
except urllib.error.HTTPError as err:
return err.code
def main():
for job_id in sys.argv[1:]:
print(job_id, redeliver(job_id))
main()Check the delivery history
The job events timeline includes webhook.delivery events with the delivery metadata, so you can see which attempts failed before you redeliver. If the signature check fails on the redelivered body, compare the secret fingerprint rather than rotating blindly; the event mapping post shows the payload your handler should expect.
For a service with only a few jobs a day, polling avoids this class of problem entirely, as the callback or polling post explains.
Sources
Related posts
More in Developers
- waitForJob times out at 20 minutes: why it does not fit a Vercel route
Sume SDK waitForJob waits 20 minutes by default and the job keeps billing if it throws. Vercel functions default to 300 s, so wait in a worker.
- Sume wave_size_hint and a Worker subrequest limit: submit in waves
A Worker fan-out of Sume jobs hits 50 subrequests on Free. Size each wave from generation_limits, not from the hint alone, and stop at queue_capacity_remaining.
- Sume webhook retries: 10 attempts, 30 s apart, 10 s timeout each
The delivery schedule for Sume job webhooks: 10 attempts, fixed 30 s spacing, 10 s timeout, about 4.5 minutes of retries, then redeliver and the status poll.
- Swift: URLSession async/await for one 30-second Wan 3.0 job
A 28-line main.swift that submits wan-3.0 for 30 seconds, polls with Task.sleep and saves the MP4. Runs on macOS or Linux with swiftc.
Written by Sume