Skip to content

Endpoint /api/v1/* — mappa concettuale

Per la firma esatta (path, body, response, status code) di ogni operazione consulta lo Schema OpenAPI. Questa pagina elenca raggruppamenti, scope, regole semantiche e flussi multi-step non rappresentabili in OpenAPI.

Convenzioni:

  • Tutti i path sotto https://<instance>/api/v1/.
  • Authorization: Bearer <token> su ogni chiamata.
  • uid = IMEI del device (stringa, 15 cifre). id = UUID LifeDome.
  • Default-deny: lo schema OpenAPI elenca l'intera superficie partner. Qualunque altro endpoint risponde 403 scope_not_available.

Utenti

Path base: /api/v1/auth/users/. Gestione anagrafica utenti scoped alla org del partner.

MetodoPathScope
GET/users:read
POST/users:write
GET/{id}/users:read
PATCH/{id}/users:write
DELETE/{id}/users:write
POST/{id}/invite/users:invite

Regole semantiche:

  • POST è idempotente su email. Email già esistente in altra org → membership allegata all'utente esistente, response include merged: true. Per prevenire leak cross-tenant, i campi first_name/last_name/phone_number in risposta riflettono il body della richiesta, non il profilo stored.
  • Utenti creati con password inutilizzabile (portal_active: false). Per accesso portale → POST /{id}/invite/ (vedi Invito portale).
  • PATCH ha allow-list stretta: first_name, last_name, phone_number, role (solo VIEWER/USER — promozione a ADMIN/OWNER → 400). Non scrivibili: email, password, is_active. Per disattivare → DELETE + ri-POST per riattivare.
  • DELETE = soft-close della membership nella org del partner. L'utente globale non viene eliminato.
  • POST /{id}/invite/ rate-limited a 1/ora per utente. Risposte: 202 (in coda), 200 { already_active: true }, 404 (non in org).

Dispositivi

Path base: /api/v1/devices/. Registry dei device fisici (IMEI-keyed).

MetodoPathScope
GET/devices:read
POST/devices:write
GET/{uid}/devices:read
PATCH/{uid}/devices:write
DELETE/{uid}/devices:write
GET/{uid}/capabilities/catalog:read

Regole semantiche:

  • POST con IMEI già presente nella stessa org = upsert (200). IMEI registrato in altra org → 409 imei_conflict.
  • La risposta partner per un device non include la lista assignments né PII degli utenti assegnati (vedi Assegnazioni).
  • DELETE = soft-delete (imposta deleted_at). Il device esce dagli endpoint partner dopo la cancellazione.
  • capabilities/ ritorna le capability risolte per il device (config catalog + override per-istanza).

Shape last_status (per-metric freshness)

last_status (su lista/dettaglio device) espone uno snapshot per-metric. Ogni chiave allow-listed mappa a un oggetto { value, ts } dove ts è il timestamp server-side del pacchetto che ha riportato quella metrica per ultimo. Metriche diverse possono avere ts diversi perché il device le invia in pacchetti distinti.

json
"last_status": {
  "hr":   { "value": 72,   "ts": "2026-04-17T08:22:11Z" },
  "sbp":  { "value": 122,  "ts": "2026-04-17T08:18:02Z" },
  "dbp":  { "value": 80,   "ts": "2026-04-17T08:18:02Z" },
  "spo2": { "value": 97,   "ts": "2026-04-17T08:18:02Z" },
  "bat":  { "value": 83,   "ts": "2026-04-17T08:22:11Z" }
}

Allow-list delle chiavi wire (chiavi fuori lista vengono droppate server-side):

ChiaveUnitàDescrizione
batint (0-100)Batteria %
hrintFrequenza cardiaca (bpm)
sbp / dbpintPressione sistolica / diastolica (mmHg)
spo2intSaturazione ossigeno (%)
tempfloatTemperatura corporea (°C)
glucosefloatGlicemia (mg/dL)
stepsintContapassi
gsm_signalintSegnale GSM (0-31)
satellitesintSatelliti GPS agganciati

Timestamp semantica: ts è il momento server-side di ingestione del pacchetto. ts: null indica una entry legacy precedente all'introduzione di questo shape; si auto-corregge al pacchetto successivo del device.


Assegnazioni

Path base: /api/v1/devices/{uid}/ (scritture) + /api/v1/assignments/ (lettura). Relazione utente↔device.

Ruoli

RuoloValoreItalianoSemantica
OWNER30ProprietarioHolder principale. Creato dal partner al provisioning. Controllo completo.
ASSIGNED20AssegnatoCo-holder. Controllo operativo, no delete né trasferimento.
VIEWER10VisualizzatoreRead-only. Creato tipicamente via flow share (invito).

Endpoint

MetodoPathScopeNote
GET/api/v1/assignments/assignments:readLista assignment attivi
GET/api/v1/assignments/{id}/assignments:readDettaglio
POST/api/v1/devices/{uid}/assign/assignments:writerole: owner/assigned
POST/api/v1/devices/{uid}/unassign/assignments:writeSoft-close (is_active=false)
POST/api/v1/devices/{uid}/share/assignments:shareCrea VIEWER via invito email
DELETE/api/v1/devices/{uid}/share/{user_id}/assignments:shareRevoca share VIEWER
POST/api/v1/organizations/invitations/server-accept/invitations:writeServer-side accept di token share

Regole semantiche

  • assign accetta solo owner/assigned. Per VIEWER usare share/.
  • Errori assign: utente non in org → 400 User not found in this organization.; già assegnato attivo → 400 User already has an active assignment for this device..
  • share/ ha due rami:
    • Email già nella org → crea direttamente assignment VIEWER, nessuna email inviata.
    • Email sconosciuta → crea invito (scadenza 7 giorni, device target in metadata privato) e accoda email.
    • link_base opzionale, HTTPS, host nella allow-list configurata sul partner.
  • server-accept/ è il path partner-side (separato dal /accept/ umano unauthenticated). Il campo password è vietato (400 password_not_allowed_in_partner_flow); utente creato con password inutilizzabile.

Trasferimento ownership

Non c'è endpoint dedicato. Sequenza due chiamate, non atomica:

  1. POST /api/v1/devices/{uid}/unassign/ con { "user_id": "<vecchio_owner>" }
  2. POST /api/v1/devices/{uid}/assign/ con { "user_id": "<nuovo_owner>", "role": "owner" }

Proprietà:

  • Dati storici (locations, telemetry, events, geofences, commands) conservati — sono org-scoped, non owner-scoped.
  • Storico assignment conservato (soft-close + nuova riga).
  • Se step 2 fallisce, device resta unassigned. Il caller deve fare rollback ri-assegnando il vecchio owner.

Posizioni

Path base: /api/v1/devices/{uid}/locations/. Scope: locations:read.

MetodoPathDescrizione
GET/latest/Ultima posizione nota
GET/Storico, cursor pagination
GET/segments/Segmenti viaggio (sosta/movimento) in finestra temporale

Note:

  • source è enum (gps, lbs, wifi, ...). carrier è stringa (nome MCC/MNC risolto) o null. address è reverse-geocoding opzionale.
  • Storico filtrabile per ts_after, ts_before, source, ordering (ts/-ts).
  • segments/ default window = ultime 6 ore. Tipi segmento: moving | stopped.

Telemetria

Path base: /api/v1/devices/{uid}/telemetry/. Scope: telemetry:read.

MetodoPathDescrizione
GET/latest/Merge ultime 50 righe per chiave metrica
GET/Storico, cursor pagination

Note:

  • /latest/ ritorna { data: { <metric>: { value, ts }, … } }. Il merge usa le ultime 50 righe Telemetry, newest-wins per chiave; ogni entry porta il ts della riga Telemetry sorgente. Nessun ts top-level: la freshness è per-metric.
  • Chiavi data identiche a last_status (vedi Dispositivi). Valori null sono omessi; valori 0 (es. bat: 0 dispositivo morente, steps: 0 paziente fermo) passano: la validità è valutata in fase di ingestione del pacchetto, non in fase di serializzazione della response.
  • Storico / ritorna righe raw { id, ts, device_ts, received_at, data }. ts è server-side (canonico), device_ts è l'orologio del device dal payload (audit-only, può essere null o sballato), received_at è il timestamp di INSERT su DB (interno). data è il dizionario chiave→valore così come ingestito, senza ulteriori filtri sui valori.
  • Storico filtrabile per cursor, ts_after, ts_before, metric (es. ?metric=hr).
  • 404 se nessun dato disponibile.

Eventi / Allarmi

Path base: /api/v1/events/. Scope: events:read, events:acknowledge.

MetodoPathScope
GET/events:read
GET/{id}/events:read
POST/{id}/acknowledge/events:acknowledge

Note:

  • Cursor pagination. Filtri: device_uid, event_type, severity, acknowledged, ts_after, ts_before, fence_id, ordering.
  • event_type e severity sono enum integer serializzati come label lowercase (info, warning, critical, geofence_exit, ...).
  • Detail include il campo notes (assente in lista).
  • Su acknowledge da token partner, acknowledged_by è null (no attribuzione umana); notes opzionale.

Comandi

Path base: /api/v1/devices/{uid}/commands/.

MetodoPathScope
GET/commands:read
POST/commands:write
GET/{command_uuid}/commands:read
DELETE/{command_uuid}/commands:write

Regole semantiche:

  • Cursor pagination. Filtri: status, command_type, created_after, created_before.
  • command_type dipende dalle capability del device — consulta GET /api/v1/devices/{uid}/capabilities/ per la lista supportata. Tipici: locate_now, send_message, set_working_mode, set_timezone, restart, power_off, test_heart_rate, test_blood_pressure, test_temperature, test_blood_oxygen, calibrate_bp, factory_reset.
  • Idempotency-Key raccomandato sulle POST.
  • Lifecycle status pubblico: pendingsendingsentack_ok | ack_error | timeout. sending = preso in carico, in scrittura sul trasporto del dispositivo.
  • 429 se la coda comandi del device è piena.

Messaging

Path base: /api/v1/devices/{uid}/messages/. Opt-in per partner (capability gating).

MetodoPathScope
GET/messaging:read
GET/{id}/messaging:read
DELETE/{id}/messaging:write
POST/send-text/messaging:write
POST/send-tts/messaging:write
POST/upload-voice/messaging:write (multipart/form-data)
POST/bulk-delete/messaging:write

Note:

  • Enum values come label lowercase: direction (inbound/outbound), message_type (text/voice), device_delivery_status (pending/processing/ready/sending/delivered/failed).
  • TTS non è un message_type — è un'azione (POST /send-tts/) che crea un messaggio voice (audio sintetizzato server-side).
  • Limiti: send-text 200 caratteri; send-tts 500 caratteri; upload-voice 10 MB / 30 s (AMR o simili); bulk-delete 1–100 UUID.
  • Messaggi inviati da token partner hanno sender_user_id: null (no attribuzione umana). sender_name valorizzato da request o logica di servizio.

Geofence

Path base: /api/v1/geofences/. Scope: geofences:read, geofences:write.

MetodoPathScope
GET/geofences:read
POST/geofences:write
GET/{id}/geofences:read
PATCH/{id}/geofences:write
DELETE/{id}/geofences:write
POST/{id}/devices/geofences:write (solo scope=device)
DELETE/{id}/devices/{uid}/geofences:write

Regole semantiche:

  • Solo fence circolari in questa versione. fence_typecircle → 400.
  • center {lat, lng} obbligatorio per circle. radius in metri, > 0 e ≤ 50 000.
  • dwell_threshold_seconds richiesto se trigger_on_dwell: true.
  • Regole scope (validazione server-side):
    • org — feature flag geofence_scoping richiesta; group/user devono essere null. Si applica a tutti i device attivi della org.
    • group — non esposto ai partner (primitiva admin umana).
    • useruser obbligatorio nella org; group null. Risolve via assegnazioni del device.
    • device (default) — group/user null. Si applica solo ai device linkati esplicitamente via POST /{id}/devices/. Lista vuota → fence non matcha nulla.
  • PATCH consente cambio di name/description/center/radius/trigger_*/schedule/is_active. Non consente cambio di scope/group/user.
  • Response list include device_count. Response detail include devices, schedule e i campi scope-dipendenti (group_id/user_id/...).

