Agent skill
HeyGen Webhooks Skill
Receive and verify HeyGen webhooks. Use when setting up HeyGen webhook endpoints, debugging the `signature` header HMAC-SHA256 verification, or handling AI video events like avatar_video.success, avatar_video.fail, video_translate.success, or video_translate.fail.
Install this skill
npx skills add hookdeck/webhook-skills --skill heygen-webhooks
When to Use This Skill
- How do I receive HeyGen webhooks?
- How do I verify the HeyGen webhook
signatureheader? - How do I know when a HeyGen avatar video has finished rendering (
avatar_video.success)? - How do I handle
video_translate.successorvideo_translate.failevents? - Why is my HeyGen webhook signature verification failing?
Verification (core)
HeyGen sends the signature in a header literally named signature: the hex-encoded HMAC-SHA256 of the raw request body, with no timestamp and no prefix. The key is the endpoint secret returned when you create the endpoint (it looks like whsec_k7x9m2...), used whole, as a UTF-8 string.
This is NOT Standard Webhooks. Do not use the
standardwebhooksorsvixlibraries, and do not strip thewhsec_prefix or base64-decode the secret. There are nowebhook-id/webhook-timestamp/webhook-signatureheaders.
const crypto = require('crypto');
function verifyHeyGenSignature(rawBody, signature, secret) {
if (!signature || !secret) return false;
const expected = crypto
.createHmac('sha256', secret) // secret as-is, including "whsec_"
.update(rawBody) // raw Buffer, not parsed JSON
.digest('hex');
const a = Buffer.from(expected);
const b = Buffer.from(signature.trim().toLowerCase());
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
HeyGen has no webhook-verification SDK, so all three examples verify manually. Read the raw body first (in Express, express.raw({ type: '*/*' }) so any content type verifies).
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
The event type is in the payload's event_type field and the data is in event_data.
| Event | Triggered When |
|---|---|
avatar_video.success | An avatar video finished rendering (event_data.video_id, url, callback_id, ...) |
avatar_video.fail | Avatar video generation failed |
video_translate.success | A video translation completed |
video_translate.fail | A video translation failed |
video_agent.success / video_agent.fail | A Video Agent session completed / failed |
For the full event list (GIF, caption, avatar training, proofread, live avatar, ...), see references/overview.md and HeyGen's webhook events docs.
Environment Variables
# Signing secret returned once by POST /v3/webhooks/endpoints (or rotate-secret)
HEYGEN_WEBHOOK_SECRET=whsec_your_endpoint_secret
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 heygen --path /webhooks/heygen
Reference Materials
- references/overview.md - HeyGen webhook concepts, event list, payload shape
- references/setup.md - Register endpoints via the v3 API, get and rotate the secret
- references/verification.md - Signature verification details and gotchas