Streaming Response

Streaming delivers partial results as they're generated, allowing your application to display text incrementally instead of waiting for the full response. This creates a much better user experience, especially for long responses.

How Streaming Works

When you set stream: true, the API returns a stream of Server-Sent Events (SSE). Each event contains a chunk of the response as it's generated.

Using cURL

curl https://openapi.linkwo.ai/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4-pro",
    "messages": [{"role": "user", "content": "Write a haiku about coding"}],
    "stream": true
  }'

The response is a stream of data: lines:

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"content":"Silent"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"content":" keys"},"finish_reason":null}]}

data: [DONE]

Using Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    base_url="https://openapi.linkwo.ai/v1",
    api_key="YOUR_API_KEY"
)

stream = client.chat.completions.create(
    model="deepseek/deepseek-v4-pro",
    messages=[{"role": "user", "content": "Explain quantum computing in simple terms"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)

Using Node.js (OpenAI SDK)

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://openapi.linkwo.ai/v1',
  apiKey: 'YOUR_API_KEY',
});

const stream = await client.chat.completions.create({
  model: 'deepseek/deepseek-v4-pro',
  messages: [{ role: 'user', content: 'Explain quantum computing in simple terms' }],
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content || '';
  process.stdout.write(content);
}

Stream Chunk Format

Each chunk in the stream has this structure:

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion.chunk",
  "created": 1719000000,
  "model": "deepseek/deepseek-v4-pro",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "partial text"
      },
      "finish_reason": null
    }
  ]
}

Delta vs Message

FieldNon-streamingStreaming
Content locationchoices[].message.contentchoices[].delta.content
ContentComplete responseIncremental fragment
finish_reasonAlways presentnull until final chunk

The first chunk typically includes delta.role: "assistant". Subsequent chunks contain delta.content fragments. The final chunk has finish_reason: "stop" and empty delta.

When to Use Streaming

Use CaseStreaming?
Chat interfacesYes — show text as it generates
Batch processingNo — collect full response for processing
API integrationsDepends — use if latency matters
Function callingNo — need complete structured output

Best Practices

  • Always handle the [DONE] marker — it signals the end of the stream
  • Set a timeout — network issues can cause streams to hang
  • Buffer small chunks — for display purposes, consider buffering to avoid excessive re-renders
  • Handle disconnects — implement retry logic for broken connections

Next Steps