Transcribe an audio file: gpt-transcribe and Whisper
On this page
Lesson rewritten November 3, 2026. This guide previously covered
whisper-1, which is deprecated and will be discontinued on February 26, 2027. OpenAI’s File transcription guide now recommendsgpt-transcribe. However,gpt-transcribedoes not provide timestamps, SRT or VTT subtitles, or averbose_jsonresponse. For these specific needs,whisper-1remains the only option until its discontinuation. The code previously accessed segments as dictionaries (segment["start"]), which raises aTypeErrorwith the Python SDK; they are objects (segment.start). Every call has been verified withopenaiSDK 3.42.1. Sources: File transcription · Create transcription · GPT-Transcribe · Deprecations.
Transcribe a recording
File transcription addresses the most common use case: you have a finished recording (a meeting, a podcast, a voice message) and you need the text. You send the file to the /v1/audio/transcriptions endpoint and receive the transcription. For audio that is still arriving, such as from a microphone or a call, the correct approach is live transcription via the Realtime API, covered later in this course.
The file must be 25 MB or smaller, in one of the following formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm.
Which model in November 2026
| Model | Status | Key points |
|---|---|---|
gpt-transcribe | Recommended | Context (prompt), keywords (keywords), expected languages (languages), streaming transcription; $0.0045 per minute |
whisper-1 | Deprecated, discontinuation February 26, 2027 | Only model providing timestamps, verbose_json, SRT and VTT, and translation to English |
gpt-4o-transcribe, gpt-4o-mini-transcribe | Deprecated, discontinuation February 26, 2027 | Replaced by gpt-transcribe |
gpt-4o-transcribe-diarize | Deprecated, discontinuation February 26, 2027 | Speaker identification (diarized_json) |
First transcription
from openai import OpenAI
client = OpenAI()
with open("recording.mp3", "rb") as audio_file:
transcription = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
)
print(transcription.text)
By default, the response is a JSON object: transcription.text contains the text, and transcription.languages lists the languages the model recognized with sufficient confidence (an empty list if it could not identify any).
Give the model context
A meeting recording is full of proper nouns, acronyms, and internal terms the model has no reason to know. gpt-transcribe accepts three hints you can combine:
with open("meeting.mp3", "rb") as audio_file:
transcription = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
prompt="Management meeting about the Corsen AI project and contract AC-42.",
keywords=["Corsen AI", "AC-42", "GDPR"],
languages=["fr", "en"],
)
print(transcription.text)
promptdescribes the context in a single sentence, in the language of the recording. This is not a system instruction; it is a hint that guides recognition.keywordslists terms to recognize. Enter one keyword per item, without<,>, or line breaks: the API rejects the entire request if it finds any.languagesspecifies expected languages using ISO 639-1 codes (fr,en,es…). It replaces thelanguageparameter from older models: never send both.
Follow transcription in real time
For long files, there is no need to wait until the end to display the beginning. With stream=True, the API returns events as processing occurs, without requiring a Realtime session:
with open("meeting.mp3", "rb") as audio_file:
stream = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
stream=True,
)
for event in stream:
if event.type == "transcript.text.delta":
print(event.delta, end="", flush=True)
elif event.type == "transcript.text.done":
print() # full transcription in event.text
Timestamps and subtitles: whisper-1, until February 26, 2027
OpenAI’s guide states explicitly: its examples for word-level timestamps, subtitles, and speaker identification rely on deprecated models. If you need these features, whisper-1 remains available until February 26, 2027, and it is the only model that accepts verbose_json and timestamp_granularities:
with open("meeting.mp3", "rb") as audio_file:
transcription = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="verbose_json",
timestamp_granularities=["segment"],
)
for segment in transcription.segments or []:
print(f"[{segment.start:.1f}s - {segment.end:.1f}s] {segment.text.strip()}")
Segments are SDK objects: read segment.start, not segment["start"]. With timestamp_granularities=["word"], word-level timestamps appear in transcription.words, at the cost of slightly higher latency. The same model also produces ready-to-use subtitles: with response_format="srt" or "vtt", the SDK returns the subtitle file text directly.
The guide does not yet designate a replacement for these functions. If your product depends on timestamps or subtitles, plan a solution before February 26, 2027.
Long files
For files larger than 25 MB, compress the audio or split it. The documentation recommends avoiding cuts in the middle of a sentence, which loses context, and suggests the pydub library for splitting (OpenAI does not guarantee this third-party software). Passing the end of the previous chunk in prompt helps the model maintain continuity, a usage of the parameter cited in the guide:
from pydub import AudioSegment
def transcribe_long(path: str, duration_ms: int = 10 * 60 * 1000) -> str:
"""Transcribes a long recording in 10-minute chunks."""
audio = AudioSegment.from_file(path)
texts: list[str] = []
for i, start in enumerate(range(0, len(audio), duration_ms)):
chunk = f"chunk_{i}.mp3"
audio[start:start + duration_ms].export(chunk, format="mp3")
options = {"prompt": texts[-1][-500:]} if texts else {} # continuity
with open(chunk, "rb") as f:
result = client.audio.transcriptions.create(model="gpt-transcribe", file=f, **options)
texts.append(result.text)
return " ".join(texts)
Fixed-duration splitting sometimes cuts a sentence in half: for a polished result, split on silence instead.
Key takeaways
gpt-transcribeis the recommended model for file transcription;whisper-1andgpt-4o-*-transcribediscontinue on February 26, 2027prompt,keywords, andlanguages(no longerlanguage) guide term and language recognitionstream=Truereturns transcription on the fly (transcript.text.delta), without a Realtime session- Timestamps,
verbose_json, SRT, and VTT exist only withwhisper-1until its discontinuation; read segments as objects (segment.start) - Maximum 25 MB per file: compress or split, preferably on silence