Skip to main content

Migrate from Batch API V2 to V3

This guide helps you upgrade from Batch API V2 to V3. While V2 continues to work, V3 offers improved performance, new features, and better developer experience.

Overview

Why Upgrade to V3?

Performance Improvements:

  • 30% faster processing times
  • Better handling of large files
  • Improved concurrent job management
  • More efficient file uploads with TUS

New Features:

  • Enhanced webhook support with retry logic
  • Glossary integration for better accuracy
  • Custom model support
  • Real-time progress tracking
  • Better error messages and debugging

Developer Experience:

  • Cleaner API design
  • Consistent response formats
  • Better documentation
  • More code examples

Compatibility

  • V2 remains supported until June 2025
  • V3 is backwards-compatible where possible
  • Most V2 code requires minimal changes

Key Differences

1. Authentication

No Change - Both V2 and V3 use Bearer token authentication:

-H "Authorization: Bearer YOUR_API_KEY"

2. Base URL

V2:

https://api.scriptix.io/api/v2/batch

V3:

https://api.scriptix.io/api/v3/batch

Simply update the version number in your base URL.

3. File Upload

V2 and V3: Similar approach, but V3 adds TUS support

V2:

curl -X POST https://api.scriptix.io/api/v2/batch/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@audio.mp3"

V3 (Standard):

curl -X POST https://api.scriptix.io/api/v3/batch/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@audio.mp3"

V3 (TUS for large files):

# Use TUS protocol for files > 2GB
curl -X POST https://api.scriptix.io/api/v3/batch/upload/tus \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Upload-Length: 5000000000" \
-H "Tus-Resumable: 1.0.0"

4. Create Transcription Job

V2:

{
"file_id": "file_abc123",
"language": "en",
"speaker_labels": true
}

V3:

{
"file_id": "file_abc123",
"language": "en",
"enable_diarization": true,
"glossary_id": "glossary_xyz", // New
"custom_model_id": "model_123", // New
"webhook_url": "https://yourapp.com/webhook"
}

5. Response Format

V2 Response:

{
"job_id": "job_abc123",
"status": "processing",
"created_at": "2024-12-07T10:00:00Z"
}

V3 Response (Enhanced):

{
"job_id": "job_abc123",
"status": "processing",
"created_at": "2024-12-07T10:00:00Z",
"updated_at": "2024-12-07T10:01:00Z",
"progress": 15, // New: Progress percentage
"estimated_completion": "2024-12-07T10:05:00Z", // New
"metadata": { // New: Additional context
"file_name": "audio.mp3",
"file_size": 5242880,
"duration": 300
}
}

6. Job Status

V2 and V3: Same status values, V3 adds more detail

Status Values (same):

  • pending - Waiting to process
  • processing - Currently transcribing
  • completed - Finished successfully
  • failed - Error occurred
  • cancelled - User cancelled

V3 Additions:

  • progress field (0-100)
  • estimated_completion timestamp
  • Detailed error object when failed

7. Webhooks

V2: Basic webhook support

{
"webhook_url": "https://yourapp.com/webhook"
}

V3: Enhanced webhooks with retry and verification

{
"webhook_url": "https://yourapp.com/webhook",
"webhook_secret": "your_secret_key", // New: For signature verification
"webhook_events": ["completed", "failed"] // New: Choose events
}

Migration Steps

Step 1: Update Base URL

Before (V2):

BASE_URL = "https://api.scriptix.io/api/v2/batch"

After (V3):

BASE_URL = "https://api.scriptix.io/api/v3/batch"

Step 2: Update Parameter Names

V2 → V3 Parameter Changes:

V2 ParameterV3 ParameterNotes
speaker_labelsenable_diarizationRenamed for clarity
N/Aglossary_idNew feature
N/Acustom_model_idNew feature
N/Aenable_timestampsNew option

Update your code:

# V2
job_data = {
"file_id": file_id,
"language": "en",
"speaker_labels": True
}

