# Streaming

> A live feed of one room or one person, for dashboards, alerts and agents that need to react in seconds.

## One stream per room

Open `GET /v1/rooms/{room}/stream` to receive snapshots of the room, with results and events in between as they happen. People appear and leave inside the snapshot, so you never open or close streams as the room changes. To follow one person across rooms, use [/v1/people/{person}/stream](https://docs.cymatics.tech/api/stream-person).

## Format

Streams use Server-Sent Events over an authenticated request. Each message has an `id`, an `event` kind and one `data` line with the same `{ data, meta }` envelope as every JSON response. Kinds include `snapshot`, `result`, `event`, `correction`, `gap`, `analysis` and `heartbeat`; a heartbeat is not a measurement.

`text/event-stream`

```
id: 3f9c2a7d1b6e4c08.41.snapshot_0
event: snapshot
data: {"data":{"object":"room.snapshot","room_id":"room_bedroom","occupied":true,"person_count":1,"people":[…]},"meta":{"request_id":"req_01","livemode":false,"output_rate_hz":1,…}}

id: 3f9c2a7d1b6e4c08.42.event
event: event
data: {"data":{"object":"event","id":"evt_01","type":"bed.exited","room_id":"room_bedroom","track_id":"trk_001",…},"meta":{…}}
```

Browsers' built-in `EventSource` can't send an `Authorization` header, and keys belong on your server anyway. Stream from your backend with the SDK, the CLI or any HTTP client.

`terminal`

```sh
curl -N "https://api.cymatics.tech/v1/rooms/room_bedroom/stream?rate_hz=1" \
  -H "Authorization: Bearer $CYMO_API_KEY" \
  -H "Accept: text/event-stream"
```

`agent.ts`

```ts
for await (const message of cymo.rooms.stream({ room_id: "room_bedroom" })) {
  console.log(message.kind, message.data);
}
```

## Rate, signals and view

`rate_hz` asks for a maximum output rate, and `meta.output_rate_hz` tells you the rate you actually got. `signals` limits messages to the signals you use, such as `heart_rate_bpm,bed_state`. `view` is `fused` for one deduplicated view of the room, or `device` for each Cymo's own tracks. Never add the two views together to count people.

## Reconnecting

If the connection drops, reconnect with the last `id` you received in the `Last-Event-ID` header. Events and corrections you missed are replayed within a bounded window, possibly with duplicates, so update your state by event ID and `revision`. The SDK resumes for you.

`terminal`

```sh
curl -N "https://api.cymatics.tech/v1/rooms/room_bedroom/stream" \
  -H "Authorization: Bearer $CYMO_API_KEY" \
  -H "Last-Event-ID: 3f9c2a7d1b6e4c08.42.event"
```

If the cursor is too old, the stream answers `410 replay_expired`. Read a fresh snapshot, then fill the gap from history with [/v1/events](https://docs.cymatics.tech/api/list-events) and [/v1/results](https://docs.cymatics.tech/api/list-results).
