OpenAI Realtime GA migration: drop the OpenAI-Beta header
Beta Realtime integrations must move to GA and stop sending OpenAI-Beta: realtime=v1. A short checklist, a code scan for the header, and where Sume jobs fit.

If your realtime voice code still sends the header OpenAI-Beta: realtime=v1, it is a beta integration. OpenAI's Realtime guide says beta integrations must migrate to the GA interface and drop that header.
This page is the checklist: what the guide asks for, a script that finds every place the header is set, and the one boundary to keep in mind if the voice session also triggers Sume generation jobs.
What the guide asks for
Four facts from the guide, as read on 2026-10-03. Nothing here is inferred beyond that page.
| Topic | What the guide says |
|---|---|
| Beta integrations | Must migrate to GA |
| Beta header | Drop OpenAI-Beta: realtime=v1 |
| Transport in a browser | Connect with WebRTC |
| Transport on a server | Connect with WebSocket |
| Safety header | Send OpenAI-Safety-Identifier |
Find every place the header is set
The header tends to live in more than one place: a server proxy, a test harness, a mobile client, a sample copied into docs. A plain text scan is enough to list them. This script walks a directory and prints each file and line that mentions the beta value.
import os
import sys
NEEDLE = "realtime=v1"
SKIP_DIRS = {".git", "node_modules", ".venv", "dist", "build"}
def scan(root):
hits = []
for folder, dirs, files in os.walk(root):
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
for name in files:
path = os.path.join(folder, name)
try:
with open(path, encoding="utf-8") as handle:
for number, line in enumerate(handle, 1):
if NEEDLE in line:
hits.append((path, number, line.strip()))
except (UnicodeDecodeError, OSError):
continue
return hits
if __name__ == "__main__":
root = sys.argv[1] if len(sys.argv) > 1 else "."
for path, number, line in scan(root):
print(f"{path}:{number}: {line}")Order of work
Do the migration in small steps so a regression is easy to place.
- List every client that opens a realtime session, and mark each as browser or server. The guide's transport rule follows that split: WebRTC in the browser, WebSocket on the server.
- Remove the beta header from one client at a time, starting with the server path, and run a short call end to end before moving on.
- Add
OpenAI-Safety-Identifierto the requests that open sessions, so the value is present from the first GA call rather than added later. - Delete the beta references from your own docs and examples, so the next teammate does not copy them back in.
Where Sume jobs fit
A realtime session is a live connection. Sume generation is not: the Developer API has no SSE or WebSocket transport, and the jobs docs say GET /v1/jobs/:id/events is a pull snapshot, not a stream. A voice assistant that decides to render an image or a clip should start the job from its server, then poll the status URL or take a webhook for the terminal event.
That server is also where the Sume key belongs. The authentication docs say browser clients should call your backend, and your backend attaches the key. The same split keeps a browser WebRTC session from ever holding a Sume credential.
Sources
Related posts
More in Developers
- OpenAI TTS: 13 built-in voices vs 9 legacy ones, pick the model first
OpenAI's guide lists gpt-4o-mini-tts with 13 built-in voices and legacy tts-1 and tts-1-hd with 9. Formats, custom voice consent and disclosure, as a checklist.
- Pause between narration lines: TTS pause markers or audio concat?
Deepgram Flux TTS allows pause markers of 500 to 3000 ms, max 8 per request. Sume's timeline audio concat joins lines with no gap. Where to put the pause.
- Performance Max text limits: 30, 90, 90 and 25 characters, counted
Performance Max headlines run 30 characters, long headlines 90, descriptions 90, business name 25. A short script counts generated copy before upload.
- Push or poll for a finished render: listen, webhook or jobs_wait
MCP 2026-07-28 adds subscriptions/listen. For a render that takes minutes, compare a listen stream, a signed webhook and jobs_wait, with a Python verifier.
Written by Sume