No KYC — no ID, no selfie, no documents. Pay in crypto: BTC, USDT, USDC, ETH, SOL, LTC
Language: English
Get an API key

Docs · streaming

Streaming responses: the answer as it is written

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].

Last updated: · 3 min read

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
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
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
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)
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 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 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.

DeepSeek V4 Pro from $1.254 per 1M input tokens · no KYC

Get an API key