Overview
Turns audio into text. Returns the full text, timestamped segments and words and, when you ask for it, who is speaking at each moment (diarization) in interviews, calls and meetings. Response formats json, verbose_json, diarized_json, text, srt and vtt.
Available models
Four literals on the same endpoint. Canary and Parakeet are the recommended ones: they transcribe real-world audio better, accept hours-long files without client-side chunking and separate speakers. Whisper stays available for compatibility with integrations that already use it.
| Model | Languages | Diarization | When to use it |
|---|---|---|---|
nvidia/canary-1b-v2 | 25 European languages; language required | Yes | Spanish and the other European languages when you know the language. The most accurate on real Spanish audio. |
nvidia/parakeet-tdt-0.6b-v3 | 25 European languages; detects the language itself | Yes | English, audio in an unknown language and high volume. On real English it beats Canary, and it is the fastest (×300–400 real time). |
whisper-large-v3 | 99 languages | No | Compatibility: integrations built for Whisper, Catalan and other languages outside the 25, and /v1/audio/translations. |
whisper-large-v3-turbo | 99 languages | No | Same as whisper-large-v3 with a distilled, faster decoder. |
Performance in Spanish and English versus Whisper
Measured by Tessera in October 2026 on the same GPU with the same normalisation (lower case, no punctuation, no filler words). FLEURS is short read sentences: the figure is WER (wrong words; lower is better). Real audio is long conversations: Spanish calls of 8 and 41 minutes and English interviews of 5 to 79 minutes with 2 or 3 speakers. There the figure is the difference against a reference transcript.
| Model | FLEURS Spanish | FLEURS English | Real Spanish audio | Real English audio | Speed on long audio |
|---|---|---|---|---|---|
nvidia/canary-1b-v2 | 3.9% | 5.7% | 6.6% | 10.5% (writes numbers as digits) | ×100–125 real time |
nvidia/parakeet-tdt-0.6b-v3 | 4.2% | 5.6% | 9.1% | 7.6% | ×300–400 real time |
whisper-large-v3 | 3.2% | 4.8% | 8.7%, with 2.3% invented text | not measured | ×3 real time |
Endpoint and parameters
POST https://api.tesseraai.cloud/v1/audio/transcriptions with multipart/form-data.
| Field | Value |
|---|---|
file | The audio: mp3, wav, m4a, flac, ogg, opus, webm or mp4. |
model | nvidia/canary-1b-v2, nvidia/parakeet-tdt-0.6b-v3, whisper-large-v3 or whisper-large-v3-turbo. |
language | ISO 639-1 code (en, es, pt…). Required with Canary; optional with Parakeet, which detects the language, and with Whisper. |
response_format | json (default), verbose_json, diarized_json, text, srt or vtt. |
timestamp_granularities[] | segment, word or both, with verbose_json. If omitted, Canary and Parakeet return both. |
diarize | true to separate speakers (Canary and Parakeet). See “Multiple speakers”. |
num_speakers, min_speakers, max_speakers | Optional hints about the number of speakers. |
prompt, temperature | Accepted for OpenAI compatibility; Canary and Parakeet ignore them. |
Request
curl https://api.tesseraai.cloud/v1/audio/transcriptions \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-F "[email protected]" \
-F "model=nvidia/parakeet-tdt-0.6b-v3" \
-F "language=en" \
-F "response_format=verbose_json"
# Python (official OpenAI SDK)
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.tesseraai.cloud/v1",
api_key=os.environ["TESSERA_API_KEY"],
)
with open("call.mp3", "rb") as f:
r = client.audio.transcriptions.create(
model="nvidia/parakeet-tdt-0.6b-v3",
file=f,
language="en",
)
print(r.text)Response
With json it returns {"text": "..."}. With verbose_json it adds duration, language (the one you sent in the request), segments[] and words[] with start and end in seconds, and usage with the seconds of audio.
{
"task": "transcribe",
"language": "es",
"duration": 85.07,
"text": "Hola, gracias por venir. ¿Has tenido problemas para encontrar la oficina? ...",
"segments": [
{
"id": 0,
"start": 0.48,
"end": 4.56,
"text": "Hola, gracias por venir. ¿Has tenido problemas para encontrar la oficina?"
}
],
"words": [
{"word": "Hola,", "start": 0.48, "end": 0.8},
{"word": "gracias", "start": 0.88, "end": 1.2}
],
"usage": {"type": "duration", "seconds": 85.07}
}Multiple speakers (diarization)
Canary and Parakeet can tell who is speaking at each moment: interviews, calls, meetings or podcasts. It is off by default, but there is nothing to configure on your account and no extra cost: you turn it on per request. Two ways: add diarize=true (works with json, verbose_json, srt and vtt), or ask for response_format=diarized_json, which turns it on by itself and answers in OpenAI's format.
| Parameter | Value | Effect |
|---|---|---|
diarize | true | Turns on speaker separation. With the OpenAI SDK it goes inside extra_body. |
response_format | diarized_json | Turns diarization on and answers in OpenAI's diarized_json format. No diarize needed. |
num_speakers | integer | Exact number of speakers, if you know it. |
min_speakers, max_speakers | integer | Range of speakers, if you only roughly know how many. |
Turning diarization on
# cURL: transcript with speakers
curl https://api.tesseraai.cloud/v1/audio/transcriptions \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-F "[email protected]" \
-F "model=nvidia/canary-1b-v2" \
-F "language=en" \
-F "response_format=verbose_json" \
-F "diarize=true" \
-F "num_speakers=2"
# Python: Tessera-specific fields go in extra_body
with open("meeting.mp3", "rb") as f:
r = client.audio.transcriptions.create(
model="nvidia/canary-1b-v2",
file=f,
language="en",
response_format="verbose_json",
extra_body={"diarize": True, "num_speakers": 2},
)
for s in r.segments:
print(s.speaker, s.start, s.text)
# Python: OpenAI's diarized_json format (turns diarization on by itself)
with open("meeting.mp3", "rb") as f:
r = client.audio.transcriptions.create(
model="nvidia/parakeet-tdt-0.6b-v3",
file=f,
response_format="diarized_json",
)
for s in r.segments:
print(s.speaker, s.start, s.text)Where the speakers appear
Speakers are labelled A, B, C… in order of appearance. Labels are consistent within one file but don't identify the person: the A in one call is not the A in another.
| Format | Where the speaker goes |
|---|---|
json + diarize=true | segments[].speaker: each segment is one speaking turn. |
verbose_json + diarize=true | segments[].speaker and words[].speaker. |
diarized_json | segments[].speaker, with type: "transcript.text.segment", same as OpenAI. |
srt or vtt + diarize=true | An [A], [B]… prefix on each subtitle. |
{
"task": "transcribe",
"duration": 85.07,
"text": "Hola, gracias por venir. Has tenido problemas para encontrar la oficina. Ninguno, ...",
"segments": [
{
"type": "transcript.text.segment",
"id": 0,
"speaker": "A",
"start": 0.32,
"end": 4.96,
"text": "Hola, gracias por venir. Has tenido problemas para encontrar la oficina."
},
{
"type": "transcript.text.segment",
"id": 1,
"speaker": "B",
"start": 5.36,
"end": 10.16,
"text": "Ninguno, el metro me deja justo enfrente, llegué con 10 minutos de margen."
},
{
"type": "transcript.text.segment",
"id": 2,
"speaker": "A",
"start": 10.4,
"end": 14.8,
"text": "Perfecto, cuéntame un poco sobre tu experiencia en atención al cliente."
}
],
"usage": {"type": "duration", "seconds": 85.07}
}Whisper (compatibility)
whisper-large-v3 and whisper-large-v3-turbo remain available with the same contract as always, so existing integrations keep working. Use them for Catalan and other languages outside the 25 Canary and Parakeet cover, and for /v1/audio/translations (translation into English). For everything else we recommend Canary or Parakeet.
- Up to 25 MB per file. For audio longer than 10 minutes, split it into 5–10 minute chunks and join the text client-side.
whisper-large-v3-turbocuts the decoder from 32 to 4 layers: faster, with a small accuracy loss.- No diarization.
Best practices
- Send
languagewhen you know it. With Canary it is required. - Send the whole file: Canary and Parakeet split and stitch the audio server-side, up to 4 hours.
- For conversations, turn on
diarize=trueand sendnum_speakersif you know how many people speak. - The
text,srtandvttformats arrive inside a JSON{"text": "..."}. With the OpenAI SDK you get that string: read it withjson.loads(r)["text"]. - Clean audio gives better results than heavily compressed mp3 or lots of background noise.