OpenAI Chat Completions Streaming with AI Gateway
Set stream: true on a chat completion request to receive tokens as the model produces them, instead of waiting for the complete response.
Create a streaming chat completion that streams tokens as they are generated.
import OpenAI from 'openai';
const apiKey = process.env.AI_GATEWAY_API_KEY || process.env.VERCEL_OIDC_TOKEN;
const openai = new OpenAI({
apiKey,
baseURL: 'https://ai-gateway.vercel.sh/v1',
});
const stream = await openai.chat.completions.create({
model: 'anthropic/claude-opus-5',
messages: [
{
role: 'user',
content: 'Write a one-sentence bedtime story about a unicorn.',
},
],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
}import os
from openai import OpenAI
api_key = os.getenv('AI_GATEWAY_API_KEY') or os.getenv('VERCEL_OIDC_TOKEN')
client = OpenAI(
api_key=api_key,
base_url='https://ai-gateway.vercel.sh/v1'
)
stream = client.chat.completions.create(
model='anthropic/claude-opus-5',
messages=[
{
'role': 'user',
'content': 'Write a one-sentence bedtime story about a unicorn.'
}
],
stream=True,
)
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
print(content, end='', flush=True)curl -X POST "https://ai-gateway.vercel.sh/v1/chat/completions" \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-opus-5",
"messages": [
{
"role": "user",
"content": "Write a one-sentence bedtime story about a unicorn."
}
],
"stream": true
}'Streaming responses are sent as Server-Sent Events (SSE), a web standard for real-time data streaming over HTTP. Each event, except the final [DONE] sentinel, contains a JSON object with the partial response data.
The response format follows the OpenAI streaming specification:
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"anthropic/claude-opus-5","choices":[{"index":0,"delta":{"content":"Once"},"finish_reason":null}]}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"anthropic/claude-opus-5","choices":[{"index":0,"delta":{"content":" upon"},"finish_reason":null}]}
data: [DONE]Key characteristics:
- Each line starts with
data:followed by JSON, except the finaldata: [DONE]line - Content is delivered incrementally in the
delta.contentfield - The stream ends with
data: [DONE] - Empty lines separate events
SSE Parsing Libraries:
If you're building custom SSE parsing (instead of using the OpenAI SDK), these libraries can help:
- JavaScript/TypeScript:
eventsource-parser- Robust SSE parsing with support for partial events - Python:
httpx-sse- SSE support for HTTPX, orsseclient-pyfor requests
For more details about the SSE specification, see the W3C specification.
- Tool calling - Stream a response that calls your functions
- Reasoning - Control how much a model thinks before answering
- Advanced - Provider options and prompt caching
Was this helpful?