Soglie di allerta

Path base: /api/v1/alert-thresholds/.

MetodoPathScope
GET/thresholds:read
POST/thresholds:write
GET/{id}/thresholds:read
PATCH/{id}/thresholds:write
DELETE/{id}/thresholds:write

Regole semantiche:

  • scope enum integer: ORGANIZATION (10), DEVICE (15), USER (20).
    • USERuser obbligatorio, device null.
    • DEVICEdevice obbligatorio, user null.
    • ORGANIZATION → entrambi null.
  • metric_key validato contro il catalogo telemetria — stesse chiavi di last_status (vedi Dispositivi).
  • low/high — almeno uno richiesto; se entrambi presenti, low ≤ high.
  • In response, enum integer sono serializzati come label stringa (scope: "Organization", severity: "Warning", override_mode: "Replace").

Audit log

Path base: /api/v1/audit-log/. Scope: audit:read. Solo righe della propria org.

MetodoPath
GET/
GET/{id}/

Filtri: actor (UUID utente), actor_partner_integration (UUID), actor_type (partners/users/system), action (0=created, 1=updated, 2=deleted), content_type, model_name, timestamp_after, timestamp_before, search (su object_repr).

Note:

  • actor_type:
    • partners → scrittura via token partner → actor_partner_integration popolato.
    • users → scrittura umana → actor popolato ({id, email, full_name}).
    • system → evento senza request-context (task automatici, migrazioni).
  • actor_partner_integration.deleted: true indica snapshot conservato di integrazione cancellata.
  • Detail aggiunge raw changes ({field: [old, new]}) e additional_data (metadati arbitrari). La lista espone solo changes_summary derivato.

