Skip to main content

Resolve event data with GraphQL

Webhook payloads contain stable identifiers and changing measurements. Use the GraphQL API to resolve those identifiers into the names, hierarchy, floor plans, and sensor associations needed by your application.

  1. Bootstrap reference data from GraphQL before processing events.
  2. Cache buildings, floors, floor spaces, sensors, and their relationships locally by ID.
  3. Process webhooks idempotently and join each event to the cached reference data.
  4. Query GraphQL on a cache miss, then update the cache.
  5. Refresh reference data periodically and use GraphQL to reconcile after an interruption.

Join events against your local cache rather than querying GraphQL once per event. Webhook batches can contain many events for the same entity, so per-event lookups add latency and unnecessary API traffic.

Event typeEvent identifierGraphQL lookupReference data to cache
OccupancyChangesfloorSpaceIdfloorSpace(id:)Space name, capacity, type, floor, and building
FloorSightingsfloorIdfloor(id:)Floor name, building, floor plan URL, and scale
SpaceSensorReadingsspaceSensorIdspaceSensor(id:)Sensor name, type, installations, floors, and floor spaces

Resolve occupancy events

Use floorSpaceId from the occupancy event to identify the affected desk, room, or zone.

Open in API Explorer

Example query

query ResolveOccupancySpace($floorSpaceId: ID!) {
floorSpace(id: $floorSpaceId) {
id
name
capacity
spaceType {
id
name
}
floor {
id
name
building {
id
name
}
}
}
}

Example variables

{
"floorSpaceId": "ac52e43d-7c21-4464-ab21-d0ace07a94b1"
}

Example response

{
"data": {
"floorSpace": {
"id": "ac52e43d-7c21-4464-ab21-d0ace07a94b1",
"name": "Meeting Room 12.04",
"capacity": 8,
"spaceType": { "id": "0f3f9c6a-2f6d-4f0a-9a5b-8f6a1f9f2b31", "name": "Meeting Room" },
"floor": {
"id": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204",
"name": "Level 12",
"building": { "id": "0b26f8f3-5d1c-4c6a-9d3e-1a2b3c4d5e6f", "name": "1 Example Street" }
}
}
}
}

Resolve floor sightings

Use floorId to fetch the floor plan and scale required to display sighting coordinates. Coordinates are measured in centimetres from the top-left of the floor plan.

Open in API Explorer

Example query

query ResolveSightingFloor($floorId: ID!) {
floor(id: $floorId) {
id
name
floorPlanUrl
scale
building {
id
name
}
}
}

Example variables

{
"floorId": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204"
}

Example response

{
"data": {
"floor": {
"id": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204",
"name": "Level 12",
"floorPlanUrl": "https://cdn.xysense.io/floorplans/level-12.png",
"scale": 1.8,
"building": { "id": "0b26f8f3-5d1c-4c6a-9d3e-1a2b3c4d5e6f", "name": "1 Example Street" }
}
}
}

Resolve space sensor readings

Use spaceSensorId to identify the sensor and the active installations and floor spaces it serves. The event's capabilityName identifies the measured property, such as temperature or humidity.

Open in API Explorer

Example query

query ResolveSpaceSensor($spaceSensorId: ID!) {
spaceSensor(id: $spaceSensorId) {
id
name
type {
id
name
}
installations(isActive: true) {
id
name
floor {
id
name
building {
id
name
}
}
floorSpaces {
id
name
}
}
}
}

Example variables

{
"spaceSensorId": "8bb1ba0b-6ea8-4635-86ef-3d57a7de4df3"
}

Example response

{
"data": {
"spaceSensor": {
"id": "8bb1ba0b-6ea8-4635-86ef-3d57a7de4df3",
"name": "SS-12-041",
"type": { "id": "6a1f2b3c-4d5e-6f70-8192-a3b4c5d6e7f8", "name": "Space Sensor Mini" },
"installations": [
{
"id": "4d1c2b3a-5e6f-7081-92a3-b4c5d6e7f809",
"name": "Level 12 North",
"floor": {
"id": "a2961d46-971f-4ce1-a66e-7ee7bdb2a204",
"name": "Level 12",
"building": { "id": "0b26f8f3-5d1c-4c6a-9d3e-1a2b3c4d5e6f", "name": "1 Example Street" }
},
"floorSpaces": [{ "id": "ac52e43d-7c21-4464-ab21-d0ace07a94b1", "name": "Meeting Room 12.04" }]
}
]
}
}
}

Handle reference-data changes

Treat GraphQL reference data as mutable. Spaces can be renamed, sensors can be moved, and installations can become inactive. Keep event records keyed by their XY Sense identifiers and update descriptive fields from GraphQL rather than treating names as identifiers.