SSE Event Types
Server-Sent Events defines three browser events and four stream fields. The browser events (message, open, error) fire on the EventSource object. The stream fields (data, event, id, retry) are written by the server in the text/event-stream response.
WHATWG
HTML §9.2
Fields: data: event: id: retry: # comment
Browser Events
message
§9.2.6event: message (default)
The default SSE event type. Fired when the server sends a data: field without an explicit event: field, or when event: message is set explicitly. Handled by the EventSource onmessage handler or addEventListener('message', handler). The most commonly used event type for LLM token streaming.
open
§9.2.3EventSource onopen
The open event fires on the EventSource object when the connection to the server is established and the HTTP response headers have been received with Content-Type: text/event-stream. It does not correspond to a server-sent event field – it is fired by the browser when the connection is ready. EventSource.readyState changes from CONNECTING (0) to OPEN (1).
error
§9.2.3EventSource onerror
The error event fires when the EventSource connection fails: network error, wrong Content-Type, non-2xx HTTP response, or the server closes the connection. After an error, the browser automatically schedules a reconnect unless the error is permanent (HTTP 204 stops reconnection). The error event provides no detail about the cause – check readyState to distinguish reconnecting from closed.
Stream Fields
Custom Event Types
§9.2.5 / §9.2.6event: typename
SSE supports named custom event types via the event: field. Any valid string can be used as an event type (except 'message', 'open', 'error' which are reserved). The browser fires a MessageEvent with event.type set to the custom name. Clients subscribe with addEventListener('typename', handler). Custom types are essential for multiplexing multiple data streams on a single SSE connection.
id and retry Fields
§9.2.5 / §9.2.6id: / retry:
The id: field sets the Last-Event-ID – a cursor the browser sends on reconnect so the server can resume from the right position. The retry: field (milliseconds integer) sets the reconnect delay. Both are set by the server; the browser tracks id: automatically and sends it as a request header on reconnect. These two fields enable resumable SSE streams without application logic.
LLM streaming: OpenAI, Anthropic, and Google Gemini all stream tokens via SSE. The pattern: data: {"delta": "token"} repeated, then data: [DONE] as sentinel. Source: WHATWG HTML §9.2 →