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 processprocessing- Currently transcribingcompleted- Finished successfullyfailed- Error occurredcancelled- User cancelled
V3 Additions:
progressfield (0-100)estimated_completiontimestamp- Detailed
errorobject 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 Parameter | V3 Parameter | Notes |
|---|---|---|
speaker_labels | enable_diarization | Renamed for clarity |
| N/A | glossary_id | New feature |
| N/A | custom_model_id | New feature |
| N/A | enable_timestamps | New 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_labels→enable_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_labelstoenable_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 Duration | V2 Time | V3 Time | Improvement |
|---|---|---|---|
| 5 minutes | 50s | 35s | 30% faster |
| 30 minutes | 4m 30s | 3m 10s | 30% faster |
| 1 hour | 9m 20s | 6m 30s | 30% faster |
| 2 hours | 19m 00s | 13m 15s | 30% faster |
Support
Need help migrating?
- Batch API V3 Documentation
- V2 Documentation (legacy)
- Contact support via dashboard
- Email: support@scriptix.io