Don’t Make People Wait
A model writes its answer a few words at a time. Without streaming, your app waits until the whole answer is finished and then shows it in one go. For a long answer, that can mean several seconds of a blank screen. Streaming sends each piece of the answer to your app as soon as the model writes it. The first words appear almost at once, and the rest fill in as the model goes. It’s the reason chat apps feel quick, and it’s the first thing most real AI apps need.Core Concepts
How a Stream Arrives
When you set"stream": true, the API keeps the connection open and sends a series of small messages called Server-Sent Events (SSE). Each event carries one piece of the answer, called a delta. Your app adds each delta to what it already has.
On the Responses endpoints, each event has a type. The ones you’ll use most:
On the Chat Completions endpoints, each chunk carries its text in
choices[0].delta.content, and the stream ends with a finish_reason such as "stop".
When to Stream
Stream when a person is waiting to read the answer: chat windows, writing assistants, anything interactive. Don’t bother when your code needs the whole answer before it can do anything, such as a background job or a step that parses JSON (Lesson 3). A normal request is simpler there.Errors Can Arrive Mid-Stream
A stream can fail at two points:- Before any text arrives. On the direct endpoints you get a normal HTTP error, such as a
503, and the OpenAI SDK raises it as an exception. - After text has started. The HTTP status is already
200, so the error arrives in the stream: aresponse.failedevent on Direct Responses, or an error chunk on Chat Completions. The OpenAI SDK raises an error chunk as an exception from the loop, so catch it.
Get Started
This example streams a short answer from Direct Responses and prints it as it arrives.-N turns off buffering so you see each event as it arrives. The raw stream looks like this (trimmed):
The Same Thing on Chat Completions
If your app uses the Chat Completions shape, readdelta.content from each chunk. Add stream_options to get token usage in a final chunk:
Good to Know
- Keep your API key on the server. Don’t call the API from browser code, where anyone can read the key. Stream from your server and pass the text on to the browser. The streaming tutorial builds a small proxy that does this. See API Key Security.
- Check the status before reading. A request that fails before the stream starts returns a JSON error, not events, so check for it first so a
401shows a clear message instead of a parsing error. - Some chunks have no text. The first and last chunks often carry no content. Skip them quietly.
- Keep what the user has seen. If a stream fails partway, leave the partial text on screen and mark it as interrupted, rather than letting it vanish. Handling Streaming Failures covers this in production.
- Reasoning can stream too. Reasoning models can send their reasoning before the answer, in separate events. Reasoning shows how to read them.
Key Takeaway
Streaming shows the answer as the model writes it, so your app feels fast. Set"stream": true, add each text delta as it arrives, and be ready for a stream to end early: at the output limit, or with an error after some text has already appeared.
Learn more
- Direct Responses: Streaming: every event type on the Responses stream
- Streaming AI Responses in Real Time: a step-by-step tutorial with a server-side proxy
- Handling Streaming Failures: retry budgets, continuing an interrupted answer and partial-output UX
- Streaming on the direct endpoints: how errors arrive before and after output starts
What’s next
Next, you’ll keep a conversation going across many turns, and learn what to do when it gets too long.Lesson 2: Conversations That Remember
Keep history, stay inside the context window and trim old turns.

