# Streaming responses: the answer as it is written

> Stream chat completions with server-sent events: stream: true, the chunk format, token usage in the last event, and examples in curl, Python and Node.js.

- URL: https://llmwithcrypto.com/docs/streaming/
- Last updated: 2026-10-23
- Publisher: LLMwithCrypto (https://llmwithcrypto.com)

With `stream: true`, the answer arrives in small pieces as the model writes it, the way chat interfaces show text appearing. The format is the OpenAI one: server-sent events, one JSON chunk per event, then `[DONE]`.

**Quick answer — How do I stream a chat completion from LLMwithCrypto?**

Add `"stream": true` to the body of `POST https://llmwithcrypto.com/api/v1/chat/completions`. **LLMwithCrypto** then answers with server-sent events: each `data:` line holds a `chat.completion.chunk` with a piece of text in `delta.content`, and the stream ends with `data: [DONE]`. Add `"stream_options": {"include_usage": true}` to get the token counts in a last chunk. This works on every model, as documented on 23 October 2026.

## Why stream at all?

For people, because the first words appear within a moment instead of after the whole answer is written. A long answer from a large model can take many seconds to finish; streamed, the reader starts reading right away.

For programs it matters less: a script that needs the full text gains nothing from streaming and has more parsing to do. Stream when a human is watching, and send a normal request otherwise. The price is the same either way. You pay per token from your balance: input and output tokens are counted by the model’s own tokenizer and charged at that model’s price per 1M tokens. A call that ends in an error costs nothing.

*curl: -N keeps the connection unbuffered*

```bash
curl -sN "https://llmwithcrypto.com/api/v1/chat/completions" \
  -H "Authorization: Bearer $LLMWITHCRYPTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4.1-flash",
    "messages": [{"role": "user", "content": "Write a haiku about latency."}],
    "stream": true,
    "stream_options": {"include_usage": true},
    "max_tokens": 120
  }'

```

*Python: print the text as it arrives*

```python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://llmwithcrypto.com/api/v1",
    api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)

stream = client.chat.completions.create(
    model="deepseek-v4.1-flash",
    messages=[{"role": "user", "content": "Write a haiku about latency."}],
    stream=True,
    stream_options={"include_usage": True},
    max_tokens=120,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:
        print("\n", chunk.usage.prompt_tokens, "in,", chunk.usage.completion_tokens, "out")

```

*Node.js: for await over the chunks*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const stream = await client.chat.completions.create({
  model: 'deepseek-v4.1-flash',
  messages: [{ role: 'user', content: 'Write a haiku about latency.' }],
  stream: true,
  stream_options: { include_usage: true },
  max_tokens: 120,
});
for await (const chunk of stream) {
  const text = chunk.choices[0]?.delta?.content;
  if (text) process.stdout.write(text);
  if (chunk.usage) console.log(`\n${chunk.usage.prompt_tokens} in, ${chunk.usage.completion_tokens} out`);
}

```

## What does the stream look like on the wire?

Each event is one line starting with `data: `, followed by a blank line. The first chunk usually carries the `role`, the next ones a few characters of `content` each, and the chunk with a `finish_reason` closes the answer. With `include_usage`, one more chunk follows with an empty `choices` array and the `usage` object. The stream always ends with `data: [DONE]`. The ids and counts below are illustrative.

*Server-sent events of one short answer (illustrative)*

```text
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":"Packets"},"finish_reason":null}]}

data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":" cross the"},"finish_reason":null}]}

data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":19,"total_tokens":33}}

data: [DONE]

```

## What if the stream breaks?

An error found before the first token, such as a wrong key or an empty balance, comes back as a normal HTTP error with a JSON body, not as a stream; the [errors page](https://llmwithcrypto.com/docs/errors/) lists them. An error during generation ends the stream early, without a `finish_reason`.

If you close the connection yourself, generation stops. You then pay for the input and the tokens already generated, as with any call. Your code should treat a stream that ends without a `finish_reason` and without `[DONE]` as incomplete, and send the request again if it needs the full answer.

## Streaming: common questions

### Does streaming cost more?

No. The same tokens are billed at the same price. You pay per token from your balance: input and output tokens are counted by the model’s own tokenizer and charged at that model’s price per 1M tokens. A call that ends in an error costs nothing.

### Can I stream with tool calling?

Yes, on the models that support tools: the function name and arguments arrive in pieces in `delta.tool_calls` and must be joined before use. The [tool calling page](https://llmwithcrypto.com/docs/tool-calling/) shows the non-streamed loop, which is simpler to start with.

### Why do I get no usage in a streamed call?

Add `"stream_options": {"include_usage": true}`. Without it, a stream carries no token counts; the dashboard still shows them.

---

LLMwithCrypto: LLMwithCrypto is an OpenAI-compatible LLM API for open-weight models — DeepSeek V4 Pro, DeepSeek V4.1 Flash, DeepSeek R1, Qwen3.5 397B A17B, Qwen3 235B A22B Instruct, gpt-oss-120b, gpt-oss-20b, GLM-4.7, Llama 3.3 70B Instruct, Gemma 4 31B, Mistral Large 3, Mistral Small 4 — paid per token from a prepaid crypto balance, at 5% below the median price of the public hosts. No KYC: no ID, no selfie, no documents. Prompts and outputs are not stored.
