Package Information
Documentation
πͺοΈ 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-api
Via 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/n8n
Credentials Setup
- Go to Credentials β New
- Search for Tornado API
- Enter your API Key (starts with
sk_) - Base URL:
https://api.tornadoapi.io(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 hours
The 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: File
Send 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 build
Local 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 dev
Automatically 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 login
3. 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 publish
5. 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