Skip to main content
Lesson 4 of 16 · Voxtral Audio: Transcription and Speech-to-Text

The Offline Transcription API

Lesson 4 of 16 Updated November 3, 2026 Developer
On this page
  1. The transcription endpoint
  2. Call parameters
  3. Supported audio formats
  4. Response structure
  5. Parameter combinations
  6. Authentication
  7. Key takeaways

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 by voxtral-mini-transcribe-3, voxtral-mini-transcribe-realtime-3, and voxtral-mini-tts-3-0. Key changes: timestamps are segment-only (word returns a 400 error), real-time diarization is supported, real-time session settings are locked after the first audio chunk, and context_bias entries 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".
  • file or file_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.

FormatCharacteristic
MP3Most common, good compression
WAVUncompressed, maximum quality
FLACLossless compression
OGGOpen format, good compression
M4A / AACApple format, common on mobile
WEBMWeb 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/transcriptions endpoint 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, language and timestamp_granularities were 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.