Skip to main content

Streaming Responses

CLI Proxy API supports two methods for receiving real-time streaming responses:
  1. Server-Sent Events (SSE): Standard HTTP streaming via the /v1/chat/completions endpoint
  2. WebSocket: Bidirectional streaming via the /v1/responses endpoint (OpenAI Responses format)

Server-Sent Events (SSE)

Enabling Streaming

Set stream: true in your chat completions request:

SSE Response Format

The server sends chunks as data: prefixed JSON objects:

Chunk Structure

string
Unique identifier for the completion (same across all chunks).
string
Always chat.completion.chunk.
integer
Unix timestamp when the completion was created.
string
The model used for generation.
array
Array of completion choices (typically one element).
integer
Choice index (0 for single-choice requests).
object
Incremental changes to the message.
string
Set to assistant in the first chunk only.
string
Text content delta for this chunk.
array
Incremental tool call updates (if function calling is used).
string
Why generation stopped. null for intermediate chunks, set in final chunk:
  • stop: Natural completion
  • length: Max tokens reached
  • tool_calls: Model called a function
  • content_filter: Content filtered
object
Token usage statistics (only in final chunk with finish_reason).

SSE Headers

Keep-Alive Behavior

The SSE connection uses chunked transfer encoding and flushes after each chunk. The server automatically handles:
  • Immediate Flush: Each chunk is sent immediately to minimize latency
  • Connection Management: Graceful handling of client disconnects
  • Error Streaming: Errors during streaming are sent as error chunks (not HTTP errors)

WebSocket Streaming

For more advanced use cases, CLI Proxy API provides a WebSocket endpoint that supports:
  • Bidirectional communication
  • Multi-turn conversations without reconnecting
  • Incremental input appending
  • Session management

WebSocket Endpoint

Note: Use wss:// for secure WebSocket connections over TLS.

Authentication

WebSocket authentication is controlled by the websocket_auth configuration setting:
When enabled, authenticate via query parameter or WebSocket subprotocol:

Request Format

Send JSON text messages with one of these types:

1. response.create

Start a new conversation:

2. response.append

Continue an existing conversation:
The server automatically merges the previous response output with the new input.

3. Incremental Input (Advanced)

For providers that support WebSocket v2 mode (like Codex), use previous_response_id:
This sends only the incremental input without expanding the full conversation history.

Response Events

The server sends JSON text messages with different event types:

response.created

Content Deltas

Streaming content chunks:

response.completed

error

WebSocket Implementation

From openai_responses_websocket.go:49-194:
Key features:
  • Session Pinning: Once a provider is selected for the first request, subsequent requests in the session use the same provider
  • Error Handling: Errors are sent as WebSocket messages, not connection closes
  • Automatic Reconnect: Clients can reconnect with the same x-codex-turn-state header to resume a session

JavaScript Example

Python Example (SSE)

Configuration

Disable WebSocket Authentication

For development or internal networks:

Keep-Alive Settings

For long-running streams, the proxy includes keep-alive mechanisms:
  • SSE: Automatic flush after each chunk
  • WebSocket: Ping/pong frames handled by underlying gorilla/websocket library
  • HTTP Timeouts: Configurable via reverse proxy (Nginx, etc.)
WebSocket connections remain open until explicitly closed by the client or an error occurs. Make sure to implement proper connection management in production.

Error Handling

SSE Errors

Errors during SSE streaming are sent as error chunks:

WebSocket Errors

WebSocket errors are sent as error event messages:
The connection remains open after error messages, allowing retry logic.

Best Practices

  1. Connection Reuse: For multiple requests, use WebSocket instead of opening new SSE connections
  2. Timeout Handling: Implement client-side timeouts for stalled streams
  3. Graceful Degradation: Fall back to non-streaming if streaming fails
  4. Buffer Management: Process chunks immediately to avoid memory buildup
  5. Error Recovery: Implement exponential backoff for reconnection attempts
The streaming implementation automatically handles provider-specific quirks and normalizes responses to the OpenAI format. See sdk/api/handlers/openai/openai_handlers.go for the SSE implementation and openai_responses_websocket.go for WebSocket handling.