Create stream

bucketpathstringrequired

Bucket ID. Must match [a-z0-9_-]{4,64}; an invalid ID answers 400.

streampathstringrequired

Stream ID within the bucket: 1 to 122 bytes, without /, \0 or .., not starting with $, and {bucket}/{stream} together at most 122 bytes. streams is reserved. An invalid ID answers 400.

Content-Typeheaderstring

Content type of the initial payload (e.g. application/json). Becomes the stream's content type.

Stream-Closedheaderstring

Set to true to close the stream immediately after creation.

Stream-TTLheaderstring

Sliding time-to-live in seconds. Appends and closes restart the window; reads renew it at most once per quarter of the TTL. See stream lifecycle.

Stream-Expires-Atheaderstring

Absolute expiration timestamp (RFC 3339). Mutually exclusive with Stream-TTL.

Stream-Seqheaderstring

Seeds the stream's stored Stream-Seq: later appends that carry Stream-Seq must be bytewise greater than it. A create never checks it, and a PUT that finds the stream already there ignores it. See how Stream-Seq is checked.

Producer-Idheaderstring

Producer identity for exactly-once writes.

Producer-Epochheaderstring

Producer epoch (must accompany Producer-Id).

Producer-Seqheaderstring

Producer sequence number (must accompany Producer-Id).

Stream-Incarnationheaderstring

Optional precondition: the stream's incarnation token, as a previous response's Stream-Incarnation header returned it. The create applies only if the stream exists as that incarnation (it then answers as a create of an existing stream: 200 or 409); a missing stream answers 412 and is not created. Without the header, the request behaves exactly as described here. A malformed value answers 400. See Stream-Incarnation.

bodybodybinary

Optional initial payload. If provided, becomes the first entry in the stream.

Response

StatusMeaning
201Stream created.
200Stream already exists (idempotent).
400Invalid bucket ID, invalid stream ID (including one that starts with $), invalid headers, or bad JSON payload.
404The bucket was purged; its ID is permanently fenced.
409Stream already exists with a different content type, closed state or lifetime, or Producer-Seq is not 0.
412Stream-Incarnation did not match: the stream is another incarnation (its token is in the response's Stream-Incarnation), or it does not exist. Nothing was created.

Response headers include Location, Content-Type, Stream-Next-Offset, Stream-Incarnation, and lifetime headers (Stream-TTL / Stream-Expires-At) when set. Stream-Closed: true is set if the create request also closed the stream. ETag is set on reads only.

In an application/json stream, a top-level JSON array in the initial payload creates one message per element.

curl -X PUT http://127.0.0.1:4437/demo/hello
curl -X PUT http://127.0.0.1:4437/demo/hello \
  -H 'Content-Type: application/json' \
  --data-binary '{"msg": "first entry"}'
curl -X PUT http://127.0.0.1:4437/demo/ephemeral \
  -H 'Stream-TTL: 3600'

If a stream with the same ID already exists and has identical configuration, the response is 200 OK (idempotent). If the existing stream differs in content type, closed state, TTL or expiry, the response is 409 Conflict. A PUT answered 200 ignores its body and its Stream-Seq.