Skip to main content

Direct Blob Upload (Recommended)

Upload files directly to cloud storage using pre-signed URLs for optimal performance and reduced API server load.

Recommended for most use cases — This method is faster and more efficient than TUS or API-proxied uploads.


Why Direct Blob Upload?

Benefits

  • Faster uploads: Direct connection to cloud storage (no API middleman)
  • Better reliability: Global CDN and resumable uploads
  • Scalability: No API server bottleneck for large files

When to Use

  • Recommended: Files > 5MB, production workflows, automated pipelines
  • Consider TUS: Unreliable networks requiring resumable uploads
  • Consider PUT to API: Quick prototypes, files < 1MB

How It Works


Step-by-Step Guide

Step 1: Create a Session

Initialize a transcription session with your desired settings:

curl -X POST "https://api.scriptix.io/api/v3/speech-to-text/session" \
-H "x-zoom-s2t-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"language": "en-us",
"punctuation": true,
"diarization": true,
"webhook_url": "https://example.com/webhook"
}'

Response:

{
"result": {
"session_id": "1b8a70f1000001000002d1a37b",
"status": "new"
}
}

Step 2: Request an Upload URL

Get a pre-signed URL for uploading your file:

curl -X POST "https://api.scriptix.io/api/v3/speech-to-text/session/1b8a70f1000001000002d1a37b/upload-url" \
-H "x-zoom-s2t-key: YOUR_API_KEY"

Response:

{
"result": {
"upload_url": "https://scriptix.blob.core.windows.net/container/session-id/file.mp4?sv=2021-08-06&se=2025-12-08T12%3A00%3A00Z&sr=b&sp=cw&sig=...",
"expires_at": "2025-12-08T12:00:00Z",
"session_id": "1b8a70f1000001000002d1a37b",
"max_file_size": 5368709120
}
}

Note: The URL expires after 24 hours. Complete your upload before expiration.


Step 3: Upload Your File to Cloud Storage

Use a simple HTTP PUT request to upload your file directly to cloud storage:

cURL:

curl -X PUT "https://scriptix.blob.core.windows.net/container/..." \
-H "x-ms-blob-type: BlockBlob" \
-H "Content-Type: audio/mp4" \
--data-binary "@/path/to/recording.mp4"

Python:

import requests

upload_url = "https://scriptix.blob.core.windows.net/..."
file_path = "/path/to/recording.mp4"

with open(file_path, "rb") as f:
response = requests.put(
upload_url,
headers={
"x-ms-blob-type": "BlockBlob",
"Content-Type": "audio/mp4"
},
data=f
)

if response.status_code == 201:
print("Upload successful!")
else:
print(f"Upload failed: {response.status_code}")

TypeScript/JavaScript:

const uploadUrl = "https://scriptix.blob.core.windows.net/...";
const filePath = "/path/to/recording.mp4";

const fileBuffer = fs.readFileSync(filePath);

const response = await fetch(uploadUrl, {
method: "PUT",
headers: {
"x-ms-blob-type": "BlockBlob",
"Content-Type": "audio/mp4"
},
body: fileBuffer
});

if (response.status === 201) {
console.log("Upload successful!");
} else {
console.error(`Upload failed: ${response.status}`);
}

Expected Response: HTTP 201 Created


Step 4: Confirm Upload Completion

Notify the API that your upload is complete to trigger processing:

curl -X POST "https://api.scriptix.io/api/v3/speech-to-text/session/1b8a70f1000001000002d1a37b/upload-complete" \
-H "x-zoom-s2t-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "recording.mp4"
}'

Response:

{
"result": {
"session_id": "1b8a70f1000001000002d1a37b",
"status": "uploaded",
"filename": "recording.mp4",
"duration": 592,
"media_type": "audio"
}
}

The API will now:

  1. Verify the file exists in cloud storage
  2. Validate file format and duration
  3. Scan for malware (if enabled)
  4. Claim subscription credits
  5. Queue the transcription job

Advanced: Multipart Upload (Large Files)

For files > 100MB, you can use chunked uploads for better performance and reliability. Here's an example using the requests library with streaming:

import requests

# Upload in 10MB chunks
chunk_size = 10 * 1024 * 1024

def upload_file_chunked(upload_url, file_path):
"""Upload file in chunks for better reliability"""
with open(file_path, "rb") as f:
response = requests.put(
upload_url,
headers={
"x-ms-blob-type": "BlockBlob",
"Content-Type": "application/octet-stream"
},
data=f
)

if response.status_code == 201:
print("Upload successful!")
return True
else:
print(f"Upload failed: {response.status_code}")
return False

# Use the function
upload_file_chunked(upload_url, "/path/to/large-file.mp4")

Error Handling

ErrorCauseSolution
invalid-stateSession already uploadedCreate a new session
file-not-foundUpload to cloud storage failedVerify upload succeeded (check HTTP 201)
invalid-fileFile has no audioCheck file format, ensure audio track exists
malware-detectedFile contains malwareRemove malicious content, upload clean file
insufficient-creditsNot enough creditsAdd credits at scriptix.app

Comparison: Upload Methods

MethodSpeedReliabilityUse Case
Direct BlobFastExcellentRecommended for production
TUSMediumBest (resumable)Unreliable networks
PUT to APISlowGoodQuick prototypes

FAQs

How long is the upload URL valid?

24 hours from generation. If expired, request a new URL.

Can I reuse the same URL for multiple files?

No. Each URL is scoped to a specific session and file path.

What happens if upload fails?

The session remains in "new" status. Request a new upload URL and retry.

Can I upload files larger than 5GB?

The maximum file size is 5GB per upload.

Do I need to call /upload-complete?

Yes! The API doesn't know upload is done until you call this endpoint.

Can I upload while transcription is running?

No. Each session processes one file. Create multiple sessions for parallel uploads.