Streaming measurements

How to read in real time

The OpenSense API is mostly request/response. For real-time downstream consumers, there are three options, in order of preference.

Configure a webhook integration for the event kinds you care about. We push to your URL within ~1 s of the event. This is the right answer for alarms, ack, clear, device state.

It is not the right answer for "raw measurements". We do not fire a webhook per measurement; the rate would be impractical and the use case rare.

Option B — MQTT subscribe (Team tier)

The MQTT bridge that ingests from customer brokers can also be configured to publish to customer brokers — measurements, events, and notifications mirrored in real time.

Today this is a Team-tier feature; the topic structure is:

opensense/<acc>/<device>/measurement      QoS 1, retained: false
opensense/<acc>/<device>/event             QoS 1, retained: false
opensense/<acc>/<device>/state             QoS 1, retained: true

Authentication is the same mTLS as inbound. Direction is configured per topic family in the dashboard.

Option C — polling

For small-scale integrations, a 60-s poll of the measurements API with agg=raw&limit=10 is fine and explicitly supported. The 120-req/min/account rate budget is generous enough that ~50 channels polling each 60 s is comfortable.

Polling is the right answer for:

  • Home Assistant dashboards.
  • Bespoke Grafana panels (where you have not yet plugged the JSON datasource into our API).
  • A 12-hour cron that grabs yesterday's data for a separate archive.

What we do not offer

  • Server-Sent Events or WebSockets. We considered both; the webhook + MQTT pair covers everything they would address. Adding a third stream is overhead for no new capability.
  • GraphQL subscriptions. We are not a GraphQL API.
  • Long-polling. The 5-second budget on HTTP handlers makes long-polling awkward and we do not want to enlarge it.

Latency budget

Per layer of the pipeline:

Stepp50p99
Edge accept → ingest service2 ms25 ms
Ingest validation + DB write2 ms50 ms
Rule engine evaluation1 ms30 ms
Outbound dispatcher → Telegram200 ms2 s
Outbound dispatcher → Email (Postmark)1 s8 s
Outbound dispatcher → Webhook50 ms500 ms
Outbound dispatcher → MQTT publish5 ms30 ms

End-to-end alarm-to-Telegram p99: ~3 s from the moment the device sends the breach to the moment the message appears in the chat.

Backpressure

If your subscribing system is slow:

  • MQTT subscribe: if your broker's queue grows, we throttle. Our bridge will drop oldest queued messages above 10 000 per topic — you receive a small gap, not unbounded growth.
  • Webhook: we retry with backoff; sustained failure removes the destination from the active set and we email you.
  • Polling: it is your concern; we serve as fast as you ask, up to the rate-limit budget.