# Status Stream

> Resume ordered hub, client, ACL, and runtime condition updates from a durable server-sent event cursor.

Source: https://docs.thalovant.com/developers/status-stream/

---
Use `GET /v1/events/conditions` when an authenticated control-plane client needs condition changes between status snapshot refreshes. The stream is an optimization over snapshot reads, not their replacement.

## Connect

```bash
curl --no-buffer --fail-with-body \
  -H "Authorization: Bearer $THALOVANT_TOKEN" \
  -H "Accept: text/event-stream" \
  https://api.thalovant.com/v1/events/conditions
```

The endpoint accepts comma-separated `uids`, `kinds`, `namespaces`, `statuses`, `reasons`, and `types` filters. A caller needs at least one supported hub, client, or ACL read scope.

Each condition event keeps the existing condition fields and adds an ordered stream envelope:

```text
id: 1842
event: condition
data: {"version":1,"sequence":1842,"event_type":"upsert","resource":{"kind":"Hub","uid":"hub-uid","name":"primary","namespace":"tenant-a"},"resource_kind":"Hub","resource_uid":"hub-uid","type":"Ready","status":"True"}
```

| Field | Meaning |
| --- | --- |
| SSE `id` | An ordered event number, encoded as a decimal string. |
| `version` | Public status-event envelope version. The current version is `1`. |
| `sequence` | The same numeric value as the SSE `id`. |
| `event_type` | `upsert` for an observation or `delete` for a durable removal observation. |
| `resource` | Stable kind and UID, plus the observed name and namespace. |
| Existing condition fields | The backward-compatible payload used by earlier clients. |

## Resume Safely

1. **Store the last fully handled numeric sequence.** Persist it only after your handler accepts the event.
2. **Reconnect with the cursor.** Send `Last-Event-ID: 1842`, or use `?last_event_id=1842` when the streaming client cannot set that header.
3. **Process events in increasing sequence order.** Ignore a sequence that is equal to or lower than the last handled value.
4. **Refresh a status snapshot after cursor reset.** Reconnect without the rejected cursor only after starting snapshot recovery.

Replay is ordered and bounded to 1,000 events. The API returns `409` with `detail.code: status_cursor_expired` when recovery would exceed that window. A cursor ahead of the persisted stream returns `409` with `detail.code: invalid_status_cursor`. These failures are explicit so a client does not silently skip status.

  During migration, a non-numeric legacy cursor is accepted as live-only. It cannot provide durable replay. Move to the numeric version-1 sequence as soon as the response includes `X-Thalovant-Status-Stream-Version: 1`.

The official Python, Node, Go, and Rust SDKs do not currently wrap this control-plane SSE endpoint. Use an HTTP streaming client that supports bearer authorization, SSE framing, reconnect cancellation, and bounded backoff.

## Delivery Rules

- An event replay keeps its original sequence number; ignore events you have already handled.
- Heartbeats are SSE comments and do not advance the cursor.
- Reconnect with your last handled cursor to request missed events.
- Periodic snapshot reads remain the recovery path for a rejected cursor, a long offline interval, or a client-side parsing failure.
