This workflow corresponds to n8n.io template #8622 — we link there as the canonical source.
This workflow follows the HTTP Request → YouTube recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "OxdUBxc7llHmoDZx",
"name": "My workflow 3",
"tags": [],
"nodes": [
{
"id": "4a993817-3909-4d2b-b7ef-f2b9f34dea76",
"name": "Sticky - Webhook Contract & Security",
"type": "n8n-nodes-base.stickyNote",
"position": [
-336,
48
],
"parameters": {
"content": "Inbound trigger for external start. Validate secret; parse JSON; return 200 immediately."
},
"typeVersion": 1
},
{
"id": "ddb50403-dc30-4068-9c40-0022f222b748",
"name": "WebHook",
"type": "n8n-nodes-base.webhook",
"position": [
-96,
96
],
"parameters": {
"path": "52048302-06bd-4eae-9b004c5ed17d",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "2322ee6b-3f5a-46d4-95b2-3ac405711621",
"name": "Sticky - Normalize Text for TTS",
"type": "n8n-nodes-base.stickyNote",
"position": [
32,
16
],
"parameters": {
"height": 224,
"content": "Sanitize the video script to ensure HeyGen can use that correctly."
},
"typeVersion": 1
},
{
"id": "58891633-6f20-4d91-99f9-6f72cfd0336b",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
128,
96
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const item = $input.item;\nreturn { json: { content: item.json.body.content.replaceAll(\"\\n\", \"\").replaceAll(\"\\r\", \"\"), title:item.json.body.title } };"
},
"typeVersion": 2
},
{
"id": "2cc0fe4b-a229-4937-a8b7-d6ed766aee6b",
"name": "Sticky - Parameter Staging (Secrets & IDs)",
"type": "n8n-nodes-base.stickyNote",
"position": [
304,
-16
],
"parameters": {
"height": 320,
"content": "Init vars (script, voice_id, avatar_id, aspect, sub=false); set defaults."
},
"typeVersion": 1
},
{
"id": "86024350-5e49-43a6-a98f-f3cc0ad63abf",
"name": "Setup Heygen Parameters",
"type": "n8n-nodes-base.set",
"disabled": true,
"position": [
384,
96
],
"parameters": {
"fields": {
"values": [
{
"name": "x-api-key"
},
{
"name": "voice_id"
},
{
"name": "avatar_id"
},
{
"name": "title",
"stringValue": "={{ $json.title }}"
},
{
"name": "content",
"stringValue": "={{ $json.content }}"
}
]
},
"options": {}
},
"typeVersion": 3
},
{
"id": "f1fa5816-f371-4a91-8eed-fca27399b46f",
"name": "Sticky - Create HeyGen Job (v2)",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
-16
],
"parameters": {
"width": 208,
"height": 288,
"content": "Submit video generation request to HeyGen using API: POST /v2/video/generate with params."
},
"typeVersion": 1
},
{
"id": "970c4d5f-0ba5-4b3e-9b0b-d6edb8821f9b",
"name": "Create Avatar Video (HeyGen)",
"type": "n8n-nodes-base.httpRequest",
"position": [
608,
96
],
"parameters": {
"url": "https://api.heygen.com/v2/video/generate",
"method": "POST",
"options": {},
"jsonBody": "={\n \"video_inputs\": [\n {\n \"character\": {\n \"type\": \"avatar\",\n \"avatar_id\": \"{{ $json.avatar_id }}\",\n \"avatar_style\": \"normal\"\n },\n \"voice\": {\n \"type\": \"text\",\n \"input_text\": \"{{ $json.content }}\",\n \"voice_id\": \"{{ $json.voice_id }}\",\n \"speed\": 1.1\n }\n }\n ],\n \"dimension\": {\n \"width\": 1280,\n \"height\": 720\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "X-Api-Key",
"value": "={{ $json['x-api-key'] }}"
}
]
}
},
"typeVersion": 4
},
{
"id": "ff31c0bd-26af-4065-8e7f-9910955e5326",
"name": "Sticky - Polling Cycle",
"type": "n8n-nodes-base.stickyNote",
"position": [
784,
0
],
"parameters": {
"width": 208,
"height": 272,
"content": "Delay polling to avoid rate limits; increase wait for long video generations"
},
"typeVersion": 1
},
{
"id": "2661127a-2c82-4a88-9336-0a04df5eddb3",
"name": "Wait for Video (HeyGen)",
"type": "n8n-nodes-base.wait",
"position": [
832,
96
],
"parameters": {
"unit": "minutes",
"amount": 0.1
},
"typeVersion": 1
},
{
"id": "36b2a0f9-84d4-4b1d-b61b-f2233b28ffe2",
"name": "Get Avatar Video Status (HeyGen)",
"type": "n8n-nodes-base.httpRequest",
"position": [
1056,
96
],
"parameters": {
"url": "https://api.heygen.com/v1/video_status.get",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"queryParameters": {
"parameters": [
{
"name": "video_id",
"value": "={{ $('Create Avatar Video (HeyGen)').item.json.data.video_id }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "X-Api-Key",
"value": "={{ $('Setup Heygen Parameters').item.json['x-api-key'] }}"
}
]
}
},
"typeVersion": 4
},
{
"id": "37a4815e-7562-4764-8883-03e2502a897a",
"name": "If Processing Completed",
"type": "n8n-nodes-base.if",
"position": [
1264,
96
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "2b0f3da8-9f60-4a14-af38-8064531cf6d4",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.data.status }}",
"rightValue": "processing"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "7de09738-3b54-4b96-a46d-65c85767da8e",
"name": "Sticky - Download Result (Binary)",
"type": "n8n-nodes-base.stickyNote",
"position": [
1424,
-16
],
"parameters": {
"height": 256,
"content": "If status is not 'processing' -> Try to download; if download fails it means the video generation in HeyGen errored for whatever reason."
},
"typeVersion": 1
},
{
"id": "a97d12ea-8280-41bc-a415-42df2083c017",
"name": "Download Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
1488,
96
],
"parameters": {
"url": "={{ $json.data.video_url }}",
"options": {}
},
"typeVersion": 4
},
{
"id": "d2f7447a-232a-4817-89ef-b2058d570643",
"name": "Sticky - YouTube Upload (Binary Property & Metadata)",
"type": "n8n-nodes-base.stickyNote",
"position": [
1680,
0
],
"parameters": {
"width": 224,
"height": 240,
"content": "Upload the video (downloaded data) to Youtube."
},
"typeVersion": 1
},
{
"id": "6056c5ef-2c7f-47fd-b75c-0cf3ad286997",
"name": "Upload a video",
"type": "n8n-nodes-base.youTube",
"position": [
1712,
96
],
"parameters": {
"title": "={{ $('Setup Heygen Parameters').item.json.title }}",
"options": {},
"resource": "video",
"operation": "upload",
"categoryId": "28",
"regionCode": "US"
},
"credentials": {
"youTubeOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2ee94e2e-531d-40d7-8d83-0a805b96b3b4",
"name": "Sticky - Polling Cycle1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1008,
0
],
"parameters": {
"width": 208,
"height": 272,
"content": "Get status of the generated video from HeyGen."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "e8f0e6b5-b9a0-4b09-8106-2e326dbd3f14",
"connections": {
"Code": {
"main": [
[
{
"node": "Setup Heygen Parameters",
"type": "main",
"index": 0
}
]
]
},
"WebHook": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Download Video": {
"main": [
[
{
"node": "Upload a video",
"type": "main",
"index": 0
}
]
]
},
"If Processing Completed": {
"main": [
[
{
"node": "Download Video",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait for Video (HeyGen)",
"type": "main",
"index": 0
}
]
]
},
"Setup Heygen Parameters": {
"main": [
[
{
"node": "Create Avatar Video (HeyGen)",
"type": "main",
"index": 0
}
]
]
},
"Wait for Video (HeyGen)": {
"main": [
[
{
"node": "Get Avatar Video Status (HeyGen)",
"type": "main",
"index": 0
}
]
]
},
"Create Avatar Video (HeyGen)": {
"main": [
[
{
"node": "Wait for Video (HeyGen)",
"type": "main",
"index": 0
}
]
]
},
"Get Avatar Video Status (HeyGen)": {
"main": [
[
{
"node": "If Processing Completed",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
youTubeOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates the process of creating an AI-generated avatar video using HeyGen and directly uploading it to YouTube. By sending text input via a webhook, the workflow generates a video with a chosen avatar and voice, waits for processing, downloads the completed file,…
Source: https://n8n.io/workflows/8622/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Automated n8n workflow: Receives videos via form, dubs/translates them to the selected languages, and—upon completion—uploads them to multiple social media channels and cloud drives, including Box, Dr
My workflow 3. Uses httpRequest, youTube. Webhook trigger; 17 nodes.
Instagram - Fluxo de mensagens. Uses rabbitmq, rabbitmqTrigger, googleSheets, httpRequest. Webhook trigger; 74 nodes.
Are you a cord-cutter? Do you find yourself looking through the many titles of videos uploaded to Youtube, just to find the ones you want to watch? Even when you subscribe to the channels you like, do
Video explanation