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.

4 min readSume
All posts

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.

OpenAI Realtime migration facts (read 2026-10-03)
TopicWhat the guide says
Beta integrationsMust migrate to GA
Beta headerDrop OpenAI-Beta: realtime=v1
Transport in a browserConnect with WebRTC
Transport on a serverConnect with WebSocket
Safety headerSend 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-Identifier to 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

All Developers posts

Written by Sume