stream: true and read server-sent events. This guide covers the actual UI pattern: showing tokens as they arrive, then revealing which model answered and what it cost, once the answer is complete.
Basic Streaming
Getting the Routing Decision Mid-Stream
A streamed response doesn’t have aroutor field on each chunk the way a non-streaming response has one on the final object - the routing decision only becomes final once the full answer is generated (final token usage isn’t known until the stream ends). To get it, opt in with routor_events: true in the request body:
[DONE], carrying the full decision:
routor key instead of choices to catch this event:
@ts-expect-error/as any casts are only needed because routor_events and the routor event aren’t part of the official OpenAI SDK’s types - the request and response both work fine at runtime without them if you’re not using TypeScript, or if you’re building the request/parsing the stream by hand instead of through the SDK.)
Building the UI Pattern
The natural UI is: show tokens as they stream in, then reveal a small routing badge once theroutor event arrives - this is exactly what the dashboard’s Chat page and the Try Routor app both do. Rough shape:
- Render the assistant bubble as empty, tokens appended as they arrive
- When a
routorevent lands, stop appending text and render the routing summary (model, tier, savings %) either above or below the finished answer finishReasonon that event tells you whether the answer completed normally ("stop") or was cut off by a token limit ("length") - worth showing a “response truncated” note in the second case
Where to Go Next
- Full request/response reference - every request field, non-streaming included
- Build your first app - the non-streaming starting point this guide builds on