Bootstrap

Returns the stream's latest snapshot (if any) plus the retained updates after the snapshot offset, packed as a multipart/mixed response. When some of those updates are only in cold storage, or they exceed 8 MiB, the response is an honest partial: it stops early and the client reads the rest with ordinary reads. This is the recommended way to initialize a client that needs the complete current state of a stream.

bucketpathstringrequired

Bucket ID.

streampathstringrequired

Stream ID within the bucket.

Bootstrap does not accept ?live=sse. Combining the multipart body with an SSE event stream is rejected with 400. To go live after bootstrap, finish the multipart response, then open a separate GET /{bucket}/{stream}?offset=<Stream-Next-Offset>&live=sse.

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. Without the header, the request behaves exactly as described here. A malformed value answers 400. See Stream-Incarnation.

Response

StatusMeaning
200Bootstrap response with snapshot and updates.
307In a cluster, this node is not the stream's group leader. Location is the same request on the leader.
400Invalid query parameters (including live=sse).
404Stream not found or expired.
410Requested offset has been trimmed.
412Stream-Incarnation did not match. The response's Stream-Incarnation is the current token.
503The group has no known leader, or the leader could not confirm its leadership in time. Retry after Retry-After.

Bootstrap is served by the group's leader after it confirms with a majority of voters that it still leads, so the response reflects every append and snapshot acknowledged before the request. See Durability and consistency.

Response headers include:

HeaderDescription
Content-Typemultipart/mixed; boundary=...
Stream-Next-OffsetThe offset after the last included update, or the snapshot point when the response has no update parts. Continue reading from here.
Stream-Snapshot-OffsetThe snapshot offset, or -1 if no snapshot exists.
Stream-IncarnationThe incarnation token of the stream that served the response.
Stream-Up-To-Datetrue when the response reaches the stream's tail. Absent on a partial response.
Stream-ClosedPresent and true if the stream is closed and the response reaches its tail.
Cache-Controlno-store.

Complete and partial responses

Let S be the snapshot offset, or the first retained offset when there is no snapshot. Ursula returns one of two forms:

  • Complete. Every retained byte in [S, tail), with Stream-Next-Offset at the tail and Stream-Up-To-Date: true.
  • Partial. The bytes in [S, P) for some P below the tail, with Stream-Next-Offset: P and no Stream-Up-To-Date. When bytes after S have already moved to cold storage, P = S and the response holds only the snapshot part. When the updates exceed 8 MiB, a JSON stream stops at the last message boundary within 8 MiB and always holds at least one message; any other stream answers the snapshot part alone.

Neither form skips bytes. After a partial response, read from Stream-Next-Offset with ordinary catch-up reads until Stream-Up-To-Date: true, and apply those updates before treating the state as current. Bootstrap never reads cold storage itself.

Response body

The body is a multipart/mixed message:

  1. Snapshot part

    The first part is the snapshot blob (or an empty part if no snapshot exists).

  2. Update parts

    Subsequent parts hold the updates starting at the snapshot point, with the stream's content type. For JSON streams, each part is one JSON message. For any other stream, the updates come back as one part that may contain several messages; a part boundary is not a message boundary.

curl 'http://127.0.0.1:4437/demo/hello/bootstrap'

After bootstrapping, catch up from Stream-Next-Offset if the response was partial, then switch to SSE reads with live=sse from the latest Stream-Next-Offset to receive real-time updates.

See bootstrap and snapshots for the conceptual model.