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.

5 min readSume
All posts

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.

HeyGen fields from its quick start (read 2026-10-10); Sume fields from the Errors and Jobs docs.
NeedHeyGenSume
Machine-readable reasonfailure_codeerror.code, such as insufficient_credits or rate_limited
Human-readable reasonfailure_messageerror.message
Id for supportNot read from the pageerror.request_id, also in response headers
Where a failed job's reason livesOn the video recordOn the job record (GET /v1/jobs/:id)
Rate-limit waitRetry-Afterretry-after, plus ratelimit-remaining and ratelimit-reset
Rate-limit scopeNot read from the pageerror.details.scope, read or write
Webhook failureNot read from the pagejob.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

All Comparisons posts

Written by Sume