Draftworks

Realtime

Speech-to-speech sessions with gpt-realtime-2.1 over WebSockets. Billed per response from live usage events. Scale tier.

gpt-realtime-2.1 runs live speech-to-speech sessions: you stream audio (or text) in, the model streams audio and text back over the same connection. Sessions speak the OpenAI Realtime API protocol over WebSockets.

Scale tier

Realtime is available on the Scale tier, which unlocks automatically at $5,000 lifetime purchases. Sessions from Base tier accounts receive an error event with code model_requires_scale_tier and are closed.

Connecting

Realtime sessions terminate on a dedicated host — WebSockets cannot ride through the main API host:

Realtime URL
wss://realtime.draftworks.dev/v1/realtime?model=gpt-realtime-2.1

Authenticate the handshake with your normal API key, either as a header (server-side) or the OpenAI browser subprotocol:

Python (openai SDK)
from openai import OpenAI

client = OpenAI(
    api_key="dw_live_...",
    websocket_base_url="wss://realtime.draftworks.dev/v1",
)

with client.realtime.connect(model="gpt-realtime-2.1") as connection:
    connection.session.update(session={"output_modalities": ["audio", "text"]})
    connection.response.create(
        response={"instructions": "Greet the caller and ask how you can help."}
    )
    for event in connection:
        if event.type == "response.done":
            break
Browser (subprotocol auth)
const ws = new WebSocket(
  "wss://realtime.draftworks.dev/v1/realtime?model=gpt-realtime-2.1",
  ["realtime", "openai-insecure-api-key." + apiKey],
);

Everything after the handshake is the standard Realtime protocol: session.update, input_audio_buffer.append, response.create, and the corresponding server events pass through unmodified.

Billing

Each model response inside a session ends with a response.done event carrying a usage block. Draftworks bills that usage immediately at the gpt-realtime-2.1 rates — text, audio, and image tokens each at their own rate, 25% under list on Scale — and the charge appears in your dashboard as a realtime usage event per response.

If your balance runs out mid-session you receive an error event with code insufficient_credits and the session closes; add credits and reconnect.

Limits and notes

  • Sessions are WebSocket only. WebRTC and SIP transports are not offered.
  • Realtime responses are not receipt-signed: there is no single request/response byte stream to hash. Usage events still record every token.
  • Idle sessions are closed after 10 minutes without frames.

On this page