v1 · preview

Try webhook signature, alert.created, location_withheld or 429.

↑ ↓ moveEnter openEsc close

Concepts

Positions

When the API returns a position, what location_withheld means, how privacy zones are represented and how accurate each point is.

On this page

A position is where a person is. It’s the most sensitive data in the API, and that’s why it follows exactly the same rule as the dashboard: if a person in the dashboard with those permissions can’t see it, neither can the API.

When a position is visible

It is decided by each site’s privacy level (privacy_mode in GET /v1/sites):

  • “Emergencies only” (on_demand), the default value. A person’s position is only visible when they have an open alert with severity equal to or above unveil_min_severity, during an evacuation or with a request approved in the dashboard.
  • Continuous (continuous). The plant has chosen to see positions continuously.

Inside a privacy zone (changing rooms, canteens), nobody’s position is recorded, at any level.

In an alert: location_withheld

Every alert carries location and location_withheld:

  • If the privacy level allows the position to be seen, location carries it and location_withheld is false.
  • If the position exists but isn’t delivered —in “emergencies only”, an alert below the severity that lifts the veil—, location_withheld is true. It isn’t visible in the dashboard either.

Your control room has to handle both cases. An alert without a position isn’t an error: it’s the plant protecting its people. For that case, panel_url leads to the alert’s page in the dashboard.

Latest positions

GET /v1/positions/latest (scope positions:read) returns the positions that the privacy level allows to be seen at that moment. In “emergencies only”, anyone with nothing open doesn’t appear.

FieldWhat it is
device_idThe watch.
workerThe person.
locationThe position.
in_vehicleWhether they are in a vehicle.

Every position served with an alert behind it is recorded in that alert, under “Who has seen their position”.

The location object

FieldWhat it is
latitude, longitudeWGS84 coordinates.
uncertainty_mRadius of uncertainty in metres. null if unknown, which isn’t the same as having it perfect.
sourceWhere the point comes from.
maskedtrue if the point is the representative one for a privacy zone and not the person’s own.
position_date_utcWhen it was taken.
heightHeight above the ground by barometer, with its uncertainty, building and floor, when it can be stated. Otherwise, null.
sourceWhat it means
gpsThe watch’s GPS.
networkPosition by network.
zoneThe person was in a privacy zone: the point is the zone’s, not theirs.

Always draw the uncertainty_m radius next to the point: a point without a radius gives a precision it doesn’t have.

Distances without a position

In a critical alert, nearby says who was within 100 metres and at what distance, never where. Anyone who was in a privacy zone doesn’t count. See Alerts.

Don’t track anyone in a loop

Querying GET /v1/positions/latest every few seconds gives you nothing more than the alerts: in “emergencies only” only people who already have an open alert appear, and that alert already reaches you by webhook with the position inside. On top of that, every query counts towards your rate limits.