Realtime & Inventory
The alarm endpoints are send-only. Alongside them sits a small read-only integration surface - the same one the official Home Assistant integration is built on. It answers three questions: what can this key reach, what state is it in right now, and how do I hear about changes without polling?
Everything here is fenced to the API key: a key scoped to one alarm describes one alarm, and nothing on this surface can change configuration or reach your account.
Describe: What Can This Key Reach?
Section titled “Describe: What Can This Key Reach?”curl "https://api.openalarm.io/v1/integration/describe" \ -H "X-API-Key: oa_m9s346q3d25vt4f5v37e3s3e28jt97kb6cq643dzvmxxqkfbf5kznwj47tan9zt2"Returns 200 with the standard envelope. data carries a version, your key’s visible
inventory grouped by location - each alarm with its modes (custom ones included), each panic
button - and, when realtime is available, the connection recipe:
{ "error": false, "message": null, "traceId": "8f14e45f-ea0d-4a1b-9f2c-6b3d70c5e881", "data": { "version": "1.0.0", "locations": [ { "id": "2c9wvhrq52k5refhtvmmr0f8yjz5j9e9", "name": "Home", "alarms": [ { "id": "k7m3x9q2f8d4w1b5n6p0r3t7v2x5z9c4", "name": "Front Door", "modes": [ { "id": "away", "name": "Away" }, { "id": "home", "name": "Home" }, { "id": "night", "name": "Night" } ] } ], "panicButtons": [ { "id": "71hfe865v215de1ctewh0avnh9dn65r6", "name": "Bedside" } ] } ], "realtime": { "httpHost": "…", "realtimeHost": "…", "channel": "/account/…" } }}Names and modes are the display truth - build pickers and dashboards from them rather than
hardcoding IDs. Responses are cacheable for an hour (Cache-Control says so); inventory changes
rarely, so re-describe on a schedule or on reload, not per call.
State: What Is It Right Now?
Section titled “State: What Is It Right Now?”curl "https://api.openalarm.io/v1/integration/state" \ -H "X-API-Key: oa_m9s346q3d25vt4f5v37e3s3e28jt97kb6cq643dzvmxxqkfbf5kznwj47tan9zt2"Returns 200; data.alarms lists each visible alarm’s current state:
{ "data": { "version": "1.0.0", "alarms": [ { "id": "k7m3x9q2f8d4w1b5n6p0r3t7v2x5z9c4", "state": "away" } ] }}state is the armed mode’s id (home, away, night, or a custom mode’s id), disarmed, or
triggered while the alarm has an open incident.
Realtime: Hear About Changes
Section titled “Realtime: Hear About Changes”The realtime block in the describe response is a connection recipe for a subscribe-only
event channel (AWS AppSync Events over WebSocket). Authorize the connection with the same API
key; the key can subscribe to its own account’s channel and nothing else, and can never publish.
Events carry no state - they are a nudge. When a frame arrives, call /integration/state
(or re-describe) and update from the response. This push-to-invalidate model means a missed frame
never leaves you wrong, just briefly stale, and one refresh on every (re)subscribe covers any gap.
Keep a modest poll as fallback - the official integration polls state every 60 seconds and lets the socket make everything feel instant. Reconnect with jittered exponential backoff.
Ground Rules
Section titled “Ground Rules”- Read-only, always. Arm, disarm, trigger, and clear stay on the alarm endpoints.
- These endpoints return
200, not the alarm endpoints’202- nothing here is enqueued. - The
versionfield lets clients detect shape changes; treat unknown fields as additive.