Skip to content

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.

Terminal window
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, each panic button - and, when realtime is available, the connection recipe:

{
"error": false,
"message": null,
"links": {},
"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.

Terminal window
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 vacation), disarmed, or triggered while the alarm has an open incident.

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 five minutes while its socket is up and every 60 seconds while it is down, and lets the socket make everything feel instant. Reconnect with jittered exponential backoff.

  • 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 version field lets clients detect shape changes; treat unknown fields as additive.