← Blog

Claude API WebSocket Streaming Tutorial Guide

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

Does Claude's API actually support WebSockets?

No. Anthropic's Claude API does not expose a WebSocket endpoint. If you're looking for "claude api websocket streaming tutorial" because you want real-time, token-by-token output in your app, what you actually want is server-sent events (SSE) over a standard HTTPS connection — Claude streams responses that way, and it behaves a lot like a WebSocket from the client's perspective, just without a persistent bidirectional socket.

This matters because a lot of tutorials conflate "streaming" with "WebSocket," and if you go looking for wss:// endpoints in Anthropic's docs or any Claude-compatible API, you won't find them. Below is how streaming actually works, a working implementation, and — if you genuinely need a WebSocket layer (for broadcasting to multiple browser tabs, for example) — how to build one on top of it.

Why Claude uses SSE instead of WebSockets

SSE and WebSockets solve different problems:

Claude's "streaming" is exactly the second case: you send one message, Claude generates tokens, and you receive them incrementally as event: lines over the same HTTP response. There's no need for a persistent socket because there's no ongoing two-way conversation at the transport layer — each turn is still a discrete request.

This also makes Claude streaming easier to work with in serverless environments, behind corporate proxies, and in browsers without extra libraries, since fetch and EventSource-style parsing both handle it natively.

Implementing real-time streaming with curl

Enable streaming by setting "stream": true on your request:

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-4-20250514",
    "max_tokens": 1024,
    "stream": true,
    "messages": [{"role": "user", "content": "Explain SSE in two sentences."}]
  }'

The response comes back as a sequence of event: / data: pairs — message_start, repeated content_block_delta events carrying token chunks, message_delta, and finally message_stop. There's no socket handshake, no Upgrade header, just a long-lived HTTP response being read incrementally.

Parsing the stream in JavaScript

In the browser or Node, you read the response body as a stream and split on newlines:

const response = await fetch("https://api.anthropic.com/v1/messages", {
  method: "POST",
  headers: {
    "x-api-key": process.env.ANTHROPIC_API_KEY,
    "anthropic-version": "2023-06-01",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-opus-4-20250514",
    max_tokens: 1024,
    stream: true,
    messages: [{ role: "user", content: "Stream this response." }],
  }),
});

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();

  for (const line of lines) {
    if (line.startsWith("data:")) {
      const payload = JSON.parse(line.slice(5));
      if (payload.type === "content_block_delta") {
        process.stdout.write(payload.delta.text);
      }
    }
  }
}

That's the whole pattern: one HTTP request, incremental reads, no socket management, no reconnect logic beyond normal HTTP retry handling.

When you actually need a WebSocket on top

There are legitimate cases where you want a WebSocket even though Claude itself doesn't use one:

In all of these, the WebSocket sits between your server and your client — not between your server and Claude. The pattern is:

  1. Your backend opens a normal SSE/HTTP streaming request to Claude.
  2. As chunks arrive, your backend forwards them over the existing WebSocket connection to the client.
  3. The WebSocket layer is yours to manage (ping/pong, reconnects, auth) — Claude's API is unaware of it.

This is a thin proxy, not a protocol translation hack. Most teams that think they need "Claude WebSocket streaming" actually need this: a WebSocket between browser and their own server, with SSE between their server and Claude.

Where SubToAPI fits in

If you're building this proxy layer yourself, you still have to handle API key management, retries, and streaming response parsing on your backend before it ever reaches your WebSocket clients. SubToAPI turns your existing Claude access into a standard HTTPS API with sub_live_... application keys, and its streaming support (see /docs/streaming) follows the same SSE event structure described above — so the same parsing code works whether you're calling Claude directly or through SubToAPI.

That's useful if you want to give each service or team member their own scoped key instead of sharing one raw API key across your WebSocket proxy, your batch jobs, and your CI pipeline. You can check the request/response shape in /docs/messages, and the full setup in /docs/quickstart. Plans start with a free trial at /signup, with pricing at /pricing.

Questions

Is there a WebSocket endpoint for the Claude API? No. Claude's API streams responses over standard HTTPS using server-sent events when you set stream: true. There is no wss:// endpoint, and none is needed for the request/response streaming pattern Claude uses.

How do I get real-time token output without WebSockets? Set "stream": true in your request body and read the HTTP response incrementally, parsing the data: lines for content_block_delta events. This gives you token-by-token output over a normal HTTP connection, as shown in the curl and JavaScript examples above.

When should I add a WebSocket layer in front of Claude streaming? Add one only when you need to push Claude's output to multiple clients at once, combine it with other real-time events (presence, typing indicators), or route it through an existing WebSocket connection your app already maintains. The WebSocket sits between your server and your clients — your server still talks to Claude over standard HTTP streaming.

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 →