Streaming

Subscribe to presence changes instead of polling for them.

ProposedNot yet callable

This documents a design under review. Endpoints, payloads and field names may change before release.

Opening a stream

The stream is Server-Sent Events, so it survives corporate proxies and reconnects on its own without a socket library.

GET /v1/presence/stream?room=block-c-204
Authorization: Bearer sk_live_...
Accept: text/event-stream
const es = new EventSource(
  "https://api.onetaplabs.com/v1/presence/stream?room=block-c-204",
  { headers: { Authorization: "Bearer " + key } },
);

es.addEventListener("presence.entered", (e) => {
  const { student, room } = JSON.parse(e.data);
  console.log(student.external_id + " entered " + room);
});

es.addEventListener("presence.exited", (e) => {
  // Fired after the grace period, not the instant a signal drops.
});

Stream events

EventFires when
presence.enteredA student is first detected in a space.
presence.exitedA student has not been detected for the grace period.
presence.movedA student is detected in a different room without an intervening exit.
heartbeatEvery 30 seconds with no other traffic, so you can tell a quiet room from a dead connection.

Treat a missing heartbeat as a broken connection and reconnect. A silent stream and an empty room look identical otherwise.

The grace period

Radio signals flicker. Without a grace period, a student walking behind a pillar would appear to leave and re-enter every few seconds, and any screen driven by the raw signal would be unreadable.

presence.exited therefore fires only after a student has gone undetected for 5 minutes by default. Institutions can tune this per room — shorter for a turnstile, longer for a lecture hall where people sit still behind others.

Reconnecting

Each message carries a Last-Event-ID. On reconnect the server replays anything missed in the last five minutes, so a brief network drop does not leave your screen permanently out of step.

id: evt_01J8ZC7Q4A
event: presence.entered
data: {"student":{"external_id":"2024CS118"},"room":"block-c-204"}

If you have been disconnected longer than the replay window, take a fresh snapshot before trusting the stream again.