Get started
SafeOnuba API
Receive SafeOnuba alerts and evacuations in your control room, your SCADA, your PSIM or your intranet, and acknowledge or close alerts from there.
On this page
The SafeOnuba API takes your plant’s alerts and evacuations to the systems your control room already uses: a SCADA, a PSIM or the intranet. It is meant so that the operator in your control room sees the same as the SafeOnuba dashboard, on their own screen, and can respond from there.
What you can do
- Receive in real time every alert and every change to an evacuation with webhooks: a signed
POSTto your server for each event. - Query alerts, evacuations and their headcount, who is missing, workers, watches, sites, zones and the positions the plant’s privacy level lets you see.
- Acknowledge and close alerts from your control room with
PUT /v1/alerts/{id}. Always on behalf of an operator, who is recorded in the alert’s timeline. - Catch up on what you missed if your receiver goes down:
GET /v1/eventsreturns the events from the last 30 days, byte for byte the same as the ones that were sent. - Integrate without watches in the sandbox, with simulated SOS, fall, heat stress and full evacuation scenarios.
What it doesn’t do
- In v1 it doesn’t start evacuations. The system proposes and a person decides in the SafeOnuba dashboard. Your control room receives the evacuation as soon as it starts and follows it until it ends.
- It doesn’t give vital signs, neither individual nor aggregated. A heat stress alert says what the worker has been told to do, not their heart rate.
- It sees no more than the dashboard. The API sees the same as a dashboard user with those permissions would. Privacy and security explains it.
Environments
| Environment | Address | Status |
|---|---|---|
| Production | https://api.safeonuba.com | Activated when the customer is registered. Not yet open to the public. |
| Test (sandbox) | https://sandbox.api.safeonuba.com | Simulated watches. This is where you integrate. |
Both have the same paths and the same contract. The only things that change when you move to production are the address and the credentials.
Conventions
- All paths are under
/v1, and every event carriesapi_version: "2026-09-24". More in Versioning. - Bodies are JSON, except the token request, which is
application/x-www-form-urlencoded. - Identifiers are UUIDs. Dates are ISO 8601 in UTC.
- Errors arrive as
application/problem+jsonwith the real HTTP status. See Errors. - Lists are paginated with a cursor. See Pagination.
- Two paths are public and need no token:
GET /v1/healthandGET /v1/openapi.json, the contract.
How it fits into your control room
The usual route has three parts:
- A webhook receiver on your network, with a public https URL. It verifies the signature, responds
2xxstraight away and puts the event on a queue. - Your control room system consumes that queue and draws the alert or the evacuation banner. Each alert carries
panel_url, the link to its page in the SafeOnuba dashboard, in case the operator needs the detail. - Occasional API calls when they are needed: the list of who is missing in an evacuation, acknowledging an alert, or
GET /v1/eventsto catch up after an outage.
From the moment an SOS goes off until it reaches your receiver, it normally takes 1 or 2 seconds. That is a typical measurement, not a service commitment.
Using this documentation with AI
If you integrate with an AI assistant, give it the documentation in Markdown rather than the URL: it reads the whole thing, without menus or tabs, and with the links already complete.
- The Copy button, at the top right of each page, copies that page as Markdown.
- Every page has its text version by adding
.mdto the address: /en/developers/webhooks.md. - /en/llms.txt is the index for tools that read it on their own, and /en/llms-full.txt is all the documentation as a single text.
- To generate typed code, the OpenAPI 3.1 contract is the source of truth.
All operations
| Operation | What it does | Scope |
|---|---|---|
POST/v1/oauth/token | Request a token (client_credentials) | No token |
GET/v1/sites | The client’s sites | Any |
GET/v1/sites/{id}/zones | A site’s zones and muster points | alerts:read |
GET/v1/alerts | List alerts | alerts:read |
GET/v1/alerts/{id} | Alert detail | alerts:read |
PUT/v1/alerts/{id} | Acknowledge or resolve an alert | alerts:write |
GET/v1/musters | List evacuations | musters:read |
GET/v1/musters/{id} | Status and headcount of an evacuation | musters:read |
GET/v1/musters/{id}/missing | Who is missing | musters:read |
GET/v1/workers | List workers | workers:read |
GET/v1/workers/{id} | Worker detail | workers:read |
GET/v1/devices | List watches | workers:read |
GET/v1/positions/latest | Latest visible positions | positions:read |
GET/v1/events | Replay events | Any |
GET/v1/webhooks | List destinations | webhooks:manage |
POST/v1/webhooks | Create a destination | webhooks:manage |
DEL/v1/webhooks/{id} | Delete a destination | webhooks:manage |
POST/v1/webhooks/{id}/rotate-secret | Rotate the signing secret | webhooks:manage |
POST/v1/webhooks/{id}/test | Send a test event | webhooks:manage |
POST/v1/sandbox/scenarios | Launch a test scenario | Any |
Next step
Getting started: from access to your first webhook in five minutes.