All documentation

Streaming

Streaming is passed through unchanged. What differs is when the request is metered and when your balance settles.

Enabling it

Set stream: true on the request, exactly as you would against the upstream API. No SP Cambo-specific parameter or header is required, and no client patch is needed. Claude Code and Codex CLI stream by default.

Transport

Streams are server-sent events. The gateway forwards upstream events as they arrive and does not buffer the response to completion, so first-token latency is the upstream latency plus routing overhead.

If you are placing your own proxy in front of SP Cambo, disable response buffering on it. A buffering proxy turns a working stream into a request that appears to hang and then delivers everything at once — this is the single most common cause of "streaming does not work" reports, and it is not something the gateway can detect for you.

When a streamed request is metered

Budget is reserved before the first upstream byte. A stream is not started unless the reservation safely covers the completion you asked for, which is why an oversized max_tokens against a nearly-spent package can be refused up front rather than failing halfway through.

When the stream ends, the actual usage reported upstream is settled and the unused part of the reservation is released. Between those two moments your activity row shows an estimated figure.

Estimated rows are never what you are charged. Read the value again after settlement — the dashboard marks the row and updates it in place.

Reading usage from a stream

Token counts are not on the individual deltas. They arrive with the terminal event of the stream, which the official SDKs expose as the final message. If you are parsing SSE by hand, accumulate the deltas for text and read usage from the last event rather than trying to count tokens yourself.

Interruptions and cancellation

If you abort a stream — closing the connection, cancelling the SDK request, Ctrl-C in a CLI — the request still settles on what was actually produced before the abort. Cancelling early is not a way to get a completion for nothing, but nor are you charged for the tokens that were never generated.

If the upstream call fails in a way that qualifies for a refund, the reservation is released exactly once. You do not need to ask for that, and re-checking does not double-release.

A stream that dies mid-response is a normal network event, not a lost request. Retry it — see rate limits for the backoff behaviour to use.

Errors during a stream

An error raised before the stream opens looks like any other failure: an HTTP status and a JSON body carrying a machine code. An error raised after the first event has already been sent arrives as an error event inside the stream, because the status line has already gone out as 200.

Handle both. Treating any 200 as success is the classic streaming bug: your client reports a successful call while the user sees a truncated answer. The SDKs surface in-stream errors as exceptions, so this mostly matters if you are reading SSE directly.

What is recorded

The same metadata as any other request: alias, key, timing, token counts and settlement state. Streamed content is forwarded, not stored — no prompt text and no completion text is retained, including for streams that fail partway through.