OpenAI Whisper API Tutorial: Speech to Text in Python (API and Local)
Transcribe audio to text in Python with OpenAI's speech-to-text API: gpt-transcribe and the deprecated whisper-1, prompts and keywords, streaming, timestamps and SRT subtitles, files over 25 MB, and running Whisper locally.
Prerequisites
- •Python 3.9 or newer
- •An OpenAI API key (for the API sections)
- •ffmpeg installed for compressing, splitting and local transcription
- •A GPU is recommended but not required for local Whisper
What You'll Learn
- Transcribe audio files with the OpenAI speech-to-text API in Python
- Improve accuracy with prompts, keywords and language hints
- Stream transcripts and generate timestamps and SRT subtitles
- Process recordings larger than the 25 MB upload limit
- Run Whisper locally with openai-whisper or faster-whisper and choose between local and API
OpenAI's speech-to-text API turns audio files into text in a few lines of Python, and the open source Whisper model can do the same on your own hardware. This tutorial covers both: how to call the OpenAI Whisper API and its newer transcription models, how to handle long recordings, timestamps and subtitles, and when running Whisper locally makes more sense.
Whisper API in 2026: what changed
"Whisper API" usually means the whisper-1 model on OpenAI's /v1/audio/transcriptions endpoint. That endpoint is still the way to transcribe files, but the models behind it have moved on:
The code below uses gpt-transcribe for plain transcription and whisper-1 only where you need timestamps. Check OpenAI's speech-to-text guide for the latest model list before you deploy.
Step 1: set up the SDK
You need an OpenAI API key in the OPENAI_API_KEY environment variable and the official Python SDK. If you have not done this before, the OpenAI API Python tutorial explains keys and billing.
pip install --upgrade openai
export OPENAI_API_KEY="sk-proj-your-key-here"Supported input formats are mp3, mp4, mpeg, mpga, m4a, wav and webm, and each upload can be at most 25 MB.
Step 2: transcribe an audio file
from openai import OpenAI
client = OpenAI()
with open("meeting.mp3", "rb") as audio_file:
transcription = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
)
print(transcription.text)The response contains the transcript text, and with gpt-transcribe also a languages list with the detected language codes. Always open the file in binary mode ("rb").
Step 3: improve accuracy with a prompt and keywords
Speech models struggle most with product names, acronyms and people's names. Give the model context with a prompt, and with gpt-transcribe a list of keywords and expected languages. The SDK passes newer fields through extra_body:
with open("support-call.wav", "rb") as audio_file:
result = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
prompt="Customer support call about the TechLogHub Pro plan and invoice AC-42.",
extra_body={
"keywords": ["TechLogHub", "AC-42", "Kubernetes", "Priya Sharma"],
"languages": ["en", "hi"],
},
)
print(result.text)Keep each keyword on one line. Do not send the older single language field together with languages. If you know the audio is in one language, passing it still helps accuracy and speed.
Step 4: stream the transcript
For long files, streaming lets you show text as soon as it is ready instead of waiting for the full transcript:
with open("lecture.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()
print("Detected languages:", event.languages)Streaming here applies to a completed file. For live microphone audio, OpenAI's Realtime API handles transcription over a WebSocket or WebRTC session instead. whisper-1 does not support streaming.
Step 5: timestamps and subtitles with whisper-1
To build subtitles or jump to the moment a word was spoken, request timestamps from whisper-1 while it remains available:
with open("talk.mp3", "rb") as audio_file:
result = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="verbose_json",
timestamp_granularities=["word", "segment"],
)
for word in result.words[:10]:
print(f"{word.start:6.2f}s {word.word}")whisper-1 can also return subtitle files directly. With response_format set to "srt" or "vtt", the SDK returns a string you can save:
with open("talk.mp3", "rb") as audio_file:
srt = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="srt",
)
with open("talk.srt", "w", encoding="utf-8") as f:
f.write(srt)Because whisper-1 is scheduled to shut down, plan a replacement for timestamp features: either a diarization or timestamp-capable model from OpenAI's current list, or the local Whisper options below, which produce timestamps and SRT files for free.
Step 6: handle files larger than 25 MB
Two simple strategies cover most cases. First, compress: speech does not need CD quality, and mono 16 kHz MP3 at 32 to 64 kbps keeps accuracy while shrinking files dramatically. An hour of audio at 32 kbps is roughly 14 MB.
ffmpeg -i meeting.wav -ac 1 -ar 16000 -b:a 32k meeting.mp3Second, split long recordings into chunks, ideally at silences, so sentences are not cut in half. ffmpeg's segment muxer splits by time:
mkdir -p chunks
ffmpeg -i podcast.mp3 -f segment -segment_time 600 -c copy chunks/part_%03d.mp3Then transcribe the chunks in order and join the text:
from pathlib import Path
from openai import OpenAI
client = OpenAI()
parts = []
for chunk in sorted(Path("chunks").glob("part_*.mp3")):
with open(chunk, "rb") as f:
result = client.audio.transcriptions.create(model="gpt-transcribe", file=f)
parts.append(result.text.strip())
print("done:", chunk.name)
Path("podcast.txt").write_text(" ".join(parts), encoding="utf-8")Passing the last sentence of the previous chunk as the prompt for the next one helps keep names and style consistent across boundaries.
Practical tips for better transcripts
Run Whisper locally instead
Whisper is also an open source model released by OpenAI under the MIT licence, so you can run it on your own machine with no per-minute cost and no audio leaving your network. The reference package needs Python and ffmpeg:
pip install -U openai-whisper
whisper meeting.mp3 --model turbo --language en --output_format srtThe CLI writes a subtitle file next to the audio. From Python:
import whisper
model = whisper.load_model("turbo")
result = model.transcribe("meeting.mp3")
print(result["text"])
for seg in result["segments"][:5]:
print(round(seg["start"], 1), round(seg["end"], 1), seg["text"])Model sizes trade speed for accuracy. The official README lists roughly 1 GB of VRAM for tiny and base, 2 GB for small, 5 GB for medium, 6 GB for turbo and 10 GB for large. turbo is an optimised large-v3 variant that is much faster with a small accuracy cost, and it is a good default on a modern GPU. On CPUs or for higher throughput, use faster-whisper, a CTranslate2 reimplementation that is several times faster and supports 8-bit quantization:
from faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, info = model.transcribe("meeting.mp3", beam_size=5)
print("Language:", info.language)
for s in segments:
print(f"{s.start:7.1f}s {s.text}")On Macs and edge devices, whisper.cpp runs quantized Whisper models efficiently on Apple Silicon and CPUs.
Whisper API vs local Whisper: which to choose
A common pattern is local Whisper or faster-whisper for bulk and sensitive audio, and the API for apps that need fast, scalable transcription without running GPUs.
Next steps
Feed transcripts into an LLM to summarise meetings or extract action items with the OpenAI API Python tutorial, index them for search with embeddings, or keep the whole pipeline on your own hardware by pairing local Whisper with a model from the run an LLM locally tutorial. If you are choosing an AI provider for the rest of your stack, see OpenAI API vs Anthropic API vs Gemini API.

