This workflow follows the Execute Workflow Trigger → 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 →
{
"name": "02 - Video Pipeline",
"nodes": [
{
"parameters": {},
"name": "Execute Workflow Trigger",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
250,
300
],
"typeVersion": 1.1
},
{
"parameters": {
"method": "GET",
"url": "={{ $json.link }}",
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"name": "Fetch Article",
"type": "n8n-nodes-base.httpRequest",
"position": [
450,
300
],
"typeVersion": 1
},
{
"parameters": {
"dataType": "json",
"options": {}
},
"name": "HTML to Text",
"type": "n8n-nodes-base.extractFromFile",
"position": [
650,
300
],
"typeVersion": 1
},
{
"parameters": {
"method": "POST",
"url": "https://openrouter.ai/api/v1/chat/completions",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"contentType": "json",
"body": {
"model": "google/gemini-2.0-flash-exp:free",
"messages": [
{
"role": "system",
"content": "You are a professional news script writer for 'The Update Desk' YouTube channel. Write engaging, factual news scripts in a broadcast news style."
},
{
"role": "user",
"content": "=Write a compelling news script based on this article:\n\nTitle: {{ $json.title }}\nSource: {{ $json.source }}\nContent: {{ $json.content }}\n\nRequirements:\n- Target length: 12-20 minutes of speech (very flexible based on story complexity)\n- Style: Professional news anchor, conversational yet authoritative\n- Structure: Hook intro (30s) \u2192 Context background (2-3min) \u2192 Main story development (6-12min) \u2192 Analysis/implications (3-5min) \u2192 Outro (30s)\n- Include specific visual cues for B-roll\n- Add lower third text suggestions\n- Optimize for YouTube virality: strong hook, clear narrative arc, memorable takeaways\n\nReturn JSON format:\n{\n \"youtubeTitle\": \"Viral-optimized title under 60 chars\",\n \"description\": \"SEO description with timestamps\",\n \"tags\": [\"tag1\", \"tag2\", \"tag3\"],\n \"segments\": [\n {\n \"type\": \"intro|background|development|analysis|outro\",\n \"script\": \"Spoken text...\",\n \"visualType\": \"stock_video|seedance|web_image|generated_image|static_title\",\n \"visualQuery\": \"Search query or prompt\",\n \"lowerThird\": \"Lower third text\",\n \"duration\": 120\n }\n ]\n}"
}
]
},
"options": {}
},
"name": "Generate Script",
"type": "n8n-nodes-base.httpRequest",
"position": [
950,
300
],
"typeVersion": 1
},
{
"parameters": {
"jsCode": "// Parse LLM response and prepare segments\nconst response = $input.all()[0].json;\nlet scriptData;\n\ntry {\n // Try to parse from content\n const content = response.choices?.[0]?.message?.content || response.content || response;\n const jsonMatch = content.match(/```json\\n?([\\s\\S]*?)\\n?```/) || content.match(/{[\\s\\S]*}/);\n scriptData = JSON.parse(jsonMatch ? jsonMatch[1] || jsonMatch[0] : content);\n} catch (e) {\n // Fallback structure\n scriptData = {\n youtubeTitle: 'Breaking News Update',\n description: 'Latest news from The Update Desk',\n tags: ['news', 'breaking'],\n segments: [{\n type: 'intro',\n script: 'Welcome to The Update Desk.',\n visualType: 'static_title',\n visualQuery: 'news studio',\n lowerThird: 'BREAKING NEWS',\n duration: 60\n }]\n };\n}\n\n// Add metadata\nreturn {\n ...scriptData,\n articleTitle: $input.all()[0].json.title,\n articleUrl: $input.all()[0].json.link,\n articleSource: $input.all()[0].json.source,\n timestamp: new Date().toISOString(),\n videoId: Math.random().toString(36).substring(7)\n};"
},
"name": "Parse Script",
"type": "n8n-nodes-base.code",
"position": [
1250,
300
],
"typeVersion": 2
},
{
"parameters": {
"jsCode": "// Split into individual items for each segment\nconst data = $input.all()[0].json;\nconst segments = data.segments || [];\n\nreturn segments.map((segment, index) => ({\n ...segment,\n videoId: data.videoId,\n youtubeTitle: data.youtubeTitle,\n description: data.description,\n tags: data.tags,\n articleTitle: data.articleTitle,\n articleUrl: data.articleUrl,\n segmentIndex: index,\n totalSegments: segments.length\n}));"
},
"name": "Split Segments",
"type": "n8n-nodes-base.code",
"position": [
1450,
300
],
"typeVersion": 2
},
{
"parameters": {
"method": "POST",
"url": "https://render-service-production-3b75.up.railway.app/generate-image",
"body": {
"prompt": "={{ $json.visualQuery }}",
"output": "=/files/images/{{ $json.videoId }}_{{ $json.segmentIndex }}.jpg",
"model": "black-forest-labs/flux.2-klein-4b",
"aspectRatio": "16:9"
},
"options": {}
},
"name": "Generate Thumbnail",
"type": "n8n-nodes-base.httpRequest",
"position": [
1650,
200
],
"typeVersion": 1
},
{
"parameters": {
"method": "POST",
"url": "https://api.speechify.ai/v1/audio/stream",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"contentType": "json",
"body": {
"input": "={{ $json.script }}",
"voice_id": "nick",
"model": "simba-english",
"audio_format": "mp3",
"options": {
"text_normalization": false,
"loudness_normalization": true
}
},
"options": {}
},
"name": "Generate TTS",
"type": "n8n-nodes-base.httpRequest",
"position": [
1650,
400
],
"typeVersion": 1
},
{
"parameters": {
"method": "POST",
"url": "https://render-service-production-3b75.up.railway.app/fetch-visual",
"body": {
"type": "={{ $json.visualType === 'stock_video' ? 'pexels' : $json.visualType === 'web_image' ? 'web' : 'pexels' }}",
"query": "={{ $json.visualQuery }}",
"output": "=/files/video/{{ $json.videoId }}_{{ $json.segmentIndex }}.mp4"
},
"options": {}
},
"name": "Fetch Visual",
"type": "n8n-nodes-base.httpRequest",
"position": [
1850,
400
],
"typeVersion": 1
},
{
"parameters": {
"method": "POST",
"url": "https://render-service-production-3b75.up.railway.app/generate-seedance",
"body": {
"prompt": "={{ $json.visualQuery }}",
"output": "=/files/video/{{ $json.videoId }}_{{ $json.segmentIndex }}_seedance.mp4",
"duration": 8,
"width": 1280,
"height": 720
},
"options": {}
},
"name": "Generate Seedance",
"type": "n8n-nodes-base.httpRequest",
"position": [
1850,
600
],
"typeVersion": 1
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.visualType }}",
"rightValue": "seedance",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
"name": "Is Seedance?",
"type": "n8n-nodes-base.if",
"position": [
1650,
550
],
"typeVersion": 2
},
{
"parameters": {
"jsCode": "// Aggregate all segment results\nconst allSegments = $input.all();\nconst videoId = allSegments[0].json.videoId;\n\n// Build render manifest\nconst manifest = {\n output: `/files/output/${videoId}.mp4`,\n segments: allSegments.map(item => ({\n type: item.json.type || 'segment',\n audio: `/files/audio/${videoId}_${item.json.segmentIndex}.mp3`,\n visual: item.json.visualPath || `/files/video/${videoId}_${item.json.segmentIndex}.mp4`,\n lowerThird: item.json.lowerThird,\n title: item.json.type === 'intro' ? item.json.youtubeTitle : undefined\n })),\n music: '/files/audio/background_music_1.mp3',\n musicVolume: 0.15,\n thumbnail: {\n output: `/files/images/${videoId}_thumb.jpg`,\n title: allSegments[0].json.youtubeTitle,\n image: `/files/images/${videoId}_0.jpg`,\n style: 'viral-news'\n }\n};\n\nreturn {\n ...manifest,\n youtubeTitle: allSegments[0].json.youtubeTitle,\n description: allSegments[0].json.description,\n tags: allSegments[0].json.tags,\n videoId\n};"
},
"name": "Build Manifest",
"type": "n8n-nodes-base.code",
"position": [
2050,
400
],
"typeVersion": 2
},
{
"parameters": {
"method": "POST",
"url": "https://render-service-production-3b75.up.railway.app/render",
"body": {
"output": "={{ $json.output }}",
"segments": "={{ $json.segments }}",
"music": "={{ $json.music }}",
"musicVolume": "={{ $json.musicVolume }}",
"thumbnail": "={{ $json.thumbnail }}"
},
"options": {}
},
"name": "Render Video",
"type": "n8n-nodes-base.httpRequest",
"position": [
2250,
400
],
"typeVersion": 1
},
{
"parameters": {
"method": "GET",
"url": "https://render-service-production-3b75.up.railway.app/status/{{ $json.jobId }}",
"options": {}
},
"name": "Poll Render Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
2450,
400
],
"typeVersion": 1
},
{
"parameters": {
"amount": 10,
"unit": "seconds"
},
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
2650,
400
],
"typeVersion": 1
},
{
"parameters": {
"workflowId": "=03 - YouTube Publisher",
"mode": "trigger"
},
"name": "Publish to YouTube",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
2850,
400
],
"typeVersion": 1.1
}
],
"connections": {
"Execute Workflow Trigger": {
"main": [
[
{
"node": "Fetch Article",
"type": "main",
"index": 0
}
]
]
},
"Fetch Article": {
"main": [
[
{
"node": "HTML to Text",
"type": "main",
"index": 0
}
]
]
},
"HTML to Text": {
"main": [
[
{
"node": "Generate Script",
"type": "main",
"index": 0
}
]
]
},
"Generate Script": {
"main": [
[
{
"node": "Parse Script",
"type": "main",
"index": 0
}
]
]
},
"Parse Script": {
"main": [
[
{
"node": "Generate Thumbnail",
"type": "main",
"index": 0
},
{
"node": "Split Segments",
"type": "main",
"index": 0
}
]
]
},
"Split Segments": {
"main": [
[
{
"node": "Generate TTS",
"type": "main",
"index": 0
},
{
"node": "Is Seedance?",
"type": "main",
"index": 0
}
]
]
},
"Generate TTS": {
"main": [
[
{
"node": "Fetch Visual",
"type": "main",
"index": 0
}
]
]
},
"Fetch Visual": {
"main": [
[
{
"node": "Build Manifest",
"type": "main",
"index": 0
}
]
]
},
"Generate Seedance": {
"main": [
[
{
"node": "Build Manifest",
"type": "main",
"index": 0
}
]
]
},
"Is Seedance?": {
"main": [
[
{
"node": "Generate Seedance",
"type": "main",
"index": 0
}
],
[
{
"node": "Fetch Visual",
"type": "main",
"index": 0
}
]
]
},
"Build Manifest": {
"main": [
[
{
"node": "Render Video",
"type": "main",
"index": 0
}
]
]
},
"Render Video": {
"main": [
[
{
"node": "Poll Render Status",
"type": "main",
"index": 0
}
]
]
},
"Poll Render Status": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Publish to YouTube",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
02 - Video Pipeline. Uses executeWorkflowTrigger, httpRequest. Event-driven trigger; 16 nodes.
Source: https://github.com/nickaisbitt/vidomator/blob/154414693c2f673f3222778ffdb821493f9130e0/n8n-workflows/02-video-pipeline.json — 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 template is a powerful, reusable utility for managing stateful, long-running processes. It allows a main workflow to be paused indefinitely at "checkpoints" and then be resumed by external, async
Upload files from any source to your account Kommo or AmoCRM with a simple and reusable workflow. It can split a large file into small ones and upload chunks. Works for Kommo and amoCRM There are 3 re
Remixed Backup your workflows to GitHub from Solomon's work. Check out his templates.
Remixed Backup your workflows to GitHub from Solomon's work. Check out his templates.
This workflow audits your SharePoint Online environment for external sharing risks by identifying files and folders that are shared with anonymous links or external/guest users. It is designed to trav