Consume Server-Sent Events

Consume Server-Sent Events (SSE, `text/event-stream`), where the server pushes a continuous stream of events down a single open connection.

Overview

Consume Server-Sent Events (SSE, `text/event-stream`), where the server pushes a continuous stream of events down a single open connection.

In code

# -N disables buffering so events print as they arrive:
curl -N https://api.example.com/events \
  -H 'Accept: text/event-stream'
const es = new EventSource('https://api.example.com/events');
es.onmessage = (e) => console.log('data:', e.data);
es.addEventListener('ping', (e) => console.log('ping', e.data));
es.onerror = () => { /* browser auto-reconnects */ };
// es.close() to stop
import requests

with requests.get('https://api.example.com/events',
                  headers={'Accept': 'text/event-stream'},
                  stream=True) as r:
    for line in r.iter_lines(decode_unicode=True):
        if line.startswith('data:'):
            print(line[5:].strip())

Details

An SSE response has `Content-Type: text/event-stream` and sends a text stream of `data:`, `event:`, `id:`, and `retry:` fields, with events separated by blank lines. In curl, pass `-N` (`--no-buffer`) so events appear the instant they arrive rather than being buffered.

The browser's `EventSource` is a dedicated SSE API that parses the stream and auto-reconnects for you. On disconnect it reconnects and sends the last `id:` it saw as the `Last-Event-ID` header so the server can resume from the missed event. Note that `EventSource` only supports GET and cannot set custom headers, so if you need an auth token you may implement SSE manually via fetch streaming.

SSE is one-way, server-to-client. For bidirectional real-time, use WebSocket. If a proxy or load balancer buffers the response, events arrive in bursts, so the server should disable buffering with `Cache-Control: no-cache` and (for nginx) `X-Accel-Buffering: no`.

Related headers

Related status codes