Read stream

bucketpathstringrequired

Bucket ID.

streampathstringrequired

Stream ID within the bucket.

offsetquerystring

Starting offset: -1 for the beginning, now for the current tail, or a Stream-Next-Offset value from an earlier response.

cursorquerystring

On a long-poll or SSE read, the Stream-Cursor value from the previous live response. It lets caches tell successive live requests apart. It is not a position and never replaces offset.

consistencyquerystring

local (default) or leader, on catch-up reads only. leader makes the read linearizable: it includes every append acknowledged before the request, at the cost of one round trip from the group's leader to a majority of voters. Use it to read back your own acknowledged writes. Combining it with live answers 400. See Read path.

livequerystring

Live mode: sse for Server-Sent Events, long-poll for long-polling. Omit for catch-up read.

max_bytesquerynumber

On an offset read, the maximum bytes to read in one response or SSE data batch. Every response is capped at 8 MiB; a larger value is clamped, and a value that is not a decimal integer is ignored. A shortened response has no Stream-Up-To-Date and may end inside a message, on a JSON stream too; continue from Stream-Next-Offset. For UTF-8 SSE data, Ursula may shorten the emitted batch so Stream-Next-Offset lands on a valid text boundary.

Read modes

No live parameter. Returns all available data from the given offset immediately.

curl 'http://127.0.0.1:4437/demo/hello?offset=-1'
Stream-Incarnationheaderstring

Optional precondition: the stream's incarnation token, as a previous response's Stream-Incarnation header returned it. The read is answered only if the stream that serves it is still that incarnation; otherwise it answers 412. A long-poll or SSE read with it ends when the stream it was opened against is deleted or recreated (a long-poll answers 404 or 412; an SSE stream ends with an error event). Without the header, a long-poll still ends when the stream it registered against is recreated, usually with 416; otherwise the request behaves exactly as described here. A malformed value answers 400. See Stream-Incarnation.

Response

StatusMeaning
200Data returned. A catch-up read at the tail answers 200 with an empty body and Stream-Up-To-Date: true.
204Long-poll only: timeout_ms passed without new data, or the stream is closed and the read is at its tail (answered at once with Stream-Closed: true, which signals end of stream).
304If-None-Match matched the response's ETag.
307In a cluster, this node could not serve the read as the stream's group leader (a long-poll or SSE read on a follower, or a consistency=leader read on a node that lost leadership). Location is the same request on the leader.
400Invalid offset, live mode or consistency, consistency=leader with live, or a read parameter removed in 0.6.0 (see the release notes).
404Stream not found or expired.
410Requested offset has been trimmed. Stream-Next-Offset is the earliest offset still readable.
412Stream-Incarnation did not match: the stream was deleted and recreated. The response's Stream-Incarnation is the current token. A read that would answer 404, 410 or 416 without the header still does.
416Requested offset is beyond the stream's tail. Stream-Next-Offset is the tail.
503The group has no known leader, the leader could not confirm its leadership in time (consistency=leader and live reads), or this node holds too many live readers. Retry after Retry-After.

Response headers include Stream-Next-Offset, Stream-Incarnation, ETag, Stream-Up-To-Date, Stream-Closed, and Content-Type; the SSE response and the long-poll 204 carry Stream-Incarnation too. Long-poll responses for an open stream also carry Stream-Cursor.

Streams written with Content-Type: application/json are returned as newline-delimited JSON with response Content-Type: application/x-ndjson, one stored message per line, exactly as written minus insignificant whitespace (JSON message text). On an offset read, max_bytes applies to the encoded byte stream, so a response can end mid-line. Resume from Stream-Next-Offset and buffer any incomplete trailing line before parsing. HEAD reports the configured stream content type, while read responses report the wire representation.

SSE event format

In SSE mode, the server sends:

  • Data events (event: data): stream payload in the data field. The response Stream-Data-Content-Type header identifies the data payload type (application/x-ndjson for JSON streams, the original content type for other streams). SSE data: lines are transport lines, not guaranteed message boundaries. JSON clients should buffer until newline before parsing messages. For binary streams, data is base64-encoded (controlled by the Stream-Sse-Data-Encoding header).
  • Control events (event: control): JSON metadata including the current offset and stream state.
curl 'http://127.0.0.1:4437/demo/hello?offset=-1'
curl 'http://127.0.0.1:4437/demo/hello?offset=00000000000000000042&live=long-poll'
curl 'http://127.0.0.1:4437/demo/hello?offset=-1&live=sse'
curl -N 'http://127.0.0.1:4437/demo/hello?offset=now&live=sse'

See read modes, binary SSE, and offsets for more details.