JSON mode
Streams created with Content-Type: application/json operate in JSON mode. JSON mode provides array flattening on append and array wrapping on read.
Creating a JSON stream
curl -X PUT -H "Content-Type: application/json" \
http://localhost:4437/v1/stream/events
Appending
Single value
A single JSON object is stored as one message:
curl -X POST -H "Content-Type: application/json" \
-d '{"event": "click", "x": 100}' \
http://localhost:4437/v1/stream/events
Array flattening
A JSON array is flattened: each element becomes a separate message:
curl -X POST -H "Content-Type: application/json" \
-d '[{"event": "click"}, {"event": "scroll"}]' \
http://localhost:4437/v1/stream/events
This stores two messages. Only the top-level array is flattened; nested arrays within objects are preserved.
Rejected inputs
- Empty arrays (
[]) return400 Bad Request - Invalid JSON returns
400 Bad Request
Reading
All messages are wrapped in a JSON array regardless of how they were appended:
curl http://localhost:4437/v1/stream/events?offset=-1
[
{"event": "click", "x": 100},
{"event": "click"},
{"event": "scroll"}
]
An empty stream returns [].
SSE
SSE data events for JSON streams wrap each message in an array:
event: data
data:[{"event":"click","x":100}]
Consumers must unwrap the outer array:
const parsed = JSON.parse(data);
const items = Array.isArray(parsed) ? parsed : [parsed];
See ecosystem interop CI-003 for details on this pattern.
Non-JSON streams
JSON mode only activates for Content-Type: application/json. Other content types (e.g., text/plain) store and return raw bytes with no flattening or wrapping.