This workflow corresponds to n8n.io template #12392 — we link there as the canonical source.
This workflow follows the Google Drive → HTTP Request 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "e0df8071-816b-4710-a2f7-37ce251b993d",
"name": "Search Pixabay Videos",
"type": "n8n-nodes-base.httpRequest",
"position": [
32,
720
],
"parameters": {
"url": "https://pixabay.com/api/videos/",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "queryAuth",
"queryParameters": {
"parameters": [
{
"name": "key",
"value": "=API_Key"
},
{
"name": "q",
"value": "={{ $json.topic }}"
},
{
"name": "per_page",
"value": "={{ $json.numberOfClips }}"
},
{
"name": "video_type",
"value": "all"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "3cbcab1c-bd0a-4948-b489-cbb0e30fb883",
"name": "Upload Voiceover to Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
96,
1136
],
"parameters": {
"name": "=voiceover_{{ $now.toFormat('yyyy-MM-dd_HH-mm-ss') }}.mp3",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "12d930fb-b4fe-4dca-9d8c-b1c9139d0abf",
"name": "Make Voiceover Public",
"type": "n8n-nodes-base.googleDrive",
"position": [
560,
1152
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "share",
"permissionsUi": {
"permissionsValues": {
"role": "reader",
"type": "anyone"
}
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3,
"alwaysOutputData": true
},
{
"id": "0647ab34-57fb-4c85-9793-221e2d288acd",
"name": "Set Video Parameters1",
"type": "n8n-nodes-base.set",
"position": [
-208,
720
],
"parameters": {
"values": {
"string": [
{
"name": "topic",
"value": "productivity business workflow"
},
{
"name": "videoDuration",
"value": "300"
},
{
"name": "numberOfClips",
"value": "10"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "a8e6a227-25c2-44d2-b82e-a2975389981d",
"name": "Extract Video URLs1",
"type": "n8n-nodes-base.code",
"position": [
288,
720
],
"parameters": {
"jsCode": "// Extract video URLs from Pixabay response\nconst videos = $input.item.json.hits;\nconst clips = [];\n\nif (!videos || videos.length === 0) {\n throw new Error('No videos found for this search term');\n}\n\nfor (let i = 0; i < videos.length; i++) {\n const video = videos[i];\n \n // Get the largest available video (usually 'large' or 'medium')\n const videoUrl = video.videos?.large?.url || video.videos?.medium?.url || video.videos?.small?.url;\n \n if (videoUrl) {\n clips.push({\n url: videoUrl,\n duration: video.duration || 15, // Default to 15 seconds if not provided\n id: video.id,\n width: video.videos?.large?.width || 1920,\n height: video.videos?.large?.height || 1080\n });\n }\n}\n\nif (clips.length === 0) {\n throw new Error('No valid video URLs found');\n}\n\nreturn clips.map(clip => ({ json: clip }));"
},
"typeVersion": 2
},
{
"id": "4e1a1d7e-32c5-4dce-9326-e428bbc28726",
"name": "Build Shotstack JSON1",
"type": "n8n-nodes-base.code",
"position": [
-512,
1520
],
"parameters": {
"jsCode": "// Get video clips from input\nconst clips = $input.all().map(item => item.json);\n\n// Get the voiceover file ID from Google Drive (Download file node)\nconst driveFileId = $('Upload Voiceover to Drive').first().json.id;\n\n// Build the direct download URL for the voiceover\nconst voiceoverUrl = `https://drive.google.com/uc?export=download&id=${driveFileId}`;\n\n// Define different transitions for variety\nconst transitions = [\n \"fade\",\n \"wipeRight\",\n \"slideLeft\",\n \"slideUp\",\n \"carouselLeft\",\n \"zoom\",\n \"shuffleTopRight\",\n \"wipeLeft\",\n \"slideDown\",\n \"carouselRight\"\n];\n\n// Calculate clip durations with overlap for smooth transitions\nconst totalDuration = 300; // 5 minutes\nconst transitionDuration = 0.8; // 0.8 second overlap for smooth effect\nconst clipDuration = (totalDuration + (transitionDuration * (clips.length - 1))) / clips.length;\n\n// Build Shotstack timeline\nconst timeline = {\n soundtrack: {\n src: voiceoverUrl,\n effect: \"fadeInFadeOut\",\n volume: 1.0\n },\n tracks: [\n {\n clips: clips.map((clip, index) => ({\n asset: {\n type: \"video\",\n src: clip.url\n },\n start: (index * clipDuration) - (index * transitionDuration),\n length: clipDuration,\n fit: \"crop\",\n scale: 1,\n transition: {\n in: transitions[index % transitions.length], // Different transition for each clip\n out: transitions[index % transitions.length]\n }\n }))\n }\n ]\n};\n\nconst render = {\n timeline: timeline,\n output: {\n format: \"mp4\",\n resolution: \"hd\",\n fps: 25,\n quality: \"high\"\n }\n};\n\nreturn [{ json: render }];"
},
"typeVersion": 2
},
{
"id": "8f667238-4772-49da-b87a-cfe1268bc67c",
"name": "Submit Render Job1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-304,
1520
],
"parameters": {
"url": "https://api.shotstack.io/v1/render",
"method": "POST",
"options": {
"timeout": 30000
},
"jsonBody": "={{ JSON.stringify($json) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.1
},
{
"id": "b621ddd3-bb77-4bfe-b971-90a8b9fc5235",
"name": "Wait for Render1",
"type": "n8n-nodes-base.wait",
"position": [
-80,
1520
],
"parameters": {
"unit": "seconds",
"amount": 60
},
"typeVersion": 1
},
{
"id": "dcee4f08-8fa0-40a0-b322-705e2e7dc486",
"name": "Check Render Status1",
"type": "n8n-nodes-base.httpRequest",
"position": [
144,
1520
],
"parameters": {
"url": "=https://api.shotstack.io/v1/render/{{ $json.response.id }}",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.1
},
{
"id": "e0661ddf-4fd3-4557-93c2-10164f0dba9b",
"name": "Is Render Complete?1",
"type": "n8n-nodes-base.if",
"position": [
368,
1520
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.success }}",
"value2": "true",
"operation": "contains"
}
]
}
},
"typeVersion": 1
},
{
"id": "c2a7b00a-e04d-4fa5-acd6-fb990d26a2d1",
"name": "Download Final Video1",
"type": "n8n-nodes-base.httpRequest",
"position": [
576,
1504
],
"parameters": {
"url": "={{ $json.response.url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.1
},
{
"id": "8f380822-c062-4a5f-89b8-cbae36fdd363",
"name": "Save to Google Drive1",
"type": "n8n-nodes-base.googleDrive",
"position": [
768,
1504
],
"parameters": {
"name": "=final_video_{{ $now.toFormat('yyyy-MM-dd_HH-mm-ss') }}.mp4",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1ymC_Lf5Zi7wf3EsMIEV687PMclAnDlkV",
"cachedResultUrl": "https://drive.google.com/drive/folders/1ymC_Lf5Zi7wf3EsMIEV687PMclAnDlkV",
"cachedResultName": "Archive"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "e1ec0625-0ba5-4775-a33f-031c3ba7b7e9",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-544,
720
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.3
},
{
"id": "80aadbba-398a-4efb-8442-3cd3b85e1251",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
-128,
1136
],
"parameters": {
"url": "https://api.elevenlabs.io/v1/text-to-speech/kPzsL2i3teMYv0FxEYQ6",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $json.choices[0].message.content }}"
},
{
"name": "voice_settings.stability",
"value": "0.5"
},
{
"name": "voice_settings.similarity_boost",
"value": "0.75"
},
{
"name": "voice_settings.style",
"value": "0.0"
},
{
"name": "voice_settings.use_speaker_boost",
"value": "true"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "15d24fcc-af7d-4063-8432-f6c8540b5957",
"name": "Generate Script2",
"type": "n8n-nodes-base.openAi",
"position": [
-368,
1136
],
"parameters": {
"prompt": {
"messages": [
{
"role": "assistant",
"content": "Write a 5-minute long YouTube script that explains the real value of automation in everyday life and business. The output must be written exactly as spoken words, in a natural conversational tone. Do not include titles, headings, timestamps, bullet points, or instructions. Do not mention tools, brands, or technical jargon unless necessary. Focus on practical insights, relatable examples, and mindset shifts rather than technical steps. Explain how automation saves time, reduces mental load, improves consistency, and creates leverage. Use simple examples from daily routines and small business workflows. Speak as a calm, confident automation expert educating a general audience. End with a soft reflective closing that encourages viewers to rethink how they spend their time. Output only the spoken script, nothing else."
}
]
},
"options": {},
"resource": "chat",
"requestOptions": {},
"simplifyOutput": false
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "918f977f-08e7-4a69-96f4-429b251ef2af",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
624,
736
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 3.2
},
{
"id": "7b62b71e-b0e1-4bd7-b2f6-6f9d9257ec99",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
320,
1136
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "e1af0446-15fa-446b-9260-a1b894446916",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
624
],
"parameters": {
"color": 7,
"width": 1600,
"height": 368,
"content": "## 1. Choose video clips"
},
"typeVersion": 1
},
{
"id": "37635102-4ec4-470c-a8e4-64af1c8eeffa",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1328,
640
],
"parameters": {
"width": 624,
"height": 672,
"content": "## Automated YouTube Video Creator with AI Voiceover, Pixabay Videos to Drive\n\n## How it works\n- **Schedule Trigger** node to run the workflow\n- **Set** node is to set video parameters\n- The **HTTP request** nodes are for the API calls to [Pixabay](https://pixabay.com/) for videos, [Elevenlabs](https://elevenlabs.io/) for voiceover and [Shotstack](https://dashboard.shotstack.io/keys) for rendering. Also have one to download the video \n- **Code** nodes are used to extract video and for video configuration. \n- **Merge** voiceover and video section\n- **OpenAI** node to generate voice script and send to [Elevenlabs](https://elevenlabs.io/)\n- **Google Drive** nodes are to store the voice and video for access\n- **Loop over items** is used to loop with Google Drive to make the voiceover public\n- The **Wait** node is for delay\n- **If** node to check if render is complete\n\n## Setup\n1. Get [Pixabay](https://pixabay.com/api/docs/) API\n2. Get [Elevenlabs](https://elevenlabs.io/app/speech-synthesis/speech-to-speech) API and set in Header Auth\n3. Get [Shotstack](https://dashboard.shotstack.io/keys) API\n4. Get [OpenAI](https://platform.openai.com/settings/) Key and set in credentials\n5. Go to [Google Cloud](https://console.cloud.google.com/) and enable the Google Drive API. Then set credentials\n6. Set prompt in the OpenAI node (see example in node)\n7. Set video topic (see example in the set node) "
},
"typeVersion": 1
},
{
"id": "315383f4-ceaa-40f8-bd9e-87a51ee166e0",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
1408
],
"parameters": {
"color": 7,
"width": 1600,
"height": 368,
"content": "## 3. Create video and store in Google Drive"
},
"typeVersion": 1
},
{
"id": "03d47cf3-956e-425a-bab9-c83b738b66b5",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
1008
],
"parameters": {
"color": 7,
"width": 1600,
"height": 384,
"content": "## 2. Generate voiceover "
},
"typeVersion": 1
}
],
"connections": {
"Merge": {
"main": [
[
{
"node": "Build Shotstack JSON1",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Upload Voiceover to Drive",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
],
[
{
"node": "Make Voiceover Public",
"type": "main",
"index": 0
}
]
]
},
"Generate Script2": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Set Video Parameters1",
"type": "main",
"index": 0
},
{
"node": "Generate Script2",
"type": "main",
"index": 0
}
]
]
},
"Wait for Render1": {
"main": [
[
{
"node": "Check Render Status1",
"type": "main",
"index": 0
}
]
]
},
"Submit Render Job1": {
"main": [
[
{
"node": "Wait for Render1",
"type": "main",
"index": 0
}
]
]
},
"Extract Video URLs1": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Check Render Status1": {
"main": [
[
{
"node": "Is Render Complete?1",
"type": "main",
"index": 0
}
]
]
},
"Is Render Complete?1": {
"main": [
[
{
"node": "Download Final Video1",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait for Render1",
"type": "main",
"index": 0
}
]
]
},
"Build Shotstack JSON1": {
"main": [
[
{
"node": "Submit Render Job1",
"type": "main",
"index": 0
}
]
]
},
"Download Final Video1": {
"main": [
[
{
"node": "Save to Google Drive1",
"type": "main",
"index": 0
}
]
]
},
"Make Voiceover Public": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Search Pixabay Videos": {
"main": [
[
{
"node": "Extract Video URLs1",
"type": "main",
"index": 0
}
]
]
},
"Set Video Parameters1": {
"main": [
[
{
"node": "Search Pixabay Videos",
"type": "main",
"index": 0
}
]
]
},
"Upload Voiceover to Drive": {
"main": [
[
{
"node": "Loop Over Items",
"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.
googleDriveOAuth2ApihttpHeaderAuthopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Complete YouTube video automation workflow that creates ready-to-upload videos from start to finish. No manual editing required.
Source: https://n8n.io/workflows/12392/ — 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.
This comprehensive n8n automation template orchestrates a complete end-to-end workflow for generating engaging short-form Point-of-View (POV) style videos using multiple AI services and automatically
YouTube Automation Pipeline - Notion + Gemini + CometAPI + JSON2Video. Uses notion, httpRequest, googleDrive, writeBinaryFile. Scheduled trigger; 43 nodes.
Google Drive → AI Video Generation → Captions → Approval → Instagram & TikTok
Shopify Lifestyle Video (prototipal) copy 2. Uses httpRequest, facebookGraphApi, openAi, googleDrive. Scheduled trigger; 23 nodes.
Virtual-Weather-Caster-Workflow. Uses httpRequest, googleDrive, openAi, gmail. Scheduled trigger; 20 nodes.