Transcription API
POST an audio or video file, poll for the transcript. Whisper large-v3, 100+ languages, speaker labels, files up to 10 hours. Results as JSON, plain text, SRT or VTT.
Authentication
Every account has an API token — it's on your account page. Send it as a Bearer header on every request.
Create an account to get your token1. Submit a file
POST https://transcribe.free/api/v1/transcribe/
Authorization: Bearer YOUR_API_TOKEN
Content-Type: multipart/form-data
file the audio/video file (required)
language ISO code, or omit to auto-detect
diarization "true" for speaker labels (optional)
timestamps "false" to skip segment times (optional)
Returns 202 with the job uuid. The job goes straight onto the priority queue — API jobs are never behind free web uploads.
{
"ok": true,
"uuid": "0f2c…",
"status": "queued",
"credits_used": 12,
"status_url": "https://transcribe.free/api/v1/transcribe/0f2c…/"
}
2. Poll for the transcript
GET https://transcribe.free/api/v1/transcribe/<uuid>/?format=json
Authorization: Bearer YOUR_API_TOKEN
format is json (default, structured segments), txt, srt or vtt. Poll every few seconds until status is completed.
{
"ok": true,
"uuid": "0f2c…",
"status": "completed",
"duration_seconds": 742.5,
"language": "en",
"transcript": "Full text…",
"segments": [
{"start": 0.0, "end": 4.2, "text": "Welcome back.", "confidence": 0.98}
]
}
cURL
UUID=$(curl -s https://transcribe.free/api/v1/transcribe/ \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "file=@interview.mp3" \
-F "language=en" \
-F "diarization=true" | jq -r .uuid)
curl -s "https://transcribe.free/api/v1/transcribe/$UUID/?format=srt" \
-H "Authorization: Bearer YOUR_API_TOKEN" | jq -r .transcript > interview.srt
Python
import time, requests
H = {"Authorization": "Bearer YOUR_API_TOKEN"}
API = "https://transcribe.free/api/v1/transcribe/"
job = requests.post(API, headers=H,
files={"file": open("interview.mp3", "rb")},
data={"language": "en", "diarization": "true"}).json()
while True:
r = requests.get(API + job["uuid"] + "/", headers=H).json()
if r["status"] in ("completed", "failed"):
break
time.sleep(5)
print(r["transcript"])
Node.js
const H = {Authorization: "Bearer YOUR_API_TOKEN"};
const API = "https://transcribe.free/api/v1/transcribe/";
const form = new FormData();
form.append("file", new Blob([await fs.readFile("interview.mp3")]), "interview.mp3");
form.append("language", "en");
const {uuid} = await (await fetch(API, {method: "POST", headers: H, body: form})).json();
let job;
do {
await new Promise(r => setTimeout(r, 5000));
job = await (await fetch(`${API}${uuid}/?format=vtt`, {headers: H})).json();
} while (job.status !== "completed" && job.status !== "failed");
console.log(job.transcript);
List your jobs
curl -s "https://transcribe.free/api/v1/transcriptions/?limit=20" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Errors
Errors come back with ok:false and a code: unauthorized (401), missing_file / unsupported_format / file_too_large / file_too_long / bad_format (400), insufficient_credits (402), not_found (404), queue_failed (502). A job that fails after queueing reports status:failed with an error field, and its credits are refunded.
API pricing
The API bills exactly like the web app: 1 credit per minute of audio, rounded up. Pro ($10/month or $60/year) covers fair-use unlimited minutes and is the cheapest option for steady volume; credit packs start at $5 and never expire. There is no free API tier — the free daily allowance is web-only.
- Files to 10 hours / 5 GB, priority queue, speaker labels
- Whisper large-v3, 100+ languages, auto-detect
- No per-request fee, no minimum, no expiry on packs