Getting Started with Tornado API: From Zero to First Download
This guide walks you through getting started with Tornado API—from getting your API key to downloading your first video in under 5 minutes. No complex setup, no proxy configuration, no infrastructure to manage. Just a single API call.
Tornado API handles all the complexity of downloading videos at scale: anti-bot bypassing, proxy rotation, cloud storage delivery, and automatic retries. Whether you're building an AI video pipeline, collecting training datasets, or automating content workflows, this guide gets you started fast.
Prerequisites
- A Tornado API key (free 25 GB trial, no credit card required)
- A terminal with
curlinstalled (or any HTTP client) - Optionally: Python 3.x or Node.js for the SDK examples
Step 1: Get Your API Key
Sign up at tornadoapi.io/request-access to request your free API key. You'll receive a key in the format sk_xxxxxxxxxxxxxxxx. The free trial includes 25 GB of downloads—enough to test your integration thoroughly.
Step 2: Test Your Key
Verify your API key works by checking your usage:
curl -X GET "https://api.tornadoapi.io/usage" \
-H "x-api-key: sk_your_api_key"You should see your current usage statistics, confirming your key is active.
Step 3: Create Your First Download
Download any YouTube video with a single POST request. Tornado handles everything behind the scenes—anti-bot bypassing, downloading, processing, and storage:
curl -X POST "https://api.tornadoapi.io/jobs" \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000"
}That's it—your video is now being downloaded. No proxy setup, no cookies to manage, no 403 errors. Tornado's proprietary anti-restriction engine handles all of that automatically.
Step 4: Check Job Status
Poll the status endpoint until the job completes (typically under 2 minutes):
curl -X GET "https://api.tornadoapi.io/jobs/550e8400-..." \
-H "x-api-key: sk_your_api_key"Response when complete:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "Completed",
"s3_url": "https://cdn.example.com/videos/video.mp4?signature=...",
"step": "Finished"
}Job Status Values
| Status | Description |
|---|---|
| Pending | Job is queued, waiting to be processed |
| Processing | Job is being downloaded/processed |
| Completed | Job finished successfully, file available at s3_url |
| Failed | Job failed—check the error field for details |
Step 5: Configure Direct Cloud Delivery
By default, Tornado stores files on our managed storage and provides a presigned download URL. For production use, configure your own cloud storage so files go directly to your bucket with zero egress fees:
curl -X POST "https://api.tornadoapi.io/user/storage" \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"provider": "s3",
"bucket": "my-video-pipeline",
"region": "us-east-1",
"access_key": "AKIAIOSFODNN7EXAMPLE",
"secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}'Tornado supports AWS S3, Cloudflare R2, Azure Blob Storage, Google Cloud Storage, Alibaba OSS, and any S3-compatible endpoint. See the multi-cloud storage guide for all providers.
Python Example
import requests
import time
API_KEY = "sk_your_api_key"
BASE_URL = "https://api.tornadoapi.io"
# Create a job
response = requests.post(
f"{BASE_URL}/jobs",
headers={"x-api-key": API_KEY},
json={"url": "https://youtube.com/watch?v=..."}
)
job_id = response.json()["job_id"]
print(f"Job created: {job_id}")
# Wait for completion
while True:
status = requests.get(
f"{BASE_URL}/jobs/{job_id}",
headers={"x-api-key": API_KEY}
).json()
if status["status"] == "Completed":
print(f"Download ready: {status['s3_url']}")
break
elif status["status"] == "Failed":
print(f"Error: {status['error']}")
break
time.sleep(2)Node.js Example
const API_KEY = "sk_your_api_key";
const BASE_URL = "https://api.tornadoapi.io";
async function downloadVideo(url) {
// Create job
const response = await fetch(`${BASE_URL}/jobs`, {
method: "POST",
headers: {
"x-api-key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ url }),
});
const { job_id } = await response.json();
console.log(`Job created: ${job_id}`);
// Poll for completion
while (true) {
const status = await fetch(
`${BASE_URL}/jobs/${job_id}`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
if (status.status === "Completed") {
return status.s3_url;
}
if (status.status === "Failed") {
throw new Error(status.error);
}
await new Promise(r => setTimeout(r, 2000));
}
}
// Usage
downloadVideo("https://youtube.com/watch?v=...")
.then(url => console.log("Ready:", url));Advanced Options
Tornado supports many options to customize your downloads:
| Parameter | Description | Example |
|---|---|---|
max_resolution | Limit video resolution | "1080" |
folder | S3 prefix for organization | "datasets/2025-01" |
webhook_url | Get notified on completion | "https://myapp.com/hook" |
clip_start | Extract from timestamp | "00:01:30" |
clip_end | Extract to timestamp | "00:03:00" |
Why Tornado Instead of yt-dlp?
If you're currently using yt-dlp, you know the pain of managing proxies, handling rate limits, and dealing with random 403 errors. Tornado eliminates all of that:
- Zero 403 errors — Our anti-restriction engine bypasses all bot detection automatically
- TB/hour throughput — Scale to terabytes per hour without any infrastructure changes
- Direct cloud delivery — No intermediate servers, no egress fees
- Zero maintenance — No proxy infrastructure, no yt-dlp updates to track
Next Steps
- Set up webhooks to avoid polling and build async pipelines
- Configure your own storage for direct cloud delivery
- Learn about batch downloads for playlists and podcast shows
- Build AI training datasets at scale
- Use video clipping for short-form content creation