Before you can generate video with a digital twin (type: "digital_twin"), HeyGen needs proof that the person depicted agreed to be cloned. This protects the avatar subject, your account, and HeyGen — and it’s what lets you use a real person’s likeness responsibly at scale.
The consent API step applies only to digital twin avatars. A group created from a photo (
type: "photo") or prompt (type: "prompt") has no consent request to make and reports consent_status of null. If you add a photo or prompt look to an existing group, it retains that group’s consent status.A photo avatar is still built from a real person’s image. Having no API step to complete is not permission to use someone’s likeness. HeyGen runs no consent check and keeps no consent record for a photo avatar, so getting the subject’s agreement before you create one, and keeping your own record of it, is your responsibility. Your account team can answer questions about your contract terms.The three levels of access
Consent is offered as three increasing levels of access. Each level removes friction from the flow, and each is unlocked for a progressively narrower set of accounts. Higher levels are more powerful and correspondingly more restricted.Collect consent via API
One endpoint drives both Level 1 and Level 2:POST /v3/avatars/{group_id}/consent. By default it starts the webcam flow and returns a URL for the avatar subject — the link is valid for 24 hours; enterprise accounts can pass a pre-recorded consent_video instead.
Record via webcam (Level 1)
reroute_url is where the subject lands after completing consent (HeyGen’s own completion page by default). The response carries the avatar_group, with consent_status of pending, and the consent page url to send to the subject. Call the endpoint again for a fresh link once it expires. consent_status then moves to accepted (consent cleared) or rejected (resubmit).
Upload a consent video (Level 2)
Enterprise accounts can submit a pre-recorded consent statement directly — same endpoint, withconsent_video in place of the flow parameters:
consent_video takes {"type": "url", "url": "https://..."} or {"type": "asset_id", "asset_id": "..."} (see Upload Assets).
The video is submitted immediately for review — the subject never visits a consent page, so the response contains the avatar_group alone and no url. Because there is no hosted page in this flow, send consent_video on its own, without the webcam-flow parameters. This flow is enterprise-only — please reach out to sales or your account team to request access.
What the consent video must contain
Because the upload flow has no hosted page prompting the subject, you provide the statement yourself. Consent is validated semantically, so minor wording differences are fine, and the statement can be in any language. Translate it however fits your subject. The current recommended statement:“Hey there! I’m speaking with LOTS of energy, while staying natural and confident. This helps HeyGen capture my voice, my expressions, and my motion, so my avatar can behave JUST like me in ANY video!”
Record the consent clip separately from the training footage. Training footage works best at about 2 minutes of natural talking (see Footage that trains well), while the consent clip must be under 35 seconds.
Track the result
There is no webhook for consent. Pollconsent_status on the group with GET /v3/avatars/{group_id} after submitting; review usually completes within a few minutes. The status belongs to the group, not the individual look. The instant_avatar.success and instant_avatar.fail webhook events report twin training, not consent.
When consent_status is rejected, the group’s status is failed, and error carries code moderation_failed with a message in plain language you can show the subject, such as “Please make sure your consent video is under 35s.”
Resubmit after a rejection
You can callPOST /v3/avatars/{group_id}/consent again for a group whose consent_status is rejected, with a new webcam link or a new consent_video. While a submitted consent video is still under review, the endpoint returns a 400 asking you to wait, and once consent is accepted it returns a 400 because consent is already complete. Send the Idempotency-Key header so a network retry does not create a second submission.

