tornado-api

n8n node for Tornado API - Download TBs of YouTube videos & Spotify podcasts with advanced features

Package Information

Downloads: 295 weeklyΒ /Β 335 monthly
Latest Version: 1.3.2
Author: Velys Software

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_start and clip_end timestamps
  • πŸ“Ί 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) and job_id filter
  • ⚑ 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

  1. Go to Credentials β†’ New
  2. Search for Tornado API
  3. Enter your API Key (starts with sk_)
  4. 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 }} equals Completed
  • 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

  1. Build the node: npm run build
  2. 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
    
  3. 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

  1. Go to n8n Community Nodes
  2. Submit your node for review via their process
  3. 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

πŸ”— Links

Discussion