# V3
job_data = {
"file_id": file_id,
"language": "en",
"enable_diarization": True, # Renamed
"enable_timestamps": True # New option
}

Step 3: Handle Enhanced Responses

Update response parsing to use new fields:

# V2
def check_job_status(job_id):
response = requests.get(
f"{BASE_URL}/jobs/{job_id}",
headers=headers
)
return response.json()["status"]

# V3 - Use additional fields
def check_job_status_v3(job_id):
response = requests.get(
f"{BASE_URL}/jobs/{job_id}",
headers=headers
)
data = response.json()

return {
"status": data["status"],
"progress": data.get("progress", 0), # New
"estimated_completion": data.get("estimated_completion"), # New
"updated_at": data.get("updated_at")
}

Step 4: Implement Webhook Signature Verification

V3 adds webhook security:

import hmac
import hashlib

def verify_webhook_signature(payload, signature, secret):
"""Verify webhook came from Scriptix"""

expected_signature = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()

return hmac.compare_digest(expected_signature, signature)

# In your webhook handler
@app.route('/webhook', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Scriptix-Signature')
payload = request.data.decode()

if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401

# Process webhook
data = request.json
# ...

Step 5: Use New Features (Optional)

Glossaries

# Create transcription job with glossary
job_response = requests.post(
f"{BASE_URL}/transcribe",
headers=headers,
json={
"file_id": file_id,
"language": "en",
"glossary_id": "glossary_medical_terms" # V3 feature
}
)

Custom Models

# Use custom trained model
job_response = requests.post(
f"{BASE_URL}/transcribe",
headers=headers,
json={
"file_id": file_id,
"language": "en",
"custom_model_id": "model_legal_terms" # V3 feature
}
)

Progress Tracking

# Monitor progress in real-time
def wait_for_completion_v3(job_id):
while True:
status_data = check_job_status_v3(job_id)

print(f"Status: {status_data['status']}")
print(f"Progress: {status_data['progress']}%")

if status_data["estimated_completion"]:
print(f"ETA: {status_data['estimated_completion']}")

if status_data["status"] == "completed":
break

time.sleep(5)

Complete Migration Example

V2 Code

import requests
import time

API_KEY = "your_api_key"
BASE_URL = "https://api.scriptix.io/api/v2/batch"
headers = {"Authorization": f"Bearer {API_KEY}"}

def transcribe_v2(file_path, language="en"):
# Upload file
with open(file_path, "rb") as f:
upload_response = requests.post(
f"{BASE_URL}/upload",
headers=headers,
files={"file": f}
)

file_id = upload_response.json()["file_id"]

# Create job
job_response = requests.post(
f"{BASE_URL}/transcribe",
headers=headers,
json={
"file_id": file_id,
"language": language,
"speaker_labels": True
}
)

job_id = job_response.json()["job_id"]

# Poll for completion
while True:
status_response = requests.get(
f"{BASE_URL}/jobs/{job_id}",
headers=headers
)

status = status_response.json()["status"]

if status == "completed":
result_response = requests.get(
f"{BASE_URL}/jobs/{job_id}/result",
headers=headers
)
return result_response.json()
elif status == "failed":
raise Exception("Transcription failed")

time.sleep(5)

V3 Code (Upgraded)

import requests
import time

API_KEY = "your_api_key"
BASE_URL = "https://api.scriptix.io/api/v3/batch"
headers = {"Authorization": f"Bearer {API_KEY}"}

def transcribe_v3(file_path, language="en", glossary_id=None):
# Upload file
with open(file_path, "rb") as f:
upload_response = requests.post(
f"{BASE_URL}/upload",
headers=headers,
files={"file": f}
)

if upload_response.status_code != 200:
raise Exception(f"Upload failed: {upload_response.text}")

file_id = upload_response.json()["file_id"]

# Create job with V3 features
job_payload = {
"file_id": file_id,
"language": language,
"enable_diarization": True, # Renamed from speaker_labels
"enable_timestamps": True, # New in V3
"webhook_url": "https://yourapp.com/webhook" # Optional
}

# Add glossary if provided
if glossary_id:
job_payload["glossary_id"] = glossary_id

job_response = requests.post(
f"{BASE_URL}/transcribe",
headers=headers,
json=job_payload
)

if job_response.status_code != 200:
raise Exception(f"Job creation failed: {job_response.text}")

job_id = job_response.json()["job_id"]

# Poll for completion with progress tracking
while True:
status_response = requests.get(
f"{BASE_URL}/jobs/{job_id}",
headers=headers
)

data = status_response.json()
status = data["status"]
progress = data.get("progress", 0)

print(f"Progress: {progress}% - {status}")

if status == "completed":
result_response = requests.get(
f"{BASE_URL}/jobs/{job_id}/result",
headers=headers
)
return result_response.json()
elif status == "failed":
error_msg = data.get("error", {}).get("message", "Unknown error")
raise Exception(f"Transcription failed: {error_msg}")

time.sleep(5)

# Usage with new features
result = transcribe_v3(
"audio.mp3",
language="en",
glossary_id="my_glossary" # Use glossary
)

Backward Compatibility

What Still Works

These V2 features work the same in V3:

  • ✅ Authentication method
  • ✅ File upload endpoint (standard size)
  • ✅ Job creation endpoint
  • ✅ Status checking
  • ✅ Result retrieval
  • ✅ Basic webhook support
  • ✅ All language codes
  • ✅ Error codes

What's Different

Minor adjustments needed:

  • ⚠️ speaker_labelsenable_diarization (renamed)
  • ⚠️ Response includes additional fields (safe to ignore)
  • ⚠️ Error responses more detailed

Breaking Changes

None! V3 is designed to be minimally disruptive.

New V3 Features Summary

1. Enhanced Progress Tracking

status = get_job_status(job_id)
print(f"Progress: {status['progress']}%")
print(f"ETA: {status['estimated_completion']}")

2. Glossary Support

job = create_job(file_id, glossary_id="medical_terms")

3. Custom Models

job = create_job(file_id, custom_model_id="legal_model")

4. TUS Protocol for Large Files

# Files > 2GB
upload_large_file_tus("large_video.mp4")

5. Webhook Signature Verification

verify_webhook(payload, signature, secret)

6. Better Error Messages

{
"error": {
"code": "INVALID_FILE_FORMAT",
"message": "File format not supported",
"details": {
"supported_formats": ["mp3", "wav", "m4a"]
}
}
}

Testing Your Migration

Parallel Testing

Run V2 and V3 side-by-side:

def test_both_versions(file_path):
print("Testing V2...")
result_v2 = transcribe_v2(file_path)

print("Testing V3...")
result_v3 = transcribe_v3(file_path)

# Compare results
assert result_v2["transcript"] == result_v3["transcript"]
print("✓ Results match!")

Migration Checklist

  • Update base URL to V3
  • Rename speaker_labels to enable_diarization
  • Update response parsing for new fields
  • Test file upload
  • Test job creation
  • Test status polling with progress
  • Test result retrieval
  • Implement webhook signature verification (if using webhooks)
  • Test with glossaries (optional)
  • Test with custom models (optional)
  • Update error handling for new error format
  • Conduct end-to-end testing
  • Deploy to production

Rollback Plan

If issues arise, rolling back to V2 is straightforward:

# Simply change the version in BASE_URL
BASE_URL = "https://api.scriptix.io/api/v2/batch" # Rollback

# Revert parameter name
job_data["speaker_labels"] = job_data.pop("enable_diarization")

Performance Comparison

Processing Times

Based on testing with typical files:

File DurationV2 TimeV3 TimeImprovement
5 minutes50s35s30% faster
30 minutes4m 30s3m 10s30% faster
1 hour9m 20s6m 30s30% faster
2 hours19m 00s13m 15s30% faster

Support

Need help migrating?

Next Steps