OpenAI-compatible streaming with SSE

Configure streaming without mixing endpoint formats. The examples keep verified routing separate from model-specific capability claims.

SSE streamingResponses APIChat CompletionsAuth routes verified

What streaming changes

With a non-streaming request, the client waits for the complete response. Streaming delivers incremental events as the model produces output. OpenAI documents server-sent events (SSE) for streamed HTTP responses; the Responses API and Chat Completions expose different event shapes.

EndpointRead text fromEnd condition
ResponsesTyped events such as response.output_text.deltaresponse.completed, or an error event
Chat Completionschunk.choices[0].delta.contentSSE terminator data: [DONE]

Verify the key and model before streaming

Start with GET /v1/models. Copy an exact model ID visible to your key, then run one short non-streaming request. This separates authentication and model routing errors from stream parsing problems.

curl -sS https://monkeytheme.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

On August 3, 2026, unauthenticated POST probes with stream: true reached both /v1/responses and /v1/chat/completions and returned structured 401 API_KEY_REQUIRED. That verifies authentication-layer routing only. It does not prove authenticated streaming for every model.

Stream with the Python SDK

The official Python SDK supports stream=True. The Responses example below prints text delta events and keeps other event types explicit.

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_KEY",
    base_url="https://monkeytheme.com/v1",
)

stream = client.responses.create(
    model="MODEL_ID_FROM_LIST",
    input="Write one short sentence.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "error":
        print("\nstream error:", event)

For Chat Completions, iterate over chunks and read chunk.choices[0].delta.content. Do not use the Responses event parser on Chat Completions output.

Stream with the Node.js SDK

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: "https://monkeytheme.com/v1",
});

const stream = client.responses.stream({
  model: "MODEL_ID_FROM_LIST",
  input: "Write one short sentence.",
});

stream.on("response.output_text.delta", (event) => {
  process.stdout.write(event.delta);
});

await stream.finalResponse();

The official Node SDK also has a Chat Completions stream runner. Treat it as a separate response format rather than renaming fields until the code compiles.

Use curl to inspect the raw SSE boundary

curl -N https://monkeytheme.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "model": "MODEL_ID_FROM_LIST",
    "input": "Reply with OK",
    "stream": true
  }'

-N disables curl output buffering. If curl shows incremental events but an application does not, inspect the application's parser and any proxy between it and the gateway.

Proxy checks for stalled streams

Nginx documents proxy_buffering off as passing the upstream response to the client synchronously as it arrives. Its proxy_read_timeout applies between successive reads, not to the total response time.

location /v1/ {
    proxy_pass http://your_upstream;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_buffering off;
    proxy_read_timeout 300s;
}
This is a diagnostic pattern, not a copy-paste production policy or an OpenAI-prescribed timeout. Review the existing Nginx configuration, upstream limits and abuse controls before changing it.

Diagnose the symptom, not just the status

SymptomLikely layer to inspect
401 before any eventKey, Authorization header and gateway authentication
404 before any eventBase URL, duplicated /v1 or unsupported endpoint
Events arrive in one batchClient output buffering or reverse-proxy buffering
Stream stops after a quiet intervalRead timeout between upstream reads; collect timestamps and request IDs
Text duplicates after reconnectApplication retry/reconnect logic; do not assume a stream can resume from an arbitrary byte

Sources and related guides

FAQ

Does streaming use WebSocket?

This guide covers HTTP streaming with server-sent events. WebSocket is not required for the Responses or Chat Completions examples shown here.

Why does the output arrive all at once?

First run curl with -N. If curl streams but the application does not, inspect client-side buffering. If neither streams, inspect reverse-proxy buffering and the upstream response.

Can I parse Responses and Chat Completions the same way?

No. Responses emits typed events such as response.output_text.delta. Chat Completions places incremental text in choices[0].delta.content.

Does a 401 prove that streaming is unsupported?

No. A structured 401 is an authentication failure before model output begins. Fix the key or header, then test streaming with a model returned to that key.

Does this page confirm every MonkeyAI model can stream?

No. The public probe verifies that both endpoint paths reach the authentication layer. Authenticated stream support must be tested with the exact model and endpoint you plan to use.