Tutorial
January 1, 20258 min read

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 curl installed (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

StatusDescription
PendingJob is queued, waiting to be processed
ProcessingJob is being downloaded/processed
CompletedJob finished successfully, file available at s3_url
FailedJob 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:

ParameterDescriptionExample
max_resolutionLimit video resolution"1080"
folderS3 prefix for organization"datasets/2025-01"
webhook_urlGet notified on completion"https://myapp.com/hook"
clip_startExtract from timestamp"00:01:30"
clip_endExtract 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

Ready to Get Started?

Request your API key and start downloading in minutes.

View Documentation