Org self

Path: /api/v1/organizations/self/. Scope: org:read. Solo partner auth — JWT umani ricevono 403.

Ritorna metadata della org: name, slug, timezone, default_locale, enabled_features (solo feature truthy), integration_status ("Active" per token validi), rate_limits (per_minute, per_hour).


Inviti

Path base: /api/v1/organizations/invitations/. Gate: feature flag managed_onboarding sulla org del partner.

MetodoPathScope
GET/invitations:read
GET/{id}/invitations:read
DELETE/{id}/invitations:write (soft-delete)
POST/{id}/revoke/invitations:write
POST/server-accept/invitations:write (vedi Assegnazioni)

Note:

  • La creazione di inviti generici (POST /) è riservata al flow umano. Il partner crea share via POST /api/v1/devices/{uid}/share/ (vedi Assegnazioni).
  • Il campo metadata (che contiene device_uid per inviti share) non è esposto in response. Per ricavare il device target, il partner intercetta il token nell'email e chiama /server-accept/ (vedi Share device).

Catalogo device

Path: /api/v1/protocols/, /api/v1/models/. Scope: catalog:read. Reference data read-only, non tenant-scoped.

MetodoPathContenuto
GET/api/v1/protocols/Lista protocolli
GET/api/v1/protocols/{slug}/Dettaglio protocollo
GET/api/v1/models/Modelli device cross-protocollo
GET/api/v1/protocols/{slug}/models/Modelli per protocollo
GET/api/v1/protocols/{slug}/models/{model_slug}/Dettaglio modello
GET/api/v1/protocols/{slug}/models/{model_slug}/capabilities/Capability del modello
GET/api/v1/devices/{uid}/capabilities/Capability risolte per il singolo device (override inclusi)

Use case: popolare dropdown nella UI client ("scegli modello al registro device"); determinare quali command_type / metriche telemetria accetta un device dato.


© Mastersoft — LifeDome