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 (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.

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 a custom mode’s id), 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 60 seconds 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.