n8n-nodes-tornado-api
v1.1.0
Published
n8n node for Tornado API - Download TBs of YouTube videos & Spotify podcasts with advanced features
Downloads
417
Maintainers
Readme
🌪️ Tornado API for n8n
Download YouTube videos & Spotify podcasts directly in your n8n workflows.
What's New in v1.1.0
- 🎬 Video Clipping: Extract segments with
clip_startandclip_endtimestamps - 📺 Live Stream Recording: Record live streams with
live_recording,live_from_start,max_duration - 📊 Resolution Selection: Limit quality with
max_resolution(4K, 1080p, 720p, etc.) - 📈 Dashboard Resource: New operations for stats, daily metrics, cluster activity, billing
- 🔔 Enhanced Webhook Trigger: New events (
batch_completed,progress) andjob_idfilter - ⚡ Progress Webhooks: Get real-time updates during download/mux/upload stages
Installation
Via npm (recommended)
cd ~/.n8n/custom
npm install n8n-nodes-tornado-apiVia Docker
docker run -it --rm -p 5678:5678 \
-v n8n_data:/home/node/.n8n \
-v /path/to/n8n-nodes-tornado-api:/home/node/.n8n/custom/n8n-nodes-tornado-api \
n8nio/n8nCredentials Setup
- Go to Credentials → New
- Search for Tornado API
- Enter your API Key (starts with
sk_) - Base URL:
https://tornado.velys.software(default)
Operations
Job → Create
Creates a download job. Returns immediately with a job_id.
Input: | Field | Type | Required | Description | |-------|------|----------|-------------| | URL | string | ✅ | YouTube or Spotify URL | | Format | select | ❌ | mp4, mkv, webm, mov | | Video Codec | select | ❌ | copy, h264, h265, vp9 | | Audio Codec | select | ❌ | copy, aac, opus, mp3 | | Audio Bitrate | select | ❌ | 64k to 320k | | Video Quality | number | ❌ | CRF 0-51 (lower = better) | | Filename | string | ❌ | Custom filename | | Folder | string | ❌ | S3 folder prefix | | Webhook URL | string | ❌ | Notification URL | | Audio Only | boolean | ❌ | Extract audio only | | Download Subtitles | boolean | ❌ | Download subtitles | | Download Thumbnail | boolean | ❌ | Download thumbnail | | Quality Preset | select | ❌ | highest, high, medium, low, lowest | | Max Resolution | select | ❌ | best, 2160, 1440, 1080, 720, 480, 360 | | Clip Start | string | ❌ | Start timestamp (HH:MM:SS or seconds) | | Clip End | string | ❌ | End timestamp (HH:MM:SS or seconds) | | Live Recording | boolean | ❌ | Enable live stream mode | | Live From Start | boolean | ❌ | Record from stream beginning | | Max Duration | number | ❌ | Max recording duration (seconds) | | Wait for Video | boolean | ❌ | Wait for scheduled streams | | Enable Progress Webhook | boolean | ❌ | Receive progress updates |
Output (YouTube):
{
"job_id": "550e8400-e29b-41d4-a716-446655440000"
}Output (Spotify Show):
{
"batch_id": "550e8400-e29b-41d4-a716-446655440001",
"total_episodes": 142,
"episode_jobs": ["job-1", "job-2", "..."]
}Job → Get Status
Check the current status of a job.
Input: | Field | Type | Required | |-------|------|----------| | Job ID | string | ✅ |
Output:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://youtube.com/watch?v=...",
"status": "Completed",
"s3_url": "https://your-bucket.s3.amazonaws.com/videos/video.mp4?X-Amz-Algorithm=...",
"step": "Finished",
"error": null
}Dashboard Operations (NEW in v1.1.0)
Monitor your Tornado API usage directly from n8n.
Dashboard → Get Stats
Get aggregated statistics for your API key.
Output:
{
"total_jobs": 1523,
"pending_jobs": 5,
"processing_jobs": 12,
"completed_jobs": 1450,
"failed_jobs": 56,
"storage_used_gb": 50.0,
"avg_processing_time_seconds": 45.2
}Dashboard → Get Daily Stats
Get job statistics for the last 7 days.
Output:
{
"daily_stats": [
{ "date": "2024-01-08", "completed": 45, "failed": 2 },
{ "date": "2024-01-09", "completed": 62, "failed": 5 }
]
}Dashboard → Get Cluster Stats
Get real-time cluster activity.
Output:
{
"total_downloading": 45,
"total_muxing": 12,
"total_uploading": 8
}Dashboard → Get Billing
Get Stripe billing information.
Output:
{
"billing_enabled": true,
"total_usage_gb": 45.67,
"period_start_formatted": "Jan 01, 2024",
"period_end_formatted": "Feb 01, 2024"
}🔔 Webhook Trigger (NEW events in v1.1.0)
Listen for Tornado events in real-time.
| Event | Description | |-------|-------------| | Job Completed | When a job finishes successfully | | Job Failed | When a job fails | | Batch Completed | When all episodes in a batch are done | | Progress Update | Real-time progress (downloading, muxing, uploading) | | Any Event | Trigger on all events |
Filter Options:
- Filter by Job ID
- Filter by Batch ID
Example Progress Webhook Payload:
{
"type": "progress",
"job_id": "550e8400-...",
"stage": "muxing",
"progress_percent": 33
}📦 S3 Storage - How It Works
Default Flow
1. You create a job → Tornado downloads the video
2. Video is uploaded to S3 → Tornado generates a presigned URL
3. You get the s3_url → Valid for 24 hoursThe s3_url Field
When a job completes, you receive a presigned S3 URL:
{
"s3_url": "https://bucket.s3.region.amazonaws.com/videos/my-video.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=..."
}This URL:
- ✅ Can be downloaded directly (no auth needed)
- ✅ Works in browsers, wget, curl
- ✅ Valid for 24 hours
- ❌ Expires after 24h (request new URL via Get Status)
Using s3_url in n8n
Download the file:
HTTP Request node:
- Method: GET
- URL: {{ $json.s3_url }}
- Response: FileSend to user:
Telegram/Slack/Discord node:
- File URL: {{ $json.s3_url }}Save to Google Drive:
Google Drive node:
- Upload from URL: {{ $json.s3_url }}🔄 Workflow Examples
Example 1: Simple YouTube Download with Polling
Use n8n's Wait and IF nodes to poll for job completion:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Trigger │ → │ Tornado API │ → │ Wait │ → │ Tornado API │ → │ IF │
│ (Manual) │ │ Job:Create │ │ (5 sec) │ │ Job:Status │ │ Completed? │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ ▲ │
▼ │ ▼
{ job_id: ... } Loop back { s3_url: ... }Node 1 - Tornado API (Create):
- Resource: Job
- Operation: Create
- URL:
https://youtube.com/watch?v=dQw4w9WgXcQ
Node 2 - Wait:
- Wait Time: 5 seconds
Node 3 - Tornado API (Get Status):
- Resource: Job
- Operation: Get Status
- Job ID:
{{ $('Tornado API').item.json.job_id }}
Node 4 - IF:
- Condition:
{{ $json.status }}equalsCompleted - True: Continue to next step
- False: Loop back to Wait node
Example 2: Download + Send to Telegram
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Telegram │ → │ Tornado API │ → │ Wait │ → │ Tornado API │ → │ Telegram │
│ Trigger │ │ Job:Create │ │ + Loop │ │ Job:Status │ │ Send Video │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘Telegram Trigger: Receives YouTube URL from user
Tornado Create: URL = {{ $json.message.text }}
Wait + Loop: Poll every 5 seconds until status = Completed
Telegram Send: Video URL = {{ $json.s3_url }}
Example 3: Batch Spotify Podcast
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Trigger │ → │ Tornado API │ → │ Split In │ → │ Tornado API │
│ │ │ Job:Create │ │ Batches │ │ Job:Status │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
{ batch_id: ..., (with Wait + Loop
episode_jobs: [...] } for each job)Tornado Create:
- URL:
https://open.spotify.com/show/... - Folder:
my-podcast
Split In Batches:
- Input:
{{ $json.episode_jobs }} - Batch Size: 10
Tornado Get Status (with Wait + Loop):
- Job ID:
{{ $json }} - Loop until status = Completed
Example 4: Configure Custom S3 Bucket + Download
Use your own S3 bucket (AWS, Cloudflare R2, MinIO):
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Manual │ → │ Tornado API │ → │ Tornado API │ → │ Wait │
│ Trigger │ │ Storage: │ │ Job:Create │ │ + Loop │
│ │ │ Configure │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
Bucket linked! s3_url points to
YOUR bucket!Node 1 - Tornado API (Configure Bucket):
- Resource: Storage
- Operation: Configure Bucket
- Provider: Amazon S3 / Cloudflare R2 / MinIO
- Endpoint URL:
https://s3.us-east-1.amazonaws.com - Bucket Name:
my-videos-bucket - Region:
us-east-1 - Access Key ID:
AKIA... - Secret Access Key:
********
Node 2 - Tornado API (Create Job):
- Resource: Job
- Operation: Create
- URL:
https://youtube.com/watch?v=...
Node 3 - Wait + Loop:
- Use n8n Wait node (5 seconds) + Get Status + IF node to poll until completed
Output (when completed):
{
"status": "Completed",
"s3_url": "https://my-videos-bucket.s3.us-east-1.amazonaws.com/videos/video.mp4?X-Amz-..."
}Example 5: Cloudflare R2 Setup
┌─────────────┐
│ Tornado API │
│ Storage: │
│ Configure │
└─────────────┘Settings for R2:
- Provider: Cloudflare R2
- Endpoint URL:
https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com - Bucket Name:
my-r2-bucket - Region:
auto - Access Key ID: (from R2 API Tokens)
- Secret Access Key: (from R2 API Tokens)
Example 6: Reset to Default Storage
If you want to stop using your custom bucket:
┌─────────────┐
│ Tornado API │
│ Storage: │
│ Reset │
└─────────────┘- Resource: Storage
- Operation: Reset to Default
Files will be uploaded to Tornado's default storage again.
📊 Status Values
| Status | Description | s3_url |
|--------|-------------|--------|
| Pending | In queue | ❌ |
| Processing | Downloading/encoding | ❌ |
| Completed | Done! | ✅ |
| Failed | Error occurred | ❌ |
📍 Processing Steps
| Step | Description |
|------|-------------|
| Queued | Waiting in queue |
| Downloading | Fetching video/audio |
| Muxing | Combining with FFmpeg |
| Uploading | Sending to S3 |
| Finished | Complete |
⚠️ Error Handling
Use the IF node to handle errors:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Tornado API │ → │ IF │ → │ Success │
│ Job:Wait │ │status=Done? │ │ Path │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼ (else)
┌─────────────┐
│ Error │
│ Handler │
└─────────────┘IF Condition:
{{ $json.status }} == "Completed"🛠️ Development
Build from Source
git clone https://github.com/Lax3n/TornadoAPI_N8N
cd n8n-nodes-tornado-api
npm install
npm run buildLocal Testing
- Build the node:
npm run build - Link to n8n:
# Windows mklink /D "%USERPROFILE%\.n8n\custom\n8n-nodes-tornado-api" "D:\path\to\n8n-nodes-tornado-api" # Linux/Mac ln -s /path/to/n8n-nodes-tornado-api ~/.n8n/custom/n8n-nodes-tornado-api - Start n8n:
n8n start
Watch Mode
npm run devAutomatically rebuilds on file changes.
📦 Publishing to npm
To publish this node so others can install it via npm install:
1. Prerequisites
- npm account (npmjs.com)
- Node.js 18+ installed
2. Login to npm
npm login3. Update package.json
Ensure these fields are correct:
{
"name": "n8n-nodes-tornado-api",
"version": "1.0.0",
"description": "n8n node for Tornado API - Download YouTube videos & Spotify podcasts",
"author": "Velys Software",
"license": "MIT"
}4. Build & Publish
npm run build
npm publish5. Versioning
For updates:
npm version patch # 1.0.0 → 1.0.1 (bug fixes)
npm version minor # 1.0.0 → 1.1.0 (new features)
npm version major # 1.0.0 → 2.0.0 (breaking changes)
npm publish✅ n8n Community Verification (Optional)
To get your node listed in the official n8n integrations:
1. Requirements
- Node must be published on npm
- Must follow n8n node naming:
n8n-nodes-* - Include proper documentation
- Include icon (SVG or PNG)
- Pass basic functionality tests
2. Submit for Review
- Go to n8n Community Nodes
- Submit your node for review via their process
- n8n team will review and potentially feature it
3. Benefits of Verification
- Listed in n8n's official integrations
- Discoverable in n8n node search
- Increased trust and visibility
