Skip to main content

Overview

NanoGPT supports streaming responses via Server-Sent Events (SSE). Streaming is available on these endpoints: All SSE streams are delivered as a sequence of data: frames separated by a blank line. Some endpoints also include an event: line to name the event type.

Enabling Streaming

Set "stream": true in the JSON request body. Chat Completions:
Messages:
Responses:
If stream is omitted or false, the endpoint returns a single JSON response.

Chat Completions Streaming (/v1/chat/completions)

Chat Completions streams OpenAI-style chat.completion.chunk objects.

Frame Format

Each SSE frame is a JSON object in a data: line:
The first chunk often includes delta.role: "assistant". Subsequent chunks typically include only incremental deltas like delta.content.

Finish Reasons

The final chunk has a non-null finish_reason:
  • stop
  • length
  • tool_calls
  • content_filter

End of Stream

After the final chunk, the stream terminates with:
Clients should treat [DONE] as a literal string (do not JSON-parse it).

Reasoning / Thinking Deltas

Some models stream reasoning alongside content. Depending on the endpoint variant you use, the delta field may be reasoning or reasoning_content. Example:

Tool Call Deltas

Tool calls stream via delta.tool_calls[]. Accumulate function.arguments across frames for the same tool_calls[index].

Usage In Streaming

Usage is not included by default in streaming. To receive usage, set:
If enabled, the final chunk includes a usage field. (Some features, like prompt caching helpers, can cause usage to be included automatically.) usage can include provider-dependent fields beyond basic token counters, including nested details and cache fields:
  • prompt_tokens
  • completion_tokens
  • total_tokens
  • prompt_tokens_details.cached_tokens
  • prompt_tokens_details.audio_tokens
  • completion_tokens_details.reasoning_tokens
  • completion_tokens_details.audio_tokens
  • completion_tokens_details.accepted_prediction_tokens
  • completion_tokens_details.rejected_prediction_tokens
  • reasoning_tokens
  • citation_tokens
  • num_search_queries
  • cache_creation_input_tokens
  • cache_read_input_tokens
  • input_tokens
When provider usage is missing or zero, NanoGPT may backfill final usage counts from pricing metadata (x_nanogpt_pricing.inputTokens / x_nanogpt_pricing.outputTokens) for consistency.

x_nanogpt_pricing In Streaming

x_nanogpt_pricing is an extension object:
  • In streaming: appears on the final chunk only
  • In non-stream JSON responses: appears as a top-level field
Stable/core fields:
  • amount?: number
  • currency?: string
  • error?: { status?: number; message: string } (message is sanitized)
Common optional fields:
  • cost?: number
  • paymentSource?: string
  • inputTokens?: number
  • outputTokens?: number
  • cacheCost?: number
  • billedToTeam?: boolean
  • billedTeamId?: number | null
  • billedTeamName?: string | null
Compatibility rule: clients must tolerate additional fields and ignore unknown keys. Example final chunk:

Messages Streaming (/v1/messages)

The Messages endpoint streams Anthropic-style named SSE events. Each event includes an event: line and a data: line. Typical sequence:
  1. message_start
  2. content_block_start
  3. content_block_delta (repeated)
  4. content_block_stop
  5. message_delta
  6. message_stop
Example (end of stream):

Tool Use

Tool calls appear as tool_use content blocks. Tool input streams as input_json_delta fragments inside content_block_delta events.

Thinking Blocks

Thinking can appear as a separate content block type (thinking) before normal text blocks.

Usage

Usage information is included near the end of the stream (for example on message_delta), and includes input_tokens and output_tokens. When prompt caching is active, cache token fields may also appear.

Responses Streaming (/v1/responses)

Responses streams a sequence of typed objects. NanoGPT emits these as SSE data: frames containing JSON with a type field (for example response.created, response.output_text.delta, etc.). Example:
Terminal events include:
  • response.completed
  • response.incomplete
  • response.failed

Tool Calls

Tool calls appear as function_call output items. Arguments stream via response.function_call_arguments.delta frames and finish with response.function_call_arguments.done.

Usage

Usage appears on the terminal event inside the full response object (for example response.completed.response.usage).

Error Handling Notes

  • If an error happens before streaming begins, you will receive a normal JSON error response with an HTTP status code.
  • If an error happens mid-stream, the stream may end early. Your parser should handle EOF without a terminal marker as an error/retry condition.
For general status-code handling and retry guidance, see Error Handling.

Raw SSE Parsing Tips

When parsing SSE manually:
  • Events are separated by a blank line (\\n\\n or \\r\\n\\r\\n).
  • A single event can include multiple data: lines; concatenate them with \\n before parsing as JSON.
  • Handle [DONE] as a sentinel string.