Overview
Submit a script or audio file to generate an avatar presentation video. The digital avatar lip-syncs to your content and speaks on your behalf.
Primary Endpoint
/api/v1/video/generateGenerate AI video with avatar using audio source and selected avatar. Either audioSrc or custom_voice is required. For background replacement, use back_id for system backgrounds or custom_back_id for backgrounds created by /api/v1/custom_back/add. The avatar must have an original background saved, or the request must provide anchor_background_img or anchor_background_color. ### Request - Send a valid bearer token. The server evaluates the operation in the authenticated caller's access context. - Send an `application/json` body. Required fields: `anchor_id`, `anchor_type`. - API-token callers may include `webhook_url` and `webhook_token` for best-effort terminal-state notifications; ordinary JWT/cookie calls ignore these fields. ### Behavior - This is an asynchronous operation: a successful submission creates a task and returns before processing finishes. - Persist the returned task identifier and use the corresponding detail or list operation to observe progress. - Treat the detail endpoint as the source of truth even when webhook delivery is enabled. ### Response - A `200` response confirms task acceptance; it does not by itself mean media generation has completed. - Retain the returned identifier and wait for a documented terminal status before using output URLs. - JSON object responses, including error responses, normally carry a top-level `trace_id` string for this request; include it when contacting support. It is not a task identifier. - Do not infer undocumented fields or statuses; clients should tolerate additional response properties. ### Errors - `400` — Bad Request - Invalid parameters or missing required audio source. - `401` — Unauthorized - Invalid or missing JWT token. ### Related Operations - `GET /api/v1/video/detail` — detail. Authentication: set header Authorization: Bearer <token> (supports user JWT or sk_ API token).
Request Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| title | string | No | Video title (optional, max 40 characters); maxLength: 40 |
| audioSrc | string | No | Audio source URL (required if custom_voice not provided) |
| custom_voice | string | No | Custom voice audio URL (required if audioSrc not provided) |
| anchor_id | string | Yes | Avatar/anchor ID (MongoDB ObjectId) |
| anchor_type | number | Yes | Avatar type (0 for system avatar, 1 for custom avatar) |
| anchor_background_img | string | No | Original avatar background image URL. Required for background replacement if the avatar record does not already have background_img or background_color. |
| anchor_background_color | string | No | Original avatar background color in RGBA format. Required for background replacement if the avatar record does not already have background_img or background_color. |
| back_id | string | No | System background template ID (MongoDB ObjectId). Mutually exclusive with custom_back_id; sending both returns error 30005. |
| face_swap_id | string | No | Face swap template ID (MongoDB ObjectId) |
| custom_back_id | string | No | Custom background ID returned by /api/v1/custom_back/add (MongoDB ObjectId). Mutually exclusive with back_id; sending both returns error 30005. |
| color | string | No | Color setting in RGBA format |
| wl_model | string | No | Watermark/logo model setting |
| isSkipRs | boolean | No | Skip resolution scaling |
| web_bg_width | number | No | Output canvas/background width. Required when using back_id, custom_back_id, or color.; default: 0 |
| web_bg_height | number | No | Output canvas/background height. Required when using back_id, custom_back_id, or color.; default: 0 |
| web_people_width | number | No | Avatar width in output layout. Required when using back_id, custom_back_id, or color.; default: 0 |
| web_people_height | number | No | Avatar height in output layout. Required when using back_id, custom_back_id, or color.; default: 0 |
| web_people_x | number | No | Avatar X position in web layout; default: 0 |
| web_people_y | number | No | Avatar Y position in web layout; default: 0 |
| web_dist_bg_width | number | No | Distributed background width; default: -1 |
| web_dist_bg_height | number | No | Distributed background height; default: -1 |
| web_dist_bg_x | number | No | Distributed background X position; default: 0 |
| web_dist_bg_y | number | No | Distributed background Y position; default: 0 |
| resolution | number | No | Video resolution (height in pixels); default: 1080 |
| msg | string | No | Additional message or notes |
| erode_factor | number | No | Erosion factor for image processing |
| isSkipGp | boolean | No | Skip green screen processing |
| isCaptionEnabled | boolean | No | Enable captions/subtitles |
| gp_model | object | No | Green screen processing model settings |
| gp_model.compose_mode | string | No | Composition mode |
| gp_model.compose_ratio | number | No | Composition ratio |
| isToPublicPool | boolean | No | Add to public pool for sharing |
| lip_model | string | No | Lip sync model selection |
| captionAlign | object | No | Caption alignment and styling settings |
| captionAlign.language | string | No | Caption language |
| captionAlign.PrimaryColour | string | No | Primary text color in RGBA format |
| captionAlign.title | string | No | Caption title |
| captionAlign.TitleBoxColour | string | No | Title box background color in RGBA format |
| captionAlign.FontName | string | No | Font family name |
| captionAlign.Fontsize | integer | No | Font size in pixels |
| captionAlign.subtitle_position | number | No | Subtitle vertical position (0-1) |
| captionAlign.OutlineColour | string | No | Text outline color in RGBA format |
| captionAlign.BackColour | string | No | Text background color in RGBA format |
| minor_suspected_skip | boolean | No | Set to true when retrying after error code 1004 to confirm and bypass the suspected-minor soft block.; default: false |
| webhook_url | string | No | HTTPS URL to receive task.completed / task.failed notifications. Best-effort delivery, single attempt, no retries; clients should treat the detail API as the source of truth.; maxLength: 2048 |
| webhook_token | string | No | Optional plaintext token returned in the X-A2e-Webhook-Token header so receivers can verify the request originated from a2e.; maxLength: 256 |
Request schema and conditional rules
{
"allOf": [
{
"type": "object",
"properties": {
"title": {
"type": "string",
"maxLength": 40,
"description": "Video title (optional, max 40 characters)",
"example": "My AI Video"
},
"audioSrc": {
"type": "string",
"description": "Audio source URL (required if custom_voice not provided)",
"example": "https://example.com/audio.mp3"
},
"custom_voice": {
"type": "string",
"description": "Custom voice audio URL (required if audioSrc not provided)",
"example": "https://example.com/custom_voice.wav"
},
"anchor_id": {
"type": "string",
"pattern": "^[a-fA-F0-9]{24}$",
"description": "Avatar/anchor ID (MongoDB ObjectId)",
"example": "507f1f77bcf86cd799439011"
},
"anchor_type": {
"type": "number",
"description": "Avatar type (0 for system avatar, 1 for custom avatar)",
"example": 0
},
"anchor_background_img": {
"type": "string",
"description": "Original avatar background image URL. Required for background replacement if the avatar record does not already have background_img or background_color.",
"example": "https://example.com/original-avatar-background.jpg"
},
"anchor_background_color": {
"type": "string",
"description": "Original avatar background color in RGBA format. Required for background replacement if the avatar record does not already have background_img or background_color.",
"example": "rgba(255,255,255,1)"
},
"back_id": {
"type": "string",
"pattern": "^[a-fA-F0-9]{24}$",
"description": "System background template ID (MongoDB ObjectId). Mutually exclusive with custom_back_id; sending both returns error 30005.",
"example": "507f1f77bcf86cd799439012"
},
"face_swap_id": {
"type": "string",
"pattern": "^[a-fA-F0-9]{24}$",
"description": "Face swap template ID (MongoDB ObjectId)",
"example": "507f1f77bcf86cd799439013"
},
"custom_back_id": {
"type": "string",
"pattern": "^[a-fA-F0-9]{24}$",
"description": "Custom background ID returned by /api/v1/custom_back/add (MongoDB ObjectId). Mutually exclusive with back_id; sending both returns error 30005.",
"example": "507f1f77bcf86cd799439014"
},
"color": {
"type": "string",
"description": "Color setting in RGBA format",
"example": "rgba(0,0,0,1)"
},
"wl_model": {
"type": "string",
"description": "Watermark/logo model setting",
"example": "default"
},
"isSkipRs": {
"type": "boolean",
"description": "Skip resolution scaling",
"example": false
},
"web_bg_width": {
"type": "number",
"default": 0,
"description": "Output canvas/background width. Required when using back_id, custom_back_id, or color.",
"example": 1920
},
"web_bg_height": {
"type": "number",
"default": 0,
"description": "Output canvas/background height. Required when using back_id, custom_back_id, or color.",
"example": 1080
},
"web_people_width": {
"type": "number",
"default": 0,
"description": "Avatar width in output layout. Required when using back_id, custom_back_id, or color.",
"example": 800
},
"web_people_height": {
"type": "number",
"default": 0,
"description": "Avatar height in output layout. Required when using back_id, custom_back_id, or color.",
"example": 600
},
"web_people_x": {
"type": "number",
"default": 0,
"description": "Avatar X position in web layout",
"example": 100
},
"web_people_y": {
"type": "number",
"default": 0,
"description": "Avatar Y position in web layout",
"example": 50
},
"web_dist_bg_width": {
"type": "number",
"default": -1,
"description": "Distributed background width",
"example": 1920
},
"web_dist_bg_height": {
"type": "number",
"default": -1,
"description": "Distributed background height",
"example": 1080
},
"web_dist_bg_x": {
"type": "number",
"default": 0,
"description": "Distributed background X position",
"example": 0
},
"web_dist_bg_y": {
"type": "number",
"default": 0,
"description": "Distributed background Y position",
"example": 0
},
"resolution": {
"type": "number",
"default": 1080,
"description": "Video resolution (height in pixels)",
"example": 1080
},
"msg": {
"type": "string",
"description": "Additional message or notes",
"example": "Custom video generation"
},
"erode_factor": {
"type": "number",
"description": "Erosion factor for image processing",
"example": 0.5
},
"isSkipGp": {
"type": "boolean",
"description": "Skip green screen processing",
"example": false
},
"isCaptionEnabled": {
"type": "boolean",
"description": "Enable captions/subtitles",
"example": true
},
"gp_model": {
"type": "object",
"description": "Green screen processing model settings",
"properties": {
"compose_mode": {
"type": "string",
"description": "Composition mode",
"example": "overlay"
},
"compose_ratio": {
"type": "number",
"description": "Composition ratio",
"example": 0.8
}
}
},
"isToPublicPool": {
"type": "boolean",
"description": "Add to public pool for sharing",
"example": false
},
"lip_model": {
"type": "string",
"description": "Lip sync model selection",
"example": "default"
},
"captionAlign": {
"type": "object",
"description": "Caption alignment and styling settings",
"properties": {
"language": {
"type": "string",
"description": "Caption language",
"example": "en"
},
"PrimaryColour": {
"type": "string",
"description": "Primary text color in RGBA format",
"example": "rgba(255,255,255,1)"
},
"title": {
"type": "string",
"description": "Caption title",
"example": "Video Caption"
},
"TitleBoxColour": {
"type": "string",
"description": "Title box background color in RGBA format",
"example": "rgba(0,0,0,0.5)"
},
"FontName": {
"type": "string",
"description": "Font family name",
"example": "Arial"
},
"Fontsize": {
"type": "integer",
"description": "Font size in pixels",
"example": 24
},
"subtitle_position": {
"type": "number",
"description": "Subtitle vertical position (0-1)",
"example": 0.9
},
"OutlineColour": {
"type": "string",
"description": "Text outline color in RGBA format",
"example": "rgba(0,0,0,1)"
},
"BackColour": {
"type": "string",
"description": "Text background color in RGBA format",
"example": "rgba(0,0,0,0.3)"
}
}
},
"minor_suspected_skip": {
"type": "boolean",
"default": false,
"description": "Set to true when retrying after error code 1004 to confirm and bypass the suspected-minor soft block."
}
},
"required": [
"anchor_id",
"anchor_type"
]
},
{
"$ref": "#/components/schemas/WebhookInput"
}
]
}Response Fields
- code: integer
- msg: string
- Audio preflight failures include the source failure reason on both the first attempt and cached failures.
- data: object
- Video generation result
- data.coins: number
- Duration in seconds (cost in coins)
- trace_id: string
- Trace ID of this HTTP request. Include it when contacting support about this request. It is generated per request and is not a task identifier; use the returned task `_id` to query results.
Request Example
curl -X POST "https://headswap.app/api/v1/video/generate" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Avatar video with custom background",
"audioSrc": "https://example.com/audio.mp3",
"anchor_id": "507f1f77bcf86cd799439011",
"anchor_type": 1,
"custom_back_id": "507f1f77bcf86cd799439014",
"anchor_background_color": "rgba(255,255,255,1)",
"resolution": 1080,
"web_bg_width": 1920,
"web_bg_height": 1080,
"web_people_width": 600,
"web_people_height": 1080,
"web_people_x": 660,
"web_people_y": 0
}'Related Endpoints
Responses
Video generation started, or audio preflight rejected with code 10001. Invalid audio URLs are cached for 180 seconds without extending the TTL on repeated requests; a different full URL is probed immediately.
Bad Request - Invalid parameters or missing required audio source
Unauthorized - Invalid or missing bearer token