How to parse a server-sent events body

By

Split a finished text/event-stream body into events in the browser. Each event has a name, an id, and data. A block with no blank line is dropped.

Free toolThis tutorial uses the SSE Frame Parser. It runs in your browser, so open it in another tab and follow along.

A server-sent events body is text/event-stream. Lines belong to a block. A blank line ends the block and dispatches an event. The SSE frame parser follows those HTML rules for one complete string. The body stays in the browser. It is not stored in the URL.

This page reads a finished body. A chunk that arrived cut in half stays as you pasted it. Joining packets is a different job, the one a streaming client does while bytes are still arriving.

Parse the sample

  1. Open the SSE frame parser.
  2. Click Load sample.
  3. Read the event list. Copy writes the summary. Download saves sse.txt.

The sample is:

: stream started
id: msg-1
event: delta
data: {"text":"Hello"}

event: delta
data: {"text":" there"}

id: msg-2
event: done
data: {"ok":true}
retry: 3000

The summary is:

Events: 3
Retry: 3000 ms
1. type=delta id=msg-1
{"text":"Hello"}
2. type=delta id=msg-1
{"text":" there"}
3. type=done id=msg-2
{"ok":true}

The note is: Ignored comment line: ”: stream started”

The second delta has no new id line, so it keeps msg-1. The id on an event is the one committed by the blank line. retry: 3000 sets the retry to 3000 milliseconds when that field line is read.

A block with no blank line is dropped. This input has a data line and then the end of the text:

data: hi

The summary is:

Events: 0
Retry: not set

The note is: The stream ends without a blank line, so the last block was not dispatched.

Comment lines start with :. The field name is the text before the first colon. One leading space after that colon is removed. Names are case-sensitive. A data line with no colon has an empty value. An empty data buffer stays undispatched. An id that contains a null character is ignored. retry is used when the value is ASCII digits and the number is a safe integer. 03000 is read as 3000. An unknown field is ignored.

One leading BOM, U+FEFF, is removed. Files up to 1 MB open from Open file. The page stops at 1,000,000 characters. After 30 notes, further notes are omitted.

How this page splits a server-sent events bodyA finished text/event-stream body is split on blank lines. Each block becomes an event with a type, an id, and data. A block with no blank line is dropped.YesEnd of textFinished bodyRead linesBlank line?Dispatch the eventDrop the unfinishedblock

How to stream LLM responses with server-sent events is about streaming a model response, including a chunk that arrives cut in half. Server-Sent Events: streaming from server to browser is the general guide. Introduction to WebSockets is the other transport.

WebSocket, SSE, or polling compares the three transports. JSON formatter pretty-prints a data payload after you have the event. Headers explainer reads the response headers around the stream.

Try the SSE Frame Parser

Paste a finished text/event-stream body and list each event name, id, and data. The split follows the HTML Standard. A block with no blank line is dropped.

Open the SSE Frame Parser →

  • WebSocket vs SSE vs Polling: Six questions to pick WebSocket, SSE, or HTTP polling — with a comparison table and anti-recommendations for serverless.
  • JSON Formatter & Validator: Validate, pretty-print, and minify JSON with clear error messages. Runs entirely in your browser.
  • HTTP Response Headers Explainer: Paste response headers and get each one explained — plus warnings for missing security headers like HSTS and CSP.

More tool tutorials →

Want me to talk about your product? You can sponsor this site.