Skip to main content
Instead of polling GET /v3/videos/{video_id} for status, you can register a webhook endpoint to receive a POST notification when a video completes, fails, or other events occur. See Webhook Events for the full event catalog and payload shapes.
  • Base path: https://api.heygen.com/v3/webhooks/endpoints

Authentication

Same as the rest of the v3 API — see the API Key guide.

Create an Endpoint

Register a URL to receive webhook events. The response includes a secret for verifying payloads — store it securely, as it will not be shown again. Full schema: POST /v3/webhooks/endpoints.

Request Parameters

List Endpoints

Retrieve all registered endpoints with pagination. Full schema: GET /v3/webhooks/endpoints.
The secret field is only returned when creating an endpoint or rotating the secret. It will be null in list responses.

Update an Endpoint

Change the URL and/or subscribed event types. The events array is fully replaced — include all event types you want to keep. Full schema: PATCH /v3/webhooks/endpoints/{endpoint_id}.
Both fields are optional — include only what you want to change.

Delete an Endpoint

Permanently remove an endpoint. Events will no longer be delivered to this URL. Full schema: DELETE /v3/webhooks/endpoints/{endpoint_id}.

Rotate Signing Secret

Generate a new signing secret for an endpoint. The old secret is invalidated immediately on rotation; deploy the new secret from the response to your verifier promptly. Expect a brief window of failed verifications during rollover — handle this gracefully on the receiver. Full schema: POST /v3/webhooks/endpoints/{endpoint_id}/rotate-secret.

Verifying Payloads

Every webhook delivery includes a signature header derived from your endpoint secret. Always verify before trusting the payload — without verification, anyone who learns your URL can forge events. HeyGen signs the raw request body with HMAC-SHA256 using the endpoint secret returned by Create Endpoint or Rotate Secret. Compute the same digest on your side and compare in constant time.
Verify against the raw body bytes, not a re-serialized JSON object. Any whitespace or key-order change will break the HMAC. In Express, use express.raw(); in Flask, use request.get_data() before request.get_json().

Delivery, retries, and idempotency

  • Success criteria: respond with 2xx within 10 seconds. Slow handlers will be timed out and retried.
  • Retries: failed deliveries are retried with exponential backoff for up to 24 hours.
  • Idempotency / replay defense: a single event can be delivered more than once (retry after a transient failure). De-duplicate on Heygen-Event-Id — this is your primary replay defense, since the signature covers the body only.
  • Stale-delivery rejection: treat Heygen-Timestamp as defense-in-depth — reject deliveries where it’s more than ~5 minutes old. (Not a substitute for event-id dedup: an attacker who captured a valid body could replay it with a fresh timestamp header without breaking the signature.)
For the full list of event types and payload shapes, see Webhook Events.

Using Callbacks Instead

If you don’t need a persistent webhook endpoint, pass a callback_url directly when creating a video — for example via Create Video Agent Session or Create Video Translation. This sends a one-off notification for that specific request without registering an endpoint:
The callback_id is echoed back in the webhook payload so you can correlate the notification with your request.