HeyGen callback_url vs a signed Sume webhook for a finished video
HeyGen lets you pass callback_url to skip polling. Sume adds mode webhook with a public HTTPS webhook_url and signs each delivery, so verify it.

HeyGen's quick start says you can pass callback_url instead of polling for a result. Sume's equivalent for a model job is mode: "webhook" with a webhook_url, and the delivery is one of three terminal events: job.completed, job.failed or job.canceled. The difference that matters is trust: when signing is configured Sume signs the raw body with HMAC-SHA256 over <timestamp>.<raw_body>, so a receiver can prove a delivery came from Sume before it moves money or publishes a video.
HeyGen source: API quick start, read 2026-10-04. The quick start page does not describe how callbacks are signed, so this post makes no claim about that. Sume sources: Webhooks and Run webhooks.
What each page tells you
HeyGen documents both ways to finish: poll the session and video endpoints, or pass a callback. Sume documents event names, the payload and the headers, and it states that URLs must be public HTTPS; localhost, private networks and plain HTTP are rejected.
| Item | HeyGen | Sume |
|---|---|---|
| Opt in | callback_url on create | mode: webhook plus webhook_url |
| Events | Not listed on the page read | job.completed, job.failed, job.canceled |
| Signature | Not described on the page read | HMAC-SHA256 over <timestamp>.<raw_body> when signing is configured |
| URL rules | Not described on the page read | Public HTTPS only |
| Keep polling too | Page offers polling as the alternative | Docs advise a polling fallback beside the webhook |
Your receiver, in order
Verify the signature against the raw bytes, answer with a 2xx quickly, store the event, then do the work. A webhook can be delivered more than once, so use job_id as the idempotency key. For Format runs the event is format.run.terminal and the payload is the whole run receipt; the signature scheme is the same, so one verifier covers both.
- Reject an empty secret at start-up, not at request time.
- Reject timestamps more than five minutes old.
- Compare signatures in constant time.
- Never parse the body before you have verified it.
Keep a poll as a safety net
A receiver can be down for a deploy. Keep one slow poll for jobs older than a few minutes, and after you fix your endpoint use POST /v1/jobs/{job_id}/webhook/redeliver, which re-sends the real terminal event with a fresh timestamp and signature. Format runs have their own redeliver, documented on Run webhooks. The webhook is a convenience; the job id remains the source of truth.
Bottom line
Both vendors let you skip polling. Sume's page gives you what you need to authenticate the callback. Whichever you use, treat the callback as a hint to fetch the result, not as the result itself.
Sources
Related posts
More in Developers
- A holiday ad brief as one JSON file that drives every Sume call
Keep one JSON brief with the product, offer, date and ratios, and have a script read it for each Sume call so every asset says the same thing.
- How big is a 3-minute Short at YouTube's 8 Mbps? About 189 MB
A 180-second 1080p Short at YouTube's 8 Mbps video and 384 kbps audio is about 189 MB. Here is the arithmetic, the TikTok ad caps, and the Sume probe field.
- How do I know a new TTS model is available on Sume?
Every week brings a new voice model. The live answer is one GET request: list the TTS Router catalog. What an unknown id returns, and how to avoid hard-coding.
- How long AI video vendors keep your file: Veo 2 days, Higgsfield 7+
Veo keeps videos two days, Higgsfield files at least seven, Sora Batch outputs were kept 24 hours. Retention facts and a download-on-complete script.
Written by Sume