Real time
Sandbox: integrating without watches
Run SOS, fall, heat stress or full evacuation scenarios with simulated watches and receive exactly what would arrive from a real plant.
On this page
The sandbox (https://sandbox.api.safeonuba.com) is a complete environment with simulated watches. It’s for integrating without having watches, without being at the plant and without bothering anyone.
A scenario doesn’t invent alerts: the simulated watches at a sandbox site send their facts and the usual engine decides. What reaches you —webhook, GET, headcount— is the same as would come from a real watch, with one difference: everything carries simulated: true.
Launching a scenario
POST /v1/sandbox/scenarios, with any valid token:
| Field | Required | What it is |
|---|---|---|
scenario | Yes | sos, fall, heat_stress or evacuation. |
site_id | No | The sandbox site. Without it, the first of yours that is a sandbox site. |
curl -X POST https://sandbox.api.safeonuba.com/v1/sandbox/scenarios \
-H "Authorization: Bearer $SAFEONUBA_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "scenario": "evacuation" }'const res = await fetch('https://sandbox.api.safeonuba.com/v1/sandbox/scenarios', {
method: 'POST',
headers: {
Authorization: `Bearer ${await safeOnubaToken()}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ scenario: 'evacuation' }),
});
const run = await res.json(); // { run_id, scenario, site_id, resource, ends_at }res = requests.post(
"https://sandbox.api.safeonuba.com/v1/sandbox/scenarios",
headers={"Authorization": f"Bearer {safeonuba_token()}"},
json={"scenario": "evacuation"},
timeout=10,
)
res.raise_for_status()
run = res.json() # run_id, scenario, site_id, resource, ends_atvar res = await http.PostAsync("https://sandbox.api.safeonuba.com/v1/sandbox/scenarios",
JsonContent.Create(new { scenario = "evacuation" }));
res.EnsureSuccessStatusCode();
var run = await res.Content.ReadFromJsonAsync<JsonElement>(); // run_id, scenario, site_id, resource, ends_atThe response (202) says what it has opened (resource: an alert or an evacuation, with its id) and when it closes by itself (ends_at). Query it with its GET or wait for the webhook.
Alert scenarios
| Scenario | What happens |
|---|---|
sos | A test person presses SOS. |
fall | A test person falls. |
heat_stress | A test person suffers heat stress. |
The alert appears (alert.created). You can acknowledge and close it from your control room with PUT /v1/alerts/{id}; if nobody closes it first, it closes itself after 10 minutes (alert.resolved).
A complete evacuation
evacuation is a general 3-minute evacuation that runs through the whole cycle, designed for testing your control room’s banner from start to finish:
| Moment | What happens | What reaches you |
|---|---|---|
| 0 s | The evacuation starts. | muster.started |
| 15 s | Four people reach point A. | muster.updated |
| 35 s | Someone reaches point B and the control room rules it out. | muster.targets_changed |
| 55 s | A person asks for help. | alert.created of type evacuation_help |
| 95 s | The person who was at B goes to C. | muster.updated |
| 3 min | All clear. | muster.ended |
In between, a muster.updated arrives every time the headcount changes.
With this you can check what is hardest to test at a real plant: that your control room shows a ruled-out point correctly, that the person asking for help moves to the top of “who’s missing”, and that the banner closes when it ends.
Sandbox limits
- At most 5 scenarios open at once per client.
- One evacuation per site at a time.
- Going over either gives
409. - In production,
POST /v1/sandbox/scenariosresponds404: it only exists in the sandbox. - A site that isn’t a sandbox site, or that has a real watch, responds
422and runs nothing.
Telling what is simulated
Everything that comes out of a scenario carries simulated: true: the alerts, and whatever is generated from them. Events from POST /v1/webhooks/{id}/test also carry organization_id: null.
If your control room shares a database or screens with production, filter on simulated so that a test is never mistaken for a real alert.