Overview
Audio + video
All transcription formats supported by the site.
Async jobs
Create a job, then poll its ID for progress and results.
US$0.04 / hour
Credits are charged by rounded-up minute.
Authentication
Every request needs a Bearer API key in the Authorization header. The full secret is shown only once when created.
HTTP header
Authorization: Bearer sz_live_your_api_keyQuick start: submit a remote file
The server must be able to download the HTTPS URL directly without a login or cookies.
cURL
curl -X POST https://scribezip.com/api/v1/transcriptions \
-H "Authorization: Bearer $SCRIBEZIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/meeting.mp3",
"language": "auto",
"accuracy_mode": "balanced"
}'Multipart upload for local files
- Create an upload session with the name, byte size, and MIME type.
- Upload every part in order using the returned part_size.
- Call complete_url to start processing.
Node.js 22+
import { open, stat } from "node:fs/promises";
const apiKey = process.env.SCRIBEZIP_API_KEY;
const path = "./meeting.mp3";
const file = await stat(path);
const created = await fetch("https://scribezip.com/api/v1/transcriptions", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
file_name: "meeting.mp3",
file_size: file.size,
mime_type: "audio/mpeg",
language: "auto",
}),
}).then((response) => response.json());
const handle = await open(path, "r");
const { part_size, part_count, part_url, complete_url } = created.upload;
for (let part = 1; part <= part_count; part += 1) {
const length = Math.min(part_size, file.size - (part - 1) * part_size);
const buffer = Buffer.alloc(length);
await handle.read(buffer, 0, length, (part - 1) * part_size);
await fetch(`${part_url}?part_number=${part}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Length": String(length),
},
body: buffer,
});
}
await handle.close();
const job = await fetch(complete_url, {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}` },
}).then((response) => response.json());
console.log(job.data.id);Get job status and results
Poll every 3–5 seconds. Status can be accepted, uploading, preprocessing, processing, completed, failed, or deleted.
cURL
curl https://scribezip.com/api/v1/transcriptions/REQUEST_ID \
-H "Authorization: Bearer $SCRIBEZIP_API_KEY"200 response
{
"data": {
"id": "request_id",
"status": "completed",
"progress": 100,
"file_name": "meeting.mp3",
"source_kind": "audio",
"duration_seconds": 330,
"billed_minutes": 6,
"credits_charged": 6,
"transcript": {
"text": "Welcome to the meeting…",
"segments": [
{ "start": 0, "end": 2.4, "text": "Welcome to the meeting…" }
]
},
"error": null
},
"meta": { "balance_credits": 14994 }
}DELETE /api/v1/transcriptions/REQUEST_ID deletes the result and any retained media.
Billing
| Rate | US$0.04 / transcription hour |
|---|---|
| Credit unit | 1 credit = 1 billed minute |
| Rounding | Under 1 minute → 1 minute; 5:30 → 6 minutes |
| Top-ups | US$10 / $20 / $50 / $100 |
| Failed jobs | Reserved credits are automatically refunded |
Data retention
API usage history is retained for 30 days.
Uploaded video source files are deleted after processing and are not retained.
Uploaded audio source files are retained for up to 60 days unless deleted sooner.
API keys are stored only as irreversible hashes; full secrets cannot be revealed again.
Common error codes
| HTTP | Code | Meaning |
|---|---|---|
401 | invalid_api_key | Missing, invalid, or revoked key |
402 | insufficient_credits | Not enough API credits |
409 | job_in_progress | The account already has an active job |
413 | file_too_large | File exceeds the allowed size |
415 | unsupported_file | Unsupported media format |
429 | rate_limited | Too many requests |