Reading streamed output
Handle protocol events without treating partial content as the final response.
No current prepared translation is available. The English source is shown without machine translation.
Choose stream: true on an endpoint/model that supports progressive output. Keep the connection open and parse Server-Sent Events as a stream. HTTP chunks and SSE events are not necessarily aligned: buffer incomplete lines and event blocks before decoding their JSON.
Request
curl -N https://api.b2b-llm.com/v1/chat/completions \
-H "Authorization: Bearer $B2B_API_KEY" -H 'Content-Type: application/json' \
-d '{"model":"gpt-5.4","messages":[{"role":"user","content":"Write a two-line project update."}],"stream":true}'
Response events
data: {"choices":[{"index":0,"delta":{"content":"Project"}}]}
data: {"choices":[{"index":0,"delta":{"content":" update"},"finish_reason":null}]}
data: [DONE]
This example is Chat Completions. Anthropic uses named events such as message_start, content_block_delta and message_stop; Responses uses response/output-item events. Do not run a Chat-only parser against another event family.
Failure and usage handling
A connection that began successfully can later carry a provider error or terminate before its final event. Treat partial text as partial, retain the request ID and show a useful failure state. Do not automatically resend a billable request merely because the browser lost its connection. Usage may only be available in a terminal event or subsequent settled history; an early chunk is not a final accounting record.
Streaming and native deferred async: true cannot be combined. Disable buffering in your own relay only when it can preserve the selected protocol's event boundaries and cancellation behavior.
Reconcile a stream with project usage
An organization request can retain HTTP200 while its stream outcome is provider_error, transport_error or incomplete. Responses must reach response.completed, native Messages must reach message_stop, and Chat must finish every requested choice or emit [DONE]. A transport close alone is not a completion certificate. Do not rerun a partial project request automatically.
Real provider counters remain the accounting source, even when only partial usage was observed. For a successfully completed text stream with no counters, the gateway labels the fallback as estimated and counts decoded generated delta bytes rather than repeated transport envelopes; a supplied output ceiling limits the estimate. An unmetered failure instead appears as unknown usage requiring review, with no automatic transport-byte charge. This does not certify that the upstream incurred no cost. Keep the request ID for your organization's billing investigation; membership/project access remains unchanged.
Connection liveness is not project progress
Your integration can receive SSE comment lines (:) between content events. They keep an established stream active but must not appear in the generated report, token count or company usage. Read complete SSE events, with LF, CRLF or CR separators, even when a line spans several reads.
For Chat Completions, a finish reason may precede the provider's final usage record; continue through [DONE]. Responses and native Messages instead end at response.completed and message_stop. The gateway closes its upstream reader at a valid protocol terminal rather than holding the request until the provider closes its socket.
A silent upstream eventually produces a stream error instead of invented text or a successful ending. Preserve the received partial work and request ID; an explicit user decision is required before another billable attempt. Waiting for the first HTTP headers is a separate stage with no SSE comments yet, and receiving a comment is not evidence that the provider is generating project content.