Stream Protocol, Transport, and Metadata
Purpose and Scope
The stream protocol page explains the contract between an AI SDK backend that produces incremental output and a frontend hook that consumes it. Its main audience is anyone building a custom endpoint, a non JavaScript backend, or a client that needs to interoperate with AI SDK UI behavior rather than only rendering a complete response after the model finishes. The page distinguishes simple text streaming from richer data streaming, and it frames the protocol as an HTTP layer concern used by UI functions such as useChat, useCompletion, and useObject.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
This matters because the UI packages do not merely receive arbitrary bytes. They expect a predictable stream shape so message state, text deltas, tool related parts, metadata, and completion state can be assembled into frontend message objects. A backend written with the AI SDK can rely on helpers such as streamText, toTextStream, and createTextStreamResponse, while a backend written in another stack can still be compatible if it emits the same protocol. The documented FastAPI example points to this cross-language use case directly.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
Relevant Source Files
content/docs/04-ai-sdk-ui/50-stream-protocol.mdx— First-party documentation for AI SDK UI stream protocols, including text streams, data streams, backend response helpers, required headers for custom data streams, and examples for Next.js routes and React chat UI.
Core Primitives
The first primitive is the text stream. A text stream is plain text delivered in chunks, and the frontend appends those chunks to form the final response. It is intentionally narrow: it works well when the only thing the application needs is assistant text, but it cannot represent richer events. In the documented Next.js example, the client selects TextStreamChatTransport, and the route handler converts UI messages into model messages, calls streamText, converts the result with toTextStream, and returns createTextStreamResponse.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
The second primitive is the data stream. A data stream uses Server-Sent Events to send typed stream parts rather than raw text chunks. The documentation highlights the benefits of this choice: standard formatting, keep-alive pings, reconnect capabilities, and improved cache handling. For custom backends, the important compatibility signal is the response header x-vercel-ai-ui-message-stream with value v1. That header tells the UI layer that the response is a versioned AI SDK UI message stream rather than an arbitrary event stream.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
Protocol Parts and Metadata
A data stream begins by describing message boundaries and then emits typed parts inside that message. The documented start part indicates the beginning of a new message and can include metadata such as the message identifier. Text content uses a start, delta, and end pattern with a unique identifier for each text block, so the frontend can append deltas to the correct block and close it when complete. Reasoning content follows the same pattern, separating reasoning deltas from ordinary visible assistant text.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
This shape is important for metadata and custom data because it prevents the client from treating every event as display text. Message-level metadata belongs with the message boundary, while block-level identifiers let the UI correlate deltas across multiple concurrent or interleaved content blocks. When an application needs tool calls, additional structured parts, or app-specific events, it should prefer the data stream protocol over the text protocol. The source page explicitly warns that text streams only support basic text data and recommends data streams for other data types. Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
Transport Choices
Transport is the client-side mechanism that sends messages to an endpoint and processes the response stream. The stream protocol page shows a text-stream-specific transport in the client example, while the official transport documentation describes the default chat transport as HTTP POST to a chat API endpoint. Use the default HTTP style when a normal route handler can receive messages and return an AI SDK compatible stream. Use an explicit text stream transport when the backend intentionally returns plain text chunks instead of the richer data protocol. Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
A practical rule is to choose the stream format before choosing the transport customization. If the backend is a standard AI SDK route, data streams are usually the most future-proof because they preserve message structure, metadata, and non-text parts. If the backend is a legacy service or a minimal completion endpoint, text streams can be easier to implement. If the communication path requires custom authentication, WebSockets, trigger-based routing, or a specialized gateway, customize the transport while keeping the response format compatible with what the consuming hook expects. Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
Execution Flow
For a text stream route, the flow is straightforward. The client calls sendMessage, the route reads an array of UIMessage values from the request body, the server converts those UI messages into model messages, and streamText starts model generation. The route then exposes the model stream as a text response by passing the result stream through toTextStream and createTextStreamResponse. This preserves a small server surface while letting the browser render partial output as it arrives.
Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
For a data stream route, the backend must emit Server-Sent Events that conform to the AI SDK UI message stream protocol. The server should identify the stream version with the required header, send a message start event, emit content parts such as text or reasoning start and delta events, and close each part with its matching end event. A compatible frontend can then reconstruct the message incrementally instead of guessing how bytes map to UI state. This is the preferred path for custom backends that need more than plain assistant text. Sources: content/docs/04-ai-sdk-ui/50-stream-protocol.mdx
Compact Reference
| Concern | Use this when | Key requirement |
|---|---|---|
| Text stream | Only basic assistant text is needed | Enable the text stream protocol on the client and return a text stream response from the backend |
| Data stream | Messages include metadata, typed parts, tool-related data, or custom events | Emit Server-Sent Events using the AI SDK UI message stream protocol |
| Custom backend | The server is not a standard AI SDK route, or is written in another language | Set x-vercel-ai-ui-message-stream: v1 for data streams |
| Message start | A new assistant message begins | Include the stream part that marks the message boundary and metadata |
| Text block | Text arrives incrementally | Emit text start, text delta, and text end parts with a stable block identifier |
| Reasoning block | Reasoning is streamed separately from visible text | Emit reasoning start, reasoning delta, and reasoning end parts with a stable block identifier |
Next Steps
Readers implementing a normal chatbot should start with the UI chatbot guide and return to this page when they need to debug stream shape, replace the backend, or introduce non-text parts. Readers implementing a custom server should prototype the simplest valid stream first, verify that message start and text deltas render correctly, and then add metadata or custom data parts. If transport behavior rather than stream encoding is the hard part, review the transport documentation next and keep the chosen protocol stable while changing how requests are routed.