Skip to main content
Lesson 6 of 18 · Realtime API and Voice Agents

Transcribe an audio file: gpt-transcribe and Whisper

Lesson 6 of 18 Updated November 3, 2026 Developer
On this page
  1. Transcribe a recording
  2. Which model in November 2026
  3. First transcription
  4. Give the model context
  5. Follow transcription in real time
  6. Timestamps and subtitles: whisper-1, until February 26, 2027
  7. Long files
  8. Key takeaways

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 recommends gpt-transcribe. However, gpt-transcribe does not provide timestamps, SRT or VTT subtitles, or a verbose_json response. For these specific needs, whisper-1 remains the only option until its discontinuation. The code previously accessed segments as dictionaries (segment["start"]), which raises a TypeError with the Python SDK; they are objects (segment.start). Every call has been verified with openai SDK 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

ModelStatusKey points
gpt-transcribeRecommendedContext (prompt), keywords (keywords), expected languages (languages), streaming transcription; $0.0045 per minute
whisper-1Deprecated, discontinuation February 26, 2027Only model providing timestamps, verbose_json, SRT and VTT, and translation to English
gpt-4o-transcribe, gpt-4o-mini-transcribeDeprecated, discontinuation February 26, 2027Replaced by gpt-transcribe
gpt-4o-transcribe-diarizeDeprecated, discontinuation February 26, 2027Speaker 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)
  • prompt describes 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.
  • keywords lists terms to recognize. Enter one keyword per item, without <, >, or line breaks: the API rejects the entire request if it finds any.
  • languages specifies expected languages using ISO 639-1 codes (fr, en, es…). It replaces the language parameter 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-transcribe is the recommended model for file transcription; whisper-1 and gpt-4o-*-transcribe discontinue on February 26, 2027
  • prompt, keywords, and languages (no longer language) guide term and language recognition
  • stream=True returns transcription on the fly (transcript.text.delta), without a Realtime session
  • Timestamps, verbose_json, SRT, and VTT exist only with whisper-1 until its discontinuation; read segments as objects (segment.start)
  • Maximum 25 MB per file: compress or split, preferably on silence