How it works
Privacy and security
The API sees the same as a dashboard user with those permissions. Positions only when the plant allows it, never vital signs, and every request is logged.
On this page
This page is for the technical team doing the integration, and also for the works council, the workers’ representatives or the data protection officer who needs to know what leaves the plant and where it goes. Everything said here is enforced by design in the API itself; it doesn’t depend on the integrator behaving well.
The API sees the same as the dashboard, no more and no less
An integration is not a back door. The API sees exactly what a SafeOnuba dashboard user with those same permissions would see:
- the same plant privacy level;
- the same privacy zones;
- the same contractor scope: what that identity can’t see doesn’t exist as far as the API is concerned (it responds
404).
And scopes limit it further: a token without positions:read sees no positions, even if the plant allowed them to be seen.
Positions: only when the plant allows it
Each plant chooses its privacy level. The default is “emergencies only”: a person’s position can only be seen when they have an open alert above a certain severity, during an evacuation, or with a request approved in the dashboard.
When the position exists but privacy doesn’t let you see it, the alert still arrives, without the position and with location_withheld: true. It isn’t visible in the dashboard either.
Every position the API delivers with an alert behind it is recorded on that alert, under “Who has seen their position”.
Technical detail: Positions.
Privacy zones
In privacy zones —changing rooms, canteens— the position is not recorded. The API gives the name and type of those zones, but not their polygon. And anyone who was in one of them isn’t counted in nearby, the list of who was close to an incident.
There are never any vital signs
The API doesn’t deliver vital signs, neither a person’s nor aggregated. No field carries heart rate, body temperature or anything derived from them.
A heat stress alert says what the worker has been told on their watch (stop and rest), the plant’s heat index and the minutes in the sun. Nothing that comes from their body.
Optional names
Workers’ names are optional by contract. Without them, each person is identified only by the code their company already uses (external_id), and alert titles are composed without a name.
Who has access, and why, in plain view
- We register each API client ourselves, with a reason that is recorded.
- Every request is logged.
- The plant sees it in its dashboard, under Settings → Integrations: who has access, to what and for what reason.
- Actions from the customer’s control room carry a name. Acknowledging or closing an alert through the API requires the operator doing it, and the alert’s timeline shows it as “Customer · Operator (via integration)”.
What the API doesn’t do
- It doesn’t start evacuations. The system can propose them; a person always decides in the dashboard.
- It can’t be used from a browser. It has no CORS: calls go out from the customer’s server, which is where the credentials live.
Transport and credential security
- All traffic is encrypted with TLS, webhooks included: a destination can only be an
httpsURL at a public address, and redirects are not followed. - Tokens last one hour and are revoked instantly if the client is deregistered.
- Secrets are shown only once, both the
client_secretand each webhook’s signing secret, and both can be rotated without downtime. - Every webhook is signed with HMAC-SHA256 and a timestamp, and the receiver rejects anything that doesn’t match or is more than 5 minutes old (see Verifying a webhook signature).
Questions a committee usually asks
Can the company track a worker through the API? Only if the plant has chosen a privacy level in the dashboard that allows it, and with the same limits. With “emergencies only”, which is the default, the API doesn’t see the position of anyone who doesn’t have an open emergency.
Can the integration tell how someone’s health is? No. There are no vital signs in the API, neither individual nor aggregated.
How do we know who is connected? In the dashboard, Settings → Integrations: who, to what and for what reason. And every request is logged.
What if the integration acknowledges or closes an alert? It goes in the alert’s timeline with the name of the operator who did it and the “via integration” mark.