← Blog

Claude API Streaming: Token-by-Token Display Guide

2026-10-12 · 5 min read · SubToAPI Team

Streaming lets your app render Claude's response as it's generated, word by word, instead of making users stare at a blank screen until the full reply is ready. This is done using server-sent events (SSE): the API keeps an open HTTP connection and pushes small chunks of text (called deltas) as the model produces them, and your frontend appends each chunk to the UI in real time.

If you've searched for "claude api streaming token by token display," you're probably trying to build a chat interface that feels responsive — like ChatGPT or Claude.ai, where text appears incrementally. Below is exactly how that works, both with Anthropic's native API and with SubToAPI if you want a simpler HTTPS/SSE contract with usage metadata baked in.

How token-by-token streaming actually works

When you set "stream": true in your request, the API doesn't wait until the whole response is generated. Instead, it sends a sequence of events over a single HTTP connection:

Each content_block_delta event contains a small fragment of text — sometimes a few characters, sometimes a full word or two. Your job on the frontend is simple: listen for these events and append the text to whatever element is displaying the response.

Streaming with curl (raw SSE)

You can see this behavior directly with curl against any Claude-compatible streaming endpoint:

curl -N https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 512,
    "stream": true,
    "messages": [
      {"role": "user", "content": "Write a haiku about rivers."}
    ]
  }'

The -N flag disables curl's output buffering so you see each event as it arrives instead of all at once at the end. You'll see a stream of event: and data: lines scroll in your terminal — that's token-by-token generation happening live.

Parsing the stream in JavaScript

In a real app, you need to parse the SSE stream and update your UI incrementally. Here's a minimal fetch-based implementation that works in the browser or Node:

async function streamMessage(prompt, onToken) {
  const response = await fetch("https://api.subtoapi.app/v1/messages", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      model: "claude-sonnet-4-5",
      max_tokens: 1024,
      stream: true,
      messages: [{ role: "user", content: prompt }]
    })
  });

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

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split("\n");
    buffer = lines.pop(); // keep incomplete line for next chunk

    for (const line of lines) {
      if (!line.startsWith("data: ")) continue;
      const payload = line.slice(6);
      if (payload === "[DONE]") return;

      const event = JSON.parse(payload);
      if (event.type === "content_block_delta") {
        onToken(event.delta.text);
      }
    }
  }
}

// Usage: append each token to a <div> as it arrives
let output = "";
await streamMessage("Explain recursion in one paragraph.", (token) => {
  output += token;
  document.getElementById("response").textContent = output;
});

This pattern — read the stream, split on newlines, parse data: lines as JSON, react to content_block_delta — is the core of almost every streaming chat UI you'll build, regardless of frontend framework.

Rendering tips for a smooth display

A few practical details that matter once you move past the toy example:

Why use SubToAPI for this instead of raw Anthropic streaming

If you already have Claude access through a subscription and want to expose it as an HTTPS API with the same SSE streaming contract, SubToAPI gives you sub_live_... application keys, the same /v1/messages streaming shape described above, plus usage metadata per request and team seats — without you having to manage separate billing or key infrastructure. The streaming behavior is identical to what's shown in this article: stream: true, SSE events, content_block_delta chunks. See the streaming docs and messages docs for the full event reference, or the quickstart to get an API key in a few minutes. Plans start at €9/month on the Solo tier, with Team and Scale options for multi-seat setups — details on pricing. You can try it with a free trial at signup.

FAQ

Does streaming cost more tokens than a non-streaming request? No. Token usage and billing are based on input and output token counts, not on whether the response is streamed or returned all at once. Streaming only changes delivery timing, not cost.

Can I stream tool use calls the same way as text? Yes. Tool use blocks stream through the same event sequence (content_block_start, content_block_delta, content_block_stop), but the deltas contain partial JSON for tool inputs instead of text. See the tools docs for how to assemble and validate that partial JSON before executing a tool call.

Why does my stream cut off mid-sentence in production but not locally? This is almost always a proxy or load balancer buffering the response and timing out the connection. Make sure any reverse proxy (nginx, CDN, etc.) has buffering disabled for SSE routes and that read timeouts are long enough for slow model responses.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →