Blog · 2026-07-10

Streaming a Free LLM API: Server-Sent Events Explained

Free LLM API streaming is the difference between a chat box that sits blank for eight seconds and one that starts typing back almost instantly. When you stream, the model sends its answer word by word as it is generated, so your users see progress right away instead of staring at a spinner. This guide explains what streaming is, why it improves perceived latency, and exactly how to consume it from curl, Python, and JavaScript using the DreamPrompting Free LLM API. It is a free, OpenAI-compatible gateway, and the only setup is a free API key you can create in seconds at /account, so everything here works with tools you already know.

Why stream LLM responses at all

A large model can take several seconds to finish a full answer. Without streaming, your app waits for the entire response before showing anything. With streaming, the first tokens arrive in a few hundred milliseconds and the rest flow in as they are ready. The total generation time is roughly the same, but the perceived latency drops dramatically because the user reads along as the model writes.

How Server-Sent Events work

Free LLM API streaming uses Server-Sent Events (SSE), a simple text protocol over a normal HTTP response. Instead of one JSON body, the server keeps the connection open and pushes a series of lines. Each event begins with data: followed by a JSON fragment, and events are separated by blank lines. When the model is done, the server sends a final data: [DONE] line and closes the stream. You do not need websockets or any special library, just the ability to read a response as it arrives.

To turn streaming on, pass "stream": true in your POST body to /api/v1/chat/completions. The base URL is https://dreamprompting.com/api/v1. Every request needs your free API key, so pass it anywhere an API key is expected and send it as Authorization: Bearer YOUR_API_KEY on raw HTTP calls. Use "model": "auto" to let the gateway pick and fail over automatically, or name a specific provider/model from the models list.

The chunk shape

Each SSE event carries an OpenAI-compatible chat.completion.chunk object. The new text lives in choices[0].delta.content. Early chunks may carry a role instead of content, and the last content chunk sets finish_reason. Here is one example event from the stream:

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1720598400,"model":"auto","choices":[{"index":0,"delta":{"content":" world"},"finish_reason":null}]}

Your job is to read each line, strip the data: prefix, parse the JSON, and append the delta content. Stop when you see [DONE].

Streaming with curl

The fastest way to watch free LLM API streaming in action is curl with the -N flag, which disables buffering so lines print as they arrive.

curl -N https://dreamprompting.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "stream": true,
    "messages": [{"role": "user", "content": "Say hello world"}]
  }'

Streaming with the Python OpenAI SDK

Because the gateway is OpenAI-compatible, the SDK's stream=True works unchanged. Point the base URL at DreamPrompting and iterate over the chunks.

from openai import OpenAI

client = OpenAI(
    base_url="https://dreamprompting.com/api/v1",
    api_key="YOUR_API_KEY",
)

stream = client.chat.completions.create(
    model="auto",
    stream=True,
    messages=[{"role": "user", "content": "Say hello world"}],
)

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

If you prefer no SDK at all, you can read the raw SSE stream with the requests library. Set stream=True on the request, iterate lines, drop the data: prefix, and break on [DONE].

import json, requests

API_KEY = "YOUR_API_KEY"

resp = requests.post(
    "https://dreamprompting.com/api/v1/chat/completions",
    headers={"Authorization": f"Bearer {API_KEY}",
             "Content-Type": "application/json"},
    json={"model": "auto", "stream": True,
          "messages": [{"role": "user", "content": "Say hi"}]},
    stream=True,
)

for line in resp.iter_lines():
    if not line:
        continue
    text = line.decode("utf-8").removeprefix("data: ")
    if text == "[DONE]":
        break
    print(json.loads(text)["choices"][0]["delta"].get("content", ""), end="")

Streaming with JavaScript fetch

In the browser or Node, use fetch and read the response body as a ReadableStream. Decode each chunk, split on newlines, and handle each SSE event as it arrives.

const res = await fetch("https://dreamprompting.com/api/v1/chat/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.DREAM_API_KEY}`,
  },
  body: JSON.stringify({
    model: "auto",
    stream: true,
    messages: [{ role: "user", content: "Say hello world" }],
  }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop();
  for (const line of lines) {
    if (!line.startsWith("data:")) continue;
    const data = line.slice(5).trim();
    if (data === "[DONE]") break;
    const json = JSON.parse(data);
    const delta = json.choices[0].delta.content;
    if (delta) process.stdout.write(delta);
  }
}

Keep a small buffer because a single network read can split an SSE line in half. Buffering the tail until the next newline arrives keeps your JSON parsing safe. The service allows 100 requests per minute, plus a rolling 24 hour account quota of 5,000 requests and 500,000 tokens, which is plenty for building and testing a streaming UI.

FAQ

Do I need an API key to stream? Yes, and it is free. Sign in with Google at /account, copy your key, and pass it as Bearer YOUR_API_KEY. No credit card is involved. See the API docs for the full request format.

Is streaming slower or more expensive? No. Streaming uses the same free endpoint and roughly the same total time. It only changes when the bytes reach you, which is what makes the UI feel faster.

What ends the stream? A final data: [DONE] line. Treat it as your signal to stop reading and close the connection. This is a free fair-use service, so keep within the 100 requests per minute limit and your rolling 24 hour account quota.

Start streaming now

Free LLM API streaming takes just one flag to enable and a few lines to consume. Read the full reference in the API docs, browse available options on the models page, or try it live in the chat playground.