API Documentation

Programmatic access to Scriptube for transcript extraction at scale.

πŸ”§ Interactive API Explorer
Try API endpoints live with the OpenAPI (Swagger) interface. Test requests, view schemas, and explore responses.
Open API Explorer β†’

Authentication

All API requests require authentication using an API key. Get your key from API Keys in your dashboard.

Header Format

Include your API key in the X-API-Key header with every request:

X-API-Key: sk_live_your_api_key_here

Key Scopes

API keys can have different permission levels:

Scope Description
full Read and write access. Can submit new transcription jobs.
read Read-only access. Can view transcripts and usage, but cannot submit new jobs.

Base URL

All API endpoints are relative to:

https://scriptube.me/api/v1

Endpoints

POST /transcripts

Submit YouTube URLs for transcript extraction. URLs are processed asynchronously.

Request Body

Parameter Type Description
urls required array List of YouTube video URLs or playlist URLs to process

Code Examples

curl -X POST https://scriptube.me/api/v1/transcripts \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "https://www.youtube.com/watch?v=VIDEO_ID_2"
    ]
  }'
import requests

API_KEY = "sk_live_your_api_key"
BASE_URL = "https://scriptube.me/api/v1"

response = requests.post(
    f"{BASE_URL}/transcripts",
    headers={
        "X-API-Key": API_KEY,
        "Content-Type": "application/json"
    },
    json={
        "urls": [
            "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
            "https://www.youtube.com/watch?v=VIDEO_ID_2"
        ]
    }
)

data = response.json()
batch_id = data["batch_id"]
print(f"Batch submitted: {batch_id}")
const API_KEY = "sk_live_your_api_key";
const BASE_URL = "https://scriptube.me/api/v1";

const response = await fetch(`${BASE_URL}/transcripts`, {
  method: "POST",
  headers: {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    urls: [
      "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "https://www.youtube.com/watch?v=VIDEO_ID_2"
    ]
  })
});

const data = await response.json();
console.log(`Batch submitted: ${data.batch_id}`);
Success Response (202 Accepted)
{
  "batch_id": "550e8400-e29b-41d4-a716-446655440000",
  "batch_number": 1,
  "status": "pending",
  "url_count": 2,
  "message": "Batch submitted for processing. Poll GET /api/v1/transcripts/{batch_id} for results."
}
GET /transcripts/{batch_id}

Get the status and results of a specific transcript batch.

Path Parameters

Parameter Type Description
batch_id required uuid The batch ID returned from POST /transcripts

Code Examples

curl https://scriptube.me/api/v1/transcripts/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-API-Key: sk_live_your_api_key"
import requests

API_KEY = "sk_live_your_api_key"
batch_id = "550e8400-e29b-41d4-a716-446655440000"

response = requests.get(
    f"https://scriptube.me/api/v1/transcripts/{batch_id}",
    headers={"X-API-Key": API_KEY}
)

data = response.json()
print(f"Status: {data['status']}")

for item in data["items"]:
    if item["status"] == "completed":
        print(f"Video: {item['title']}")
        print(f"Transcript: {item['transcript_text'][:200]}...")
const API_KEY = "sk_live_your_api_key";
const batchId = "550e8400-e29b-41d4-a716-446655440000";

const response = await fetch(
  `https://scriptube.me/api/v1/transcripts/${batchId}`,
  { headers: { "X-API-Key": API_KEY } }
);

const data = await response.json();
console.log(`Status: ${data.status}`);

data.items.forEach(item => {
  if (item.status === "completed") {
    console.log(`Video: ${item.title}`);
    console.log(`Transcript: ${item.transcript_text.slice(0, 200)}...`);
  }
});
Success Response (200 OK)
{
  "batch_id": "550e8400-e29b-41d4-a716-446655440000",
  "batch_number": 1,
  "status": "completed",
  "created_at": "2026-02-04T12:00:00Z",
  "completed_at": "2026-02-04T12:01:30Z",
  "items": [
    {
      "video_id": "dQw4w9WgXcQ",
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "title": "Rick Astley - Never Gonna Give You Up",
      "channel": "Rick Astley",
      "status": "completed",
      "transcript_text": "We're no strangers to love...",
      "transcript_language": "en",
      "duration_seconds": 213,
      "error": null
    }
  ]
}
GET /transcripts

List all transcript batches for your account.

Query Parameters

Parameter Type Description
limit integer Number of batches to return (1-100, default: 20)
offset integer Number of batches to skip (default: 0)

Code Example (cURL)

curl "https://scriptube.me/api/v1/transcripts?limit=10&offset=0" \
  -H "X-API-Key: sk_live_your_api_key"
GET /usage

Check your current usage and remaining quota.

Code Example (cURL)

curl https://scriptube.me/api/v1/usage \
  -H "X-API-Key: sk_live_your_api_key"
Success Response (200 OK)
{
  "plan": "pro",
  "credits_balance": 1850,
  "credits_monthly": 2000,
  "daily_used": 45,
  "daily_limit": 600,
  "daily_remaining": 555,
  "total_processed": 8500
}
GET /plans

