Conceptos
Alertas
Tipos, gravedad y estados de una alerta; la diferencia entre que la sala se haga cargo y que el trabajador vea el aviso; y cómo reconocerla o cerrarla.
En esta página
Una alerta es algo que ha pasado en la planta y que alguien tiene que atender: un SOS, una caída, una entrada donde no se debe, un reloj sin batería o un aviso de terremoto. Es el objeto central de la API.
El objeto
La alerta llega completa en cada webhook (data.alert) y es lo que devuelve GET /v1/alerts/{id}. Los campos que más se usan:
| Campo | Qué es |
|---|---|
type, severity, status | Qué ha pasado, cómo de grave es y en qué punto de la respuesta está. |
title | El título que lee la sala. |
site, zone | Dónde. zone puede ser null. |
worker, device | A quién le ha pasado y con qué reloj. null en las alertas de toda la planta. |
location, location_withheld | Dónde está la persona, si la privacidad de la planta deja verlo. |
details | Datos propios de cada tipo. |
acknowledged, resolved, assigned_to | Quién se ha hecho cargo, quién la ha cerrado y a quién está asignada. |
date_created, date_last_modified | Cuándo se creó y cuándo cambió por última vez. |
simulated | true si viene de un simulacro o de relojes simulados. |
panel_url | Enlace a su ficha en el panel de SafeOnuba. |
La lista entera, campo a campo, está en el esquema Alert.
Tipos
| type | Qué significa |
|---|---|
sos | La persona ha pedido ayuda desde el reloj, o la sala lo ha lanzado por ella. |
fall_detected | El reloj ha detectado una caída. |
restricted_zone_entry | Entrada en una zona restringida. |
forbidden_zone_entry | Entrada en una zona prohibida. |
permit_expired_inside | El permiso de trabajo ha caducado con la persona todavía dentro de la zona. |
permit_closed_inside | El permiso de trabajo se ha cerrado con la persona todavía dentro de la zona. |
heat_stress | Estrés térmico: el reloj le ha indicado que pare y descanse. |
evacuation_help | Durante una evacuación, la persona dice desde el reloj que no puede salir por su pie o que está ayudando a otra. |
worker_call_request | La persona avisa a la sala desde el reloj. Sin cobertura, el reloj graba un aviso de voz que se escucha en el panel. |
device_offline | El reloj lleva un tiempo sin comunicar. |
low_battery | Al reloj le queda poca batería. |
earthquake | Terremoto. Es de toda la planta: no lleva worker ni device. |
tsunami_risk | Riesgo de tsunami. Es de toda la planta: no lleva worker ni device. |
Un vehículo cerca no es una alerta
Los avisos de vehículo cerca no generan alertas propias. Van dentro de la alerta de un incidente, en dos listas:
nearby: quién había a menos de 100 metros cuando saltó una alerta crítica (SOS o caída), personas o vehículos. Da la distancia, nunca la posición, y no cuenta a quien estaba en una zona de privacidad.vehicle_warnings: los avisos de vehículo cerca que recibió esa persona en la ventana del incidente, con la distancia y si los vio en el reloj.
Detalles de cada tipo
details cambia según type. Por ejemplo, SosDetails dice cómo se pidió el SOS (trigger), ZoneDetails trae el permiso de trabajo que regía (permit_reference) y HazardDetails la magnitud, la distancia y si el aviso es oficial. Las variantes están en AlertDetails.
Gravedad
| severity | Qué significa |
|---|---|
low | Información. |
medium | Aviso. |
high | Grave. |
critical | Crítica: SOS, caída, «no puedo evacuar». |
El filtro severity de GET /v1/alerts y el min_severity de los webhooks son mínimos: high devuelve high y critical.
Estados
| status | Qué significa |
|---|---|
unacknowledged | Nadie se ha hecho cargo todavía. |
acknowledged | Un operador se ha hecho cargo. |
resolved | Cerrada. |
- Reconocer asigna la alerta a quien la reconoce si nadie la llevaba. Reconocer no es cerrar: una alerta reconocida sigue marcando a la persona en el mapa hasta que se cierra.
- Cerrar deja constancia de quién, cuándo y con qué nota, en
resolved. - Una alerta cerrada puede reabrirse. Se avisa con el evento
alert.reopened.
Reconocer y cerrar desde tu sala
PUT /v1/alerts/{id} con el scope alerts:write. El cuerpo:
| Campo | Obligatorio | Qué es |
|---|---|---|
status | Sí | acknowledged o resolved. |
actor | Sí | El operador de tu sala: name y, si quieres, external_id. |
resolution_reason | No | Al cerrar, por qué. Hasta 200 caracteres. |
note | No | Una nota. Hasta 500 caracteres. |
El operador es obligatorio porque «reconocida» mide la respuesta de una persona. En la cronología de la alerta queda «Cliente · Operador (vía integración)».
curl -X PUT https://sandbox.api.safeonuba.com/v1/alerts/0f6c2b7e-3a1d-4c55-9b0e-7d2f4a8c1e90 \
-H "Authorization: Bearer $SAFEONUBA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "resolved",
"resolution_reason": "Falsa alarma",
"note": "Confirmado por radio con el encargado.",
"actor": { "name": "E. Ejemplo", "external_id": "OP-117" }
}'const res = await fetch(`https://sandbox.api.safeonuba.com/v1/alerts/${alertaId}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${await tokenSafeOnuba()}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
status: 'resolved',
resolution_reason: 'Falsa alarma',
note: 'Confirmado por radio con el encargado.',
actor: { name: operador.nombre, external_id: operador.id },
}),
});
if (res.status === 409) {
// Ya estaba cerrada, o la transición no es posible: nada que hacer.
} else if (!res.ok) {
throw new Error(`${res.status}: ${await res.text()}`);
}res = requests.put(
f"https://sandbox.api.safeonuba.com/v1/alerts/{alerta_id}",
headers={"Authorization": f"Bearer {token_safeonuba()}"},
json={
"status": "resolved",
"resolution_reason": "Falsa alarma",
"note": "Confirmado por radio con el encargado.",
"actor": {"name": operador.nombre, "external_id": operador.id},
},
timeout=10,
)
if res.status_code != 409: # 409: ya estaba cerrada
res.raise_for_status()var cuerpo = JsonContent.Create(new
{
status = "resolved",
resolution_reason = "Falsa alarma",
note = "Confirmado por radio con el encargado.",
actor = new { name = operador.Nombre, external_id = operador.Id },
});
var res = await http.PutAsync($"https://sandbox.api.safeonuba.com/v1/alerts/{alertaId}", cuerpo);
if (res.StatusCode != System.Net.HttpStatusCode.Conflict) res.EnsureSuccessStatusCode();La respuesta es la alerta ya actualizada. Si la transición no es posible —por ejemplo, cerrar o reconocer una alerta ya cerrada— la API responde 409.
Consultar alertas
GET /v1/alerts devuelve las alertas de la más reciente a la más antigua, paginadas. Filtros:
| Parámetro | Qué filtra |
|---|---|
site_id | Un centro. |
type | Un tipo. |
status | Un estado. |
severity | Gravedad mínima. |
since, until | Intervalo de fechas, en ISO 8601. |
limit, cursor | Paginación (ver Paginación). |
Para seguir las alertas en tiempo real no consultes en bucle: usa webhooks. La lista sirve para cargar el estado al arrancar y para buscar.
Nombres de los trabajadores
Los nombres son opcionales por contrato. Si tu contrato no los incluye, worker.name no aparece y title se compone con el tipo, la zona y el identificador de empresa (external_id), sin nombre. Ver Trabajadores y relojes.