HeyGen failure_code and failure_message vs Sume job error
A failed HeyGen video carries failure_code and failure_message; a failed Sume job has an error object and a request id. How to log both the same way.

HeyGen tells you why a video failed through failure_code and failure_message on the video record; Sume gives a failed job a public error object, and every error response carries a request_id you can hand to support. If you log failures from both, store the code, the message and the id under the same three column names so one dashboard query covers either vendor.
HeyGen's fields are from its quick start, read 2026-10-10. Sume's are from the Errors and rate limits and Jobs and results pages.
What each side hands back
The HeyGen page says that when you poll /v3/videos/{video_id} the status ends as completed or failed, and that failures carry failure_code and failure_message. It also mentions a Retry-After header on rate limiting. I did not read a list of failure codes on that page, so I do not list any.
Sume's error envelope is { "error": { "code", "message", "request_id", "details" } }. A failed job reached a terminal failure with a public error, readable from the job record: the docs' own client loop reads job.error after a failed or canceled status.
| Need | HeyGen | Sume |
|---|---|---|
| Machine-readable reason | failure_code | error.code, such as insufficient_credits or rate_limited |
| Human-readable reason | failure_message | error.message |
| Id for support | Not read from the page | error.request_id, also in response headers |
| Where a failed job's reason lives | On the video record | On the job record (GET /v1/jobs/:id) |
| Rate-limit wait | Retry-After | retry-after, plus ratelimit-remaining and ratelimit-reset |
| Rate-limit scope | Not read from the page | error.details.scope, read or write |
| Webhook failure | Not read from the page | job.failed with status: ERROR and an error object |
A common log row
Pick three fields: vendor_code, vendor_message and vendor_request_id. For HeyGen fill the first two from failure_code and failure_message and leave the third empty. For Sume fill them from error.code, error.message and error.request_id. Keep the job or video id in a fourth column.
Do not put signed URLs or API keys in those columns. Sume's docs say a request id is safe to share with support and that keys, signed URLs, raw media URLs and private workspace ids should stay out of reports.
Which failures to retry
For Sume, a 429 rate_limited means wait for retry-after and send again; a 429 queue_full means the workspace's generation capacity is full, so back off for longer; a 402 insufficient_credits means top up first. A 400 means the request itself is wrong, and repeating it will not help. When a job has already been accepted, never submit a new paid request for the same intent; poll the existing one, and reuse the same Idempotency-Key if you retry the submit.
The HeyGen page I read gave Retry-After but no code table, so I cannot say which of its failures are safe to repeat. Read its error documentation before you write retry logic against it.
Alerting on the shared columns
Once both vendors write the same three columns, one query can show the top codes per vendor per day. Watch for a code that suddenly dominates, since that usually points at one broken input, such as an unreachable media URL or a script that is too long, not at a vendor outage. A spike of Sume 429 rate_limited with scope write means you are submitting too fast for your plan, while a spike with scope read means a polling loop is too tight.
Keep the raw envelope for a short time as well, because the fields you did not map are the ones you will want when a failure is new. Redact keys and signed links before it reaches storage.
Sources
Related posts
More in Comparisons
- 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.
- HeyGen webhook secret shown once: rotation vs Sume's reveal
HeyGen shows its webhook secret once and drops the old one on rotate. Sume lets you re-read it and signs with both secrets while rotating (read 2026-10-10).
- How long do Sume webhooks retry? About three hours vs Stripe
Sume makes up to 10 delivery attempts with exponential backoff capped at an hour, about three hours in all. Stripe retries for up to three days in live mode.
- Longest single shot per request: Vidu, Veo, Grok, Wan, Seedance
How long one request can run: Vidu Q4 16 s, Veo 8 s, Grok 15 s, Wan 3.0 and Seedance 2.5 30 s. Sume's matching row for each and the longest-shot cost.
Written by Sume