List all available subscription plans and their limits.

Code Example (cURL)

curl https://scriptube.me/api/v1/plans \
  -H "X-API-Key: sk_live_your_api_key"
Success Response (200 OK)
{
  "plans": [
    {
      "slug": "free",
      "title": "Free",
      "description": "Get started for free",
      "price_monthly_cents": 0,
      "credits_monthly": 20,
      "videos_per_day": 50,
      "max_batch_size": 20,
      "api_enabled": false
    },
    {
      "slug": "pro",
      "title": "Pro",
      "description": "For power users",
      "price_monthly_cents": 699,
      "credits_monthly": 2000,
      "videos_per_day": 600,
      "max_batch_size": 300,
      "api_enabled": true
    }
  ]
}
GET /transcripts/{batch_id}/export

Export batch transcripts in JSON, CSV, or plain text format.

Path Parameters

Parameter Type Description
batch_id required uuid The batch ID to export

Query Parameters

Parameter Type Description
format string Export format: json, csv, or txt (default: json)

Code Example (cURL)

curl "https://scriptube.me/api/v1/transcripts/550e8400-e29b-41d4-a716-446655440000/export?format=json" \
  -H "X-API-Key: sk_live_your_api_key" \
  -o transcripts.json
GET /health

Health check endpoint. No authentication required.

Code Example (cURL)

curl https://scriptube.me/api/v1/health
Success Response (200 OK)
{
  "status": "ok",
  "version": "1.0.0"
}

Rate Limits & Quotas

Plan Limits

Your API usage is subject to your subscription plan limits:

Plan Credits/Mo Videos/Day Max Batch Concurrent Webhooks API
Free 20 50 20 1 β€” β€”
Starter 500 200 100 3 β€” β€”
Pro 2,000 600 300 5 5 βœ“
Business 6,500 2,000 1,000 10 10 βœ“
Unlimited 20,000 ∞ 4,000 999999 25 βœ“

Credit Costs

Each action consumes credits from your monthly allocation:

Action Cost
YouTube transcript (captions) 4 credits
AI transcription (ElevenLabs) 10 credits/minute
Translation 12 credits per 1K chars

Credit Packs (Top-Up)

Need more credits? Purchase credit packs anytime. Credits never expire.

Pack Credits Price Per Credit
Micro Pack 120 $3.00 $0.0250
Standard Pack 300 $7.00 $0.0233
Bulk Pack 700 $15.00 $0.0214
Max Pack 1,500 $30.00 $0.0200

Purchase via dashboard or POST /api/billing/credits/checkout

Rate Limiting

API requests are also subject to per-minute rate limiting to ensure service stability:

  • General API requests: 100 requests/minute
  • Batch submission: Based on plan limits

Checking Your Usage

Use the GET /api/v1/usage endpoint to check your current usage and remaining quota programmatically.

Error Handling

The API uses standard HTTP status codes to indicate success or failure:

Code Description
200 Success - Request completed successfully
202 Accepted - Batch submitted for processing
401 Unauthorized - Missing or invalid API key
403 Forbidden - API key lacks required permissions or email not verified
404 Not Found - Resource doesn't exist
422 Unprocessable Entity - Invalid request body or exceeded batch size limit
429 Too Many Requests - Rate limit or quota exceeded
500 Internal Server Error - Something went wrong on our end

Error Response Format

Error responses include a detail field with a human-readable message:

{
  "detail": "Daily limit reached. You have 0 videos remaining today."
}

Bring Your Own Key (BYOK)

Use your own API keys for third-party services to get better rates, higher limits, or more control over your usage.

Supported Services

Service Key Type Used For
ElevenLabs API Key Audio transcription when captions aren't available
OpenAI API Key Whisper transcription (coming soon)
YouTube Data API Key Playlist expansion, video metadata

How BYOK Works

  1. Add your key β€” Go to Settings β†’ API Keys and add your service API key
  2. Keys are encrypted β€” All keys are encrypted with AES-256 before storage
  3. Activate the key β€” Select which key to use (you can store multiple per service)
  4. Automatic usage β€” When processing videos, your key is used instead of our shared pool

Benefits

  • No credit cost β€” BYOK requests don't consume your Scriptube credits for that service
  • Higher limits β€” Use your own quota instead of shared limits
  • Better rates β€” If you have a discounted API plan, you keep those savings
  • Full control β€” Monitor usage directly in the service's dashboard

Managing BYOK Keys via API

GET /api/v1/byok

List all your stored API keys (key values are masked).

curl -X GET https://scriptube.me/api/v1/byok \
  -H "X-API-Key: sk_live_your_api_key"
{
  "keys": [
    {
      "id": "byok_abc123",
      "service": "elevenlabs",
      "name": "My ElevenLabs Key",
      "masked_key": "sk_...x7c",
      "is_active": true,
      "created_at": "2024-01-15T10:30:00Z"
    }
  ]
}
POST /api/v1/byok

Add a new API key for a supported service.

Parameter Type Description
service required string Service name: elevenlabs, openai, or youtube
api_key required string Your API key for the service
name string Optional friendly name for this key
curl -X POST https://scriptube.me/api/v1/byok \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "elevenlabs",
    "api_key": "sk_your_elevenlabs_key",
    "name": "Production Key"
  }'
DELETE /api/v1/byok/{key_id}

Delete a stored API key.

curl -X DELETE https://scriptube.me/api/v1/byok/byok_abc123 \
  -H "X-API-Key: sk_live_your_api_key"
POST /api/v1/byok/{key_id}/activate

Activate a key to use it for processing. Only one key per service can be active.

curl -X POST https://scriptube.me/api/v1/byok/byok_abc123/activate \
  -H "X-API-Key: sk_live_your_api_key"

Integrations

Connect Scriptube to your favorite automation tools for seamless workflow integration.

Zapier Integration

Automate transcript extraction with Zapier's 5,000+ app connections.

Available Actions

Action Description
Submit URLs Submit YouTube URLs for transcript extraction
Get Batch Status Check the status of a batch job
Get Transcripts Retrieve completed transcripts
Check Usage Get current usage stats and remaining quota

Example Zap: YouTube to Google Docs

  1. Trigger: New video in YouTube playlist
  2. Action 1: Scriptube β†’ Submit URL
  3. Action 2: Delay β†’ Wait 2 minutes
  4. Action 3: Scriptube β†’ Get Transcripts
  5. Action 4: Google Docs β†’ Create document with transcript

Zapier Setup

1. In Zapier, search for "Webhooks by Zapier"
2. Choose "Custom Request" action
3. Configure:
   - Method: POST
   - URL: https://scriptube.me/api/v1/transcripts
   - Headers: 
     X-API-Key: your_api_key
     Content-Type: application/json
   - Body: {"urls": ["{{youtube_url}}"]}
4. Test and enable your Zap

n8n Integration

Self-hosted workflow automation with full API access.

HTTP Request Node Setup

{
  "method": "POST",
  "url": "https://scriptube.me/api/v1/transcripts",
  "authentication": "genericCredentialType",
  "genericAuthType": "httpHeaderAuth",
  "headers": {
    "X-API-Key": "={{ $credentials.apiKey }}"
  },
  "body": {
    "urls": ["{{ $json.youtube_url }}"]
  }
}
{
  "method": "GET",
  "url": "https://scriptube.me/api/v1/batches/{{ $json.batch_id }}",
  "headers": {
    "X-API-Key": "={{ $credentials.apiKey }}"
  }
}
{
  "method": "GET",
  "url": "https://scriptube.me/api/v1/batches/{{ $json.batch_id }}/transcripts",
  "headers": {
    "X-API-Key": "={{ $credentials.apiKey }}"
  }
}

Example n8n Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Trigger    │───▢│  Submit to  │───▢│   Wait &    │───▢│  Save to    β”‚
β”‚ (Schedule/  β”‚    β”‚  Scriptube  β”‚    β”‚   Poll      β”‚    β”‚  Notion/    β”‚
β”‚  Webhook)   β”‚    β”‚             β”‚    β”‚   Status    β”‚    β”‚  Sheets     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Webhooks

Receive real-time notifications when your transcripts are ready. Perfect for n8n, Zapier, or custom integrations.

Webhook Limits by Plan

Plan Webhooks Rate Limit
Free β€” β€”
Starter β€” β€”
Pro 5 30 deliveries/min
Business 10 120 deliveries/min
Unlimited 25 300 deliveries/min

Register a Webhook

POST /api/v1/webhooks
{
  "url": "https://your-n8n-instance.com/webhook/abc123",
  "events": ["batch.completed", "batch.failed"],
  "secret": "your-hmac-secret"  // Optional: for signature verification
}

List Your Webhooks

GET /api/v1/webhooks

Delete a Webhook

DELETE /api/v1/webhooks/{webhook_id}

Test a Webhook

POST /api/v1/webhooks/{webhook_id}/test

Available Events

Event Description
batch.created Fired when a new batch is created
batch.started Fired when batch processing begins
batch.completed Fired when all items in a batch are processed
batch.failed Fired when a batch fails completely
item.completed Fired when a single video transcript is ready
item.failed Fired when a single video fails to process
transcript.ready Fired when transcript text is available
credits.low Fired when credits drop below 20% of plan allocation
credits.depleted Fired when credits reach zero
subscription.updated Fired when plan changes (upgrade/downgrade)

Webhook Payload Format

{
  "event": "batch.completed",
  "timestamp": "2024-01-15T10:35:00Z",
  "data": {
    "batch_id": "batch_abc123",
    "batch_number": 42,
    "status": "completed",
    "item_count": 5,
    "completed_count": 5,
    "failed_count": 0
  }
}

Signature Verification (HMAC-SHA256)

If you provide a secret when registering, we'll sign payloads with HMAC-SHA256. Verify the X-Webhook-Signature header:

import hmac, hashlib

def verify_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Need Help?

If you have questions or run into issues, we're here to help.

Contact Support OpenAPI Spec