HeyGen webhooks: 10 s ack, 24 h retries vs Sume's 10 attempts

HeyGen retries failed webhooks with exponential backoff for up to 24 hours after a 10 s timeout. Sume retries 10 times, 30 s apart. Read 2026-10-10.

5 min readSume
All posts

HeyGen wants a 2xx within 10 seconds and retries failed deliveries with exponential backoff for up to 24 hours. Sume also allows 10 seconds per attempt, but it retries at a fixed delay (30 seconds by default) up to 10 attempts total, so its automatic window is minutes, not a day. After that, a Sume receiver recovers by polling or by asking for a redeliver.

HeyGen's side is from its Webhooks and Webhook Events pages, read 2026-10-10. Sume's side is the Webhooks page.

The delivery contracts

Both vendors say the same thing about your obligations: acknowledge fast, deduplicate, and do not trust delivery as the only path.

Delivery behavior (HeyGen pages read 2026-10-10; Sume per docs.sume.com/workflows/webhooks)
ItemHeyGenSume
Success2xx within 10 secondsAny 2xx, after you store the event durably
Per-attempt timeout10 seconds10 seconds
Retry scheduleExponential backoff, up to 24 hoursFixed delay, 30 s by default
Attempt capNot a count; bounded by the 24-hour window10 attempts total
DuplicatesA single event may arrive more than onceTreat job_id as the idempotency key
Dedupe keyevent_data.video_id plus event_type, or callback_idjob_id
EndpointPublic HTTPS URLPublic HTTPS URL; localhost and private networks rejected

What the numbers mean in practice

Ten attempts at 30 seconds is roughly four and a half minutes of automatic retries after the first try (nine gaps of 30 seconds, assuming the default spacing and that each attempt fails fast). If your receiver is down for an hour, HeyGen's 24-hour window will usually still deliver once you are back. Sume will have given up, and the job will already be in its real terminal state.

That is why Sume's page keeps repeating the poll fallback. Every submit returns a status_url, and a completed avatar job can be read at GET /v1/jobs/{id}/result whenever you come back. A failed delivery is not a failed job.

Sume adds a lever HeyGen's pages do not describe: POST /v1/jobs/{job_id}/webhook/redeliver (scope jobs:write) re-sends the real terminal event with a fresh timestamp and signature, even after the automatic attempts are spent, and it does not consume one of the ten.

Design the receiver for the shorter window

  • Return 2xx as soon as the event is stored. Do the download, transcode or publish step from a queue, not inside the request, so the 10-second budget is never spent on your own work.
  • Key your store on job_id for Sume and on the video id plus event type for HeyGen. Both vendors can send the same event twice.
  • Run a periodic sweep over jobs without a recorded terminal event and read their status. For avatar videos, GET /v1/avatar-videos?status=processing lists in-flight ones, with limit up to 100.
  • Verify the signature before you act. HeyGen specifies HMAC-SHA256 over the raw body in a signature header; Sume signs <timestamp>.<raw_body>. Neither verifier should accept an empty secret.

Submitting an avatar job with a webhook

On Sume, add mode: "webhook" and a webhook_url to the talking-video request, or send only the URL, which selects webhook mode. Send an Idempotency-Key so a retried submit adopts the first job instead of billing a second one. Generate avatar video has the full body, and Jobs and results explains why polling stays in place beside a webhook.

One more difference worth planning for: HeyGen's Webhook Events page says the download URL in a success payload has a limited expiry window, so fetch and store the file promptly. Sume's webhook payload carries the artifacts of the finished job, with media.sume.com URLs, but you should still copy the finished clip into your own storage at the moment you verify the event, so that a later cleanup on either side never breaks a page that embeds it.

Finally, log the delivery outcome next to the job. Sume records webhook.delivery in the job events at GET /v1/jobs/{id}/events, which is the first place to look when a callback never arrived.

Sources

Related posts

More in Comparisons

All Comparisons posts

Written by Sume