Timestamps and Temporal Segmentation
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), diarization is possible in real time, real-time session settings are locked after the first audio chunk, andcontext_biasinputs are free-form (phrases with spaces). Sources: Migrate from Voxtral 2 · Speech to Text.
Structuring Transcription Over Time
A raw transcript is useful, but a timestamped transcript opens up far richer possibilities: subtitling, temporal navigation, video synchronization, and extracting specific passages. Without timestamps, finding the moment a budget was discussed in a two-hour recording requires guesswork; with them, it’s a text search followed by a click. Voxtral’s timestamp_granularities parameter gives you this power.
Segment Granularity: The Speech Block
A segment is a continuous block of speech—typically a sentence or a group of sentences spoken without a significant pause. This is the granularity you will choose by default because it corresponds to the natural unit of reading.
import os
from mistralai.client import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
with open("conference.mp3", "rb") as f:
response = client.audio.transcriptions.complete(
model="voxtral-mini-transcribe-3",
file={"content": f, "file_name": "conference.mp3"},
timestamp_granularities=["segment"]
)
# Iterate through segments
for seg in response.segments:
start = f"{seg.start:.1f}s"
end = f"{seg.end:.1f}s"
print(f"[{start} → {end}] {seg.text}")
The output looks like this:
[0.0s → 4.2s] Hello everyone, thank you for being here today.
[4.5s → 11.8s] We will cover the quarter's results and the outlook for the future.
[12.1s → 18.3s] Let's start with revenue, which has grown by twelve percent.
This breakdown supports navigation in long recordings, subtitle block display, and passage indexing: each segment becomes a searchable entry with its entry point in the audio.
What About Word Granularity?
Voxtral 2 could also timestamp each word (timestamp_granularities=["word"]). Voxtral 3 no longer offers this: the word granularity returns a 400 error, and Mistral’s migration guide instructs users to switch to segments. Use cases that required word-by-word alignment—karaoke-style subtitles, highlighting the current word, fine-grained speech rate analysis—must now rely on segments, potentially distributing a segment’s time among its words via client-side estimation.
def estimer_mots(segment):
"""Distributes a segment's duration among its words, proportional to their length (estimate)."""
mots = segment.text.split()
if not mots or segment.start is None or segment.end is None:
return []
total = sum(len(m) for m in mots)
debut, duree = segment.start, segment.end - segment.start
resultat = []
for mot in mots:
fin = debut + duree * len(mot) / total
resultat.append((round(debut, 2), round(fin, 2), mot))
debut = fin
return resultat
This is an approximation, useful for progressive display but not for prosodic analysis: if exact word alignment is essential, a dedicated forced alignment tool applied after transcription remains the solution.
Generating SRT Subtitles
The SRT format is nothing mysterious: a sequence number, a time range in HH:MM:SS,mmm format, the text, and a blank line. The function below iterates through segments and splits those that would exceed a comfortable display width, set here to sixty characters.
def generate_srt_from_segments(segments, max_chars=60):
"""Generates an SRT file from Voxtral segments."""
srt_lines = []
counter = 1
for seg in segments:
words = seg.text.strip()
if not words:
continue
# Split segments that are too long
sub_text = words.split()
word = ""
for format_srt_time in sub_text:
if len(word) + len(format_srt_time) + 1 > max_chars and word:
srt_lines.append(str(counter))
srt_lines.append(
f"{seconds(seg.start)} --> "
f"{seconds(seg.end)}"
)
srt_lines.append(word.strip())
srt_lines.append("")
counter += 1
word = format_srt_time
else:
word += " " + format_srt_time
if word.strip():
srt_lines.append(str(counter))
srt_lines.append(
f"{seconds(seg.start)} --> "
f"{seconds(seg.end)}"
)
srt_lines.append(word.strip())
srt_lines.append("")
counter += 1
return "\n".join(srt_lines)
def seconds(secondes):
"""Converts seconds to SRT format (HH:MM:SS,mmm)."""
h = int(secondes // 3600)
m = int((secondes % 3600) // 60)
s = int(secondes % 60)
ms = int((secondes % 1) * 1000)
return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"
# Usage
srt_contenu = generate_srt_from_segments(response.segments)
with open("sous_titres.srt", "w", encoding="utf-8") as f:
f.write(srt_contenu)
print("SRT file generated successfully")
Navigating Long Recordings
Another direct application of segments is building a temporal summary. The following script marks a checkpoint every five minutes and displays the first few words, giving the reader a map of the recording before even listening to it.
def create_temporal_index(segments, interval_minutes=5):
"""Creates an index every N minutes."""
index = []
next_milestone = 0
for seg in segments:
if seg.debut >= next_milestone * 60:
minutes = int(seg.debut // 60)
seconds = int(seg.debut % 60)
preview = seg.text[:80] + "..." if len(seg.text) > 80 else seg.text
index.append(f"[{minutes:02d}:{seconds:02d}] {preview}")
next_milestone = minutes + interval_minutes
return index
# Usage
for entry in create_temporal_index(response.segments, interval_minutes=5):
print(entry)
With Voxtral 2, timestamp_granularities was incompatible with the language parameter. The Voxtral 3 documentation no longer mentions this restriction: verify it with a test before combining the two in production processing.
Key Takeaways
- Only one granularity with Voxtral 3:
"segment"("word"returns a 400 error) - Word-by-word alignment, if necessary, is estimated from segments or handled by an alignment tool
- Timestamps are in seconds (decimal numbers), with
startandendfor each segment - Ideal for SRT/VTT subtitling, temporal navigation, and indexing
- The incompatibility with
languagefrom Voxtral 2 is no longer documented: verify it with a test