The Offline Transcription API
On this page
Course updated November 3, 2026 for Voxtral 3, based on Mistral’s Migrate from Voxtral 2 guide: Voxtral 2 models (
voxtral-mini-2602,voxtral-mini-transcribe-realtime-2602,voxtral-mini-tts-2603), deprecated on October 31, 2026 and retired on April 30, 2027, are replaced in examples byvoxtral-mini-transcribe-3,voxtral-mini-transcribe-realtime-3, andvoxtral-mini-tts-3-0. Key changes: timestamps are segment-only (wordreturns a 400 error), real-time diarization is supported, real-time session settings are locked after the first audio chunk, andcontext_biasentries are free-form (phrases with spaces). Sources: Migrate from Voxtral 2 · Speech to Text.
The transcription endpoint
Mistral’s offline transcription API uses the /audio/transcriptions endpoint. It is a synchronous API: you send an audio file, the request stays open during processing, and you receive the full transcription in the response. There is no task ID to poll and no webhook to configure. This simplifies your code significantly, but you must allow generous timeouts for long files.
Before you start coding, ensure you have three prerequisites: a Mistral platform account (console.mistral.ai), an active API key, and the Python SDK installed.
Installing the SDK
pip install mistralai
Call parameters
Everything goes through client.audio.transcriptions.complete(). Two parameters are required, and four are optional. These optional parameters are what turn a raw transcription into a usable deliverable.
Required parameters
model— The model identifier. For offline transcription, use"voxtral-mini-transcribe-3"(recommended) or a pinned version like"voxtral-mini-transcribe-3".fileorfile_url— The audio file to transcribe. You have two options:file: A dictionary{"content": file_object, "file_name": "name.mp3"}for direct upload.file_url: A public URL pointing to the audio file.
Choosing between file and file_url is an architectural decision. If your audio is already stored in a publicly accessible location, file_url avoids routing the file through your server. If the file comes from a user’s device or private storage, direct upload is necessary.
Optional parameters
Four optional settings change the nature of the output.
language expects an ISO language code, such as "fr" or "en", and bypasses automatic detection. Force this for homogeneous batches, such as a catalog of interviews conducted entirely in French, to prevent a brief English passage from switching the model mid-file. Note that it is incompatible with timestamp_granularities.
timestamp_granularities takes the list ["segment"] and triggers the return of timestamps segment by segment. With Voxtral 3, the word granularity no longer exists and returns a 400 error. This parameter enables subtitle files synchronized to video or indexed passages in a two-hour conference.
diarize is a boolean. When set to True, the model identifies speakers and attributes each segment to one of them. For a six-person executive committee, this is the difference between an anonymous wall of text and a report where every commitment is attributable.
Finally, context_bias accepts a list of terms—a single word or a phrase with spaces, such as a product name—to improve recognition of specific vocabulary. The number of entries is no longer fixed, but they share the context window with the audio, so keep the list short. An engineering meeting featuring terms like “Kubernetes” and “GDPR” becomes significantly more readable with this setting.
Supported audio formats
Voxtral accepts common audio formats, and you will rarely need to convert anything beforehand. If in doubt, refer to the Audio formats page in the documentation.
| Format | Characteristic |
|---|---|
| MP3 | Most common, good compression |
| WAV | Uncompressed, maximum quality |
| FLAC | Lossless compression |
| OGG | Open format, good compression |
| M4A / AAC | Apple format, common on mobile |
| WEBM | Web format, common for browser recordings |
The critical limit is the model’s context window, which is shared between the audio and the context_bias vocabulary. A request exceeding this limit is rejected with a 400 error; the API does not truncate the file. For very long files, such as a day-long seminar, split them before sending, preferably at silence points to avoid cutting sentences in half.
Response structure
The response contains at minimum the transcribed text:
response.text # The full transcribed text (str)
If you requested timestamps (timestamp_granularities), the response also includes:
response.segments # List of segments with start, end, text
If you enabled diarization (diarize=True), each segment includes the speaker identity:
segment.speaker_id # Speaker identifier (str)
segment.start # Start time in seconds (float)
segment.end # End time in seconds (float)
segment.text # Segment text (str)
In short, the shape of the returned object depends on your request. Code that iterates over response.segments without passing timestamp_granularities will fail. Always verify consistency between your input parameters and your output handling.
Parameter combinations
Here are the five valid combinations you will encounter most often, from simplest to most specialized.
# Simple transcription (text only)
client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file={"content": f, "file_name": "audio.mp3"}
)
# With forced language (no timestamps)
client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file={"content": f, "file_name": "audio.mp3"},
language="fr"
)
# With segment timestamps
client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file={"content": f, "file_name": "audio.mp3"},
timestamp_granularities=["segment"]
)
# With diarization + timestamps
client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file={"content": f, "file_name": "audio.mp3"},
diarize=True,
timestamp_granularities=["segment"]
)
# With context biasing
client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file_url="https://example.com/audio.mp3",
context_bias=["Mistral", "Voxtral", "Corsen", "GDPR"]
)
A surprising constraint in Voxtral 2 was that language and timestamp_granularities could not be used together in the same call. The Voxtral 3 documentation no longer mentions this restriction; verify this with a test before relying on it.
Authentication
All requests require a valid API key passed to the client constructor. In development, a direct argument suffices. In production, use an environment variable to prevent the key from ending up in your Git repository.
from mistralai.client import Mistral
# Via direct argument
client = Mistral(api_key="your-api-key")
# Or via environment variable (recommended for production)
import os
os.environ["MISTRAL_API_KEY"] = "your-api-key"
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
Key takeaways
- The
/audio/transcriptionsendpoint is synchronous: send the file, receive the text. - Two upload modes: direct upload (
file) or public URL (file_url). - Optional parameters:
language,timestamp_granularities,diarize,context_bias. - In Voxtral 2,
languageandtimestamp_granularitieswere mutually exclusive; Voxtral 3 documentation no longer states this. - Common audio formats are supported; the limit is the context window shared between audio and
context_bias(400 error if exceeded). - Diarization and timestamps can be combined.