> ## Documentation index
> Fetch the complete documentation index at: https://developer.rhombus.com/llms.txt
> Use it to discover all available pages before exploring further.

# WebSocket Event Reference

> Every message on the Rhombus event WebSocket's change destination: the envelope, policy alert changes, other entity changes, STOMP headers, change types and delivery guarantees, generated from the AsyncAPI specification.

This page lists the messages a subscriber to `/topic/change/{orgUuid}` receives. It is generated from the event WebSocket's [AsyncAPI specification](https://developer.rhombus.com/rhombus_asyncapi.json); the policy alert fields and their enums come from the same schemas as the [API Reference](https://developer.rhombus.com/api-reference/event-webservice/get-recent-policy-alerts-for-organization). To connect and subscribe, see the [WebSocket overview](https://developer.rhombus.com/websocket/overview) and [WebSocket authentication](https://developer.rhombus.com/websocket/authentication).

## Delivery

- **At most once.** Messages aren't acknowledged, stored or replayed. Anything published while you are disconnected is lost, and a message the service can't process within 30 seconds of publication is dropped. After a reconnect, read what you missed from the REST API; [Build an event pipeline](https://developer.rhombus.com/solutions/event-pipeline) shows how.
- **Filtered by role.** A connection receives only what its credential's role can see. A policy alert is delivered when the role can access the alert's device or location; an alert with neither goes only to full-access roles. A role limited to some locations or devices receives only the entity types the server can check against them. See [What a connection receives](https://developer.rhombus.com/websocket/authentication#what-a-connection-receives).
- **No ordering guarantee.** Order events by their timestamps, not by arrival.
- **Frames.** The body is JSON, although the frame's `content-type` header says `text/plain;charset=UTF-8`. Key order varies, and null fields are left out. UUIDs are strings, including those in the `targetUsers` and `targetRoles` arrays that some messages carry.
- **Not every change is sent.** Many entity types send a short `REFRESH` with no `update`; read the entity from the REST API when you need its state. Seek points and bounding boxes for live video aren't sent on this destination.
- **New values appear without notice**: new entity types, change types, fields and enum values. Ignore what you don't recognize.

## Change types

| `type`    | Meaning                                                 | `update`                                      |
| --------- | ------------------------------------------------------- | --------------------------------------------- |
| `CREATE`  | Something new, such as a policy alert                   | Usually the whole object                      |
| `UPDATE`  | An existing object changed                              | The new state, the changed fields, or nothing |
| `REFRESH` | The object changed; read it again if you need its state | Usually none                                  |
| `DELETE`  | The object was removed                                  | None                                          |

## Messages you receive

### `PolicyAlertChangeEvent`

A new policy alert, or a change to one.

A \`CREATE\` carries the whole alert in \`update\`; it is sent once, when the alert is first stored, so fields that Rhombus fills in later (such as \`finalized\` and clip locations) can still be at their initial values. Read the alert from the REST API when you need its final state. \`UPDATE\` and \`DELETE\` carry only \`entityUuid\`. \`DELETE\` messages are limited to one per organization every 10 minutes, so don't rely on them to track every removed alert. A policy alert is delivered only to a role that can access the alert's device or location; an alert with neither goes only to full-access roles.

```json
{
  "entity": "POLICY_ALERT",
  "type": "CREATE",
  "update": {
    "alertMonitoringVerified": false,
    "clipLocationMap": {},
    "clipLocationMapV2": {},
    "deviceType": "CAMERA",
    "deviceUuid": "ItkwWv1qT7Wy8-pY8KDesw",
    "durationSec": 12,
    "egressBoundaryDevices": [],
    "finalized": false,
    "ingressBoundaryDevices": [],
    "locationUuid": "Rk2pQ7yLT0qX4b1nVt8sJw",
    "notificationSent": false,
    "numHumans": 1,
    "orgUuid": "wEeifGSySTiD228kK7M-Xg",
    "policyAlertTriggers": [
      "MOTION_HUMAN"
    ],
    "policyUuid": "pL0c7YvHQkWm3rN2aB9xCg",
    "ruleUuid": "rU1e9KdLR3uJ5sP0qW2tYg",
    "saved": false,
    "serverReceivedAtMs": 1791367200850,
    "shared": false,
    "textDescription": "Human detected at Front Lobby",
    "timestampMs": 1791367200000,
    "type": "POLICY_ALERT_V2",
    "uuid": "Xq3vT1bKQ2m8c9Zr0aLwYg"
  }
}
```

### `ChangeEvent`

Any other change: device state, sensors, access control, policies, clips and more.

The generic envelope for every entity except \`POLICY_ALERT\`. The shape of \`update\` depends on \`entity\`; many messages carry none, so treat them as a signal to read the entity from the REST API.

```json
{
  "entity": "CAMERA_STATE",
  "entityUuid": "ItkwWv1qT7Wy8-pY8KDesw",
  "type": "UPDATE",
  "update": {
    "connectionStatus": "GREEN",
    "firmwareVersion": "v1.0.1234",
    "healthStatus": "GREEN",
    "locationUuid": "Rk2pQ7yLT0qX4b1nVt8sJw",
    "mediaRegion": "us-west-2",
    "name": "Front Lobby",
    "stateUpdatedTimestampMs": 1791367200000,
    "uuid": "ItkwWv1qT7Wy8-pY8KDesw"
  }
}
```
