Occupancy polling
Use occupancy polling when you need pull-based updates, replay windows, or downstream reconciliation.
Requires the Occupancy API feature
The Occupancy API feature is enabled by XY Sense per organisation and can vary per building and floor. If your queries return an access-disabled error, your XY Sense representative can enable it. See Feature enablement.
1. List the spaces you care about
Open in API ExplorerExample query
query OccupancyFloorSpaces($floorId: ID!) {
floorSpaces(floorId: $floorId) {
id
name
capacity
floor {
id
name
}
spaceType {
id
name
}
}
}
Example variables
{
"floorId": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204"
}
Example response
{
"data": {
"floorSpaces": [
{
"id": "5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"name": "Desk NE-101",
"capacity": 1,
"floor": {
"id": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204",
"name": "Level 12"
},
"spaceType": {
"id": "7d2e4f60-8a91-4c23-b5d6-0e1f2a3b4c56",
"name": "Desk"
}
}
]
}
}
2. Read the current state of those spaces
Open in API ExplorerExample query
query LatestOccupancy($floorId: ID!) {
floorSpaces(floorId: $floorId) {
id
name
latestOccupancy {
floorSpaceId
headcount
occupancyStatus
previousOccupancyStatus
collectedDate
occupancyStatusChangeDate
}
}
}
Example variables
{
"floorId": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204"
}
Example response
{
"data": {
"floorSpaces": [
{
"id": "5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"name": "Desk NE-101",
"latestOccupancy": {
"floorSpaceId": "5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"headcount": 1,
"occupancyStatus": "CurrentlyOccupied",
"previousOccupancyStatus": "RecentlyOccupied",
"collectedDate": "2026-06-02T04:17:39.1066221Z",
"occupancyStatusChangeDate": "2026-06-02T04:17:39.1066221Z"
}
}
]
}
}
3. Poll for changes with a moving cursor
Each response carries a nextFrom. Persist it and send it as the next request's from: that is the cursor, and it is what stops you re-reading or skipping changes. Request windows and retention are in Limits and retention.
Example query
query OccupancyChanges($floorIds: [ID!], $from: Date!, $to: Date!) {
occupancyChanges(floorIds: $floorIds, from: $from, to: $to, includeLatest: false, includeHeadcountChanges: true) {
from
to
nextFrom
data {
floorSpaceId
headcount
occupancyStatus
previousOccupancyStatus
collectedDate
occupancyStatusChangeDate
}
}
}
Example variables
{
"floorIds": [
"a2961d46-971f-4ce1-a66e-7ee7bdb2a204"
],
"from": "2026-06-02T04:00:00Z",
"to": "2026-06-02T05:00:00Z"
}
Example response
{
"data": {
"occupancyChanges": {
"from": "2026-06-02T04:00:00Z",
"to": "2026-06-02T05:00:00Z",
"nextFrom": "2026-06-02T04:17:39.1066221Z",
"data": [
{
"floorSpaceId": "5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"headcount": 0,
"occupancyStatus": "NotOccupied",
"previousOccupancyStatus": "RecentlyOccupied",
"collectedDate": "2026-06-02T04:17:39.1066221Z",
"occupancyStatusChangeDate": "2026-06-02T04:17:39.1066221Z"
}
]
}
}
}
Narrowing the poll to specific spaces
Use explicit floor-space filters when you only care about a subset of desks, rooms, or zones.
Open in API ExplorerExample query
query FilteredOccupancyChanges($floorSpaceIds: [ID!], $from: Date!, $to: Date!) {
occupancyChanges(floorSpaceIds: $floorSpaceIds, from: $from, to: $to, includeLatest: false, includeHeadcountChanges: true) {
nextFrom
data {
floorSpaceId
headcount
occupancyStatus
collectedDate
}
}
}
Example variables
{
"floorSpaceIds": [
"5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"6e0b4c85-1f27-4d93-a8b5-3c7d9e0f1a24"
],
"from": "2026-06-02T04:00:00Z",
"to": "2026-06-02T05:00:00Z"
}
Example response
{
"data": {
"occupancyChanges": {
"nextFrom": "2026-06-02T04:52:10.5411902Z",
"data": [
{
"floorSpaceId": "5c8a1d92-4b6e-4f03-9a71-2d4e6f8a0b13",
"headcount": 1,
"occupancyStatus": "CurrentlyOccupied",
"collectedDate": "2026-06-02T04:52:10.5411902Z"
},
{
"floorSpaceId": "6e0b4c85-1f27-4d93-a8b5-3c7d9e0f1a24",
"headcount": 4,
"occupancyStatus": "CurrentlyOccupied",
"collectedDate": "2026-06-02T04:49:58.1178410Z"
}
]
}
}
}