Overview
Traffic Mode serves two live channels: entry and exit events, pushed per crossing, and occupancy, at one-minute resolution. This article covers how current each one is, where to read it, and what correction has already been applied to the value you see.
It covers Traffic Mode. Presence-mode measurements appear in the table below so you can tell which applies to your space, but presence mode is documented in How Presence Mode Occupancy Data Is Created and Aggregated
For why traffic-based occupancy drifts and how calibration corrects it, see: Traffic-Based Occupancy Logic and Specifications
1. Which measurement is your space serving?
Butlr runs sensors in two modes, and the mode determines both what the number means and how current it is. Find your measurement below before reading on.
Occupancy from Traffic Mode is accumulated at the door and therefore corrected. Occupancy from Presence Mode is counted directly and needs no correction, which is why the rest of this article applies to the first three rows only.
| Measurement | What the number is | Correction applied | How current | Reporting API | Webhook |
|---|---|---|---|---|---|
traffic |
Individual entries and exits at the door | None | Real time on the webhook | Yes | TRAFFIC |
|
|
Entries minus exits, accumulated across the operating day | Continuous, plus end of day | Live, at one-minute resolution | Yes | None |
traffic_room_occupancy + PIR (room level only)
|
Same as above, at room level | Continuous, plus end of day, plus a mid-day PIR reset | Live, at one-minute resolution; the PIR reset lands after the empty-confirmation window (§4) | Yes | None |
|
|
A direct count of people inside the space, not an accumulation | None | Real time on the webhook | Yes | FLOOR_OCCUPANCY |
2. What "live" means
Traffic Mode has two live channels, and they are current in different ways.
Occupancy is live at one-minute resolution. The newest value you can read is the minute that just ended. There is no batch window, no end-of-day wait, and no additional processing delay between the sensor and the reported number.
Entry and exit events are live per crossing. The TRAFFIC webhook pushes each entry and exit as it happens, with no aggregation window at all. If you need signal faster than one minute, this is the channel to use. The same events are also available historically through the Reporting API using measurement traffic.
Use crossings for flow, not to rebuild occupancy
The webhook carries entries and exits. It does not carry an occupancy number, and summing crossings on your side will not reproduce the occupancy figure the API reports, because correction sits between the raw crossings and the reported count. Read crossings for directional flow, door-level throughput, and per-event triggers. Read occupancy from the Reporting API (§3).
Network conditions
One variable sits outside the API. Sensors report over the site network, so a weak or congested connection can add time before a reading lands on either channel. Where that happens it is a property of the local link rather than of the reporting pipeline.
3. Reading live occupancy from the API
Occupancy is served directly, as a single request. You do not need to accumulate anything on your side (§2).
POST https://api.butlr.io/api/v3/reporting
Content-Type: application/json
Authorization: Bearer <TOKEN>
{
"group_by": { "order": ["time"] },
"window": {
"every": "1m",
"function": "median",
"timezone": "<YOUR_TIMEZONE>"
},
"options": { "format": "json" },
"filter": {
"start": "-10m",
"measurements": ["traffic_floor_occupancy"],
"spaces": { "eq": ["<SPACE_ID>"] },
"calibrated": "true",
"value": { "gte": 0 }
}
}
Read the newest key present. That value is the current occupancy.
Relative time is supported and resolves against the moment you call, so the request above is live as written: no clock arithmetic, no timezone handling, nothing to recompute between polls. Omitting stop runs the window to now.
Use traffic_floor_occupancy for a floor and traffic_room_occupancy for a room. For entry and exit counts, use measurement traffic on either the Reporting API or the TRAFFIC webhook event.
4. What correction has been applied to the value you just read
Traffic-derived occupancy carries correction in two stages. Only the first has run on a live value.
Continuous. Applied to every value, including the one you just read. Occupancy is floored so it can never report negative, and resolved to whole people. This needs no reference point and runs in real time.
At known anchors. An anchor is a moment when the true count is known. The start and end of the operating day are anchors for every space; end-of-day correction works accumulated error back across the day's curve, and cannot run earlier, because the reference point does not exist until the space empties.
PIR Zeroing adds a mid-day anchor for room-level spaces with a PIR sensor, resetting the count to zero when the room empties. Confirming that a room is genuinely empty rather than momentarily still requires a dwell window, set per space and configurable. The recommended default is 300 seconds (5 minutes), so the reset lands that long after the room actually clears. This affects the reset only. The occupancy stream stays at one-minute resolution throughout.
Presence-mode occupancy is measured directly and carries no correction stages at all.
5. Where to see it in the Platform
Live / Today shows IN / OUT and busy level. Estimated occupancy is available on this view behind the Show estimated occupancy toggle, under Options.
Historical (yesterday and earlier) shows IN / OUT trends and occupancy after both correction stages have run.
The toggle controls display only. Live occupancy is served from the API regardless of the Platform setting.
6. "Estimated Occupancy" is a count, not a forecast
It is the actual current count of people in the space. Not a forecast, not a historical average, not a busyness score.
"Estimated" describes the derivation, not the confidence. Traffic sensors count directionally at the entrance, so occupancy is entries minus exits accumulated across the operating day. Because it accumulates, a missed crossing carries forward, which is what calibration corrects. See Traffic-Based Occupancy Logic and Specifications for how far that correction goes and what residual difference to expect.
Key takeaways
- Traffic-derived occupancy is live at one-minute resolution; the newest readable value is the minute that just ended
- Entry and exit events are live per crossing on the
TRAFFICwebhook, with no aggregation window - Occupancy is served directly by the Reporting API; crossings are for flow, not for rebuilding the count
- A live traffic value has continuous correction applied; anchor-based correction lands at the day boundary, and mid-day for PIR spaces
- The PIR empty-confirmation window defaults to 300 seconds and is configurable per space
- "Estimated Occupancy" is an actual count, not a projection
- If your space runs Presence Mode, occupancy is measured directly and pushes in real time over the webhook; see How Presence Mode Occupancy Data Is Created and Aggregated
Comments
Please sign in to leave a comment.