Docs
Contact Dashboard

API referenceTranscribe a file

Transcribe a file

Send a recording and get its transcript in one response.

POSThttps://api.p99lab.com/v1/transcribe

Request body

One of:

  • the audio file as the raw body, with options in the query string;
  • multipart/form-data with the audio in a part named file, and options as form fields (language and format may also go in the query string).

Any common audio or video format, up to 600 MB and 4 hours (2 hours on self-serve accounts).

Parameters

filefilerequired in multipart

The audio. Not used with a raw body.

languagestringdefault en

Language of the speech. Audrey serves English: en.

formatbooleandefault true

Written forms for numbers, amounts, times and similar. false, 0, no, off or raw return plain words.

promptstringoptional

Context for the recording, up to 500 characters; longer text is cut. Form field in a multipart request, query parameter with a raw body.

Headers

Authorizationstringrequired

Bearer YOUR_API_KEY. X-API-Key: YOUR_API_KEY works instead.

curl
# The file as the request body
curl https://api.p99lab.com/v1/transcribe \
  -H "Authorization: Bearer $P99LAB_API_KEY" \
  --data-binary @call.wav

# Or as a multipart form, with options as fields
curl https://api.p99lab.com/v1/transcribe \
  -H "Authorization: Bearer $P99LAB_API_KEY" \
  -F file=@call.wav \
  -F language=en \
  -F format=true
Python
import os

import requests

with open("call.wav", "rb") as f:
    r = requests.post(
        "https://api.p99lab.com/v1/transcribe",
        headers={"Authorization": f"Bearer {os.environ['P99LAB_API_KEY']}"},
        files={"file": f},
        data={"language": "en", "format": "true"},
        timeout=900,
    )
body = r.json()
if not r.ok:
    detail = body["detail"]
    raise SystemExit(detail if isinstance(detail, str) else detail["message"])
print(body["text"])
Node.js
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("call.wav")]), "call.wav");
form.append("language", "en");
form.append("format", "true");

const res = await fetch("https://api.p99lab.com/v1/transcribe", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.P99LAB_API_KEY}` },
  body: form,
});
const body = await res.json();
if (!res.ok) {
  throw new Error(typeof body.detail === "string" ? body.detail : body.detail.message);
}
console.log(body.text);

Response

textstring

The transcript. Empty when the audio has no speech.

audio_secondsnumber

Length of the audio, which is what usage is charged on.

modelstring

The model that produced the text, for example audrey-0.7.

formattedboolean

Whether written forms were requested.

200 OK

{
  "text": "Thanks for calling. How can I help you today?",
  "audio_seconds": 12.84,
  "model": "audrey-0.7",
  "formatted": true
}

Errors

StatusWhen
400Empty body, no file part, unreadable audio, audio shorter than 0.05 s, or a language other than en.
401Missing or unknown key.
402Balance used up, or a renewal payment overdue.
413Larger than 600 MB, or longer than the file length limit.
429Too many parallel requests for the key, or a daily limit reached.
503Daily capacity reached, or billing briefly unavailable; see Retry-After.

Every message is listed in errors and limits.

400 Bad Request

{"detail": "audio shorter than 0.05 s"}

↑↓ to move↵ to open