Skip to main content
Docs vCurrentAPI
Version: Current

Alert governance (fighting fatigue)

SauBit emits deterministic clinical alerts (clinical_alerts) on top of drug-drug interactions. In real settings, alert overload causes fatigue: clinicians start ignoring warnings — including critical ones. Alert governance lets each organization tune what is shown without ever changing the clinical truth.

Copia um prompt pronto com fluxo de integração, payload e exemplos.

Safety principles

  • Suppression is presentation, not diagnosis. A suppressed alert still counts towards the prescription_risk_level. Governance never lowers prescription risk.
  • Critical risk cannot be hidden. Alerts at/above confirm_min_severity (default CONTRAINDICADO) are always surfaced and flagged requires_confirmation: true — no policy lever can suppress them.
  • Every suppression is auditable. Each suppressed item carries the reason (suppression_reason) and, for known-alert overrides, the recorded justification.

Response fields

Each clinical_alerts item exposes:

FieldDescription
idStable alert id (drug-order independent). Use it to suppress/justify known alerts.
requires_confirmationtrue when explicit confirmation is required before proceeding.

And the response gains the alert_governance block:

"alert_governance": {
"applied": true,
"policy_enabled": true,
"view": "pharmacist",
"unit": "icu",
"min_severity": "MODERADO",
"confirm_min_severity": "CONTRAINDICADO",
"requires_confirmation": true,
"confirmation_required_ids": ["drug_allergy-1a2b3c4d5e"],
"total_alerts": 4,
"visible_count": 2,
"suppressed_count": 2,
"suppressed": [
{ "type": "food_alcohol", "severity": "LEVE", "id": "food_alcohol-9f8e7d6c5b", "suppression_reason": "below_min_severity", "justification": "" }
]
}

Suppression reasons:

ReasonMeaning
below_min_severityBelow the configured minimum severity.
suppressed_typeAlert type suppressed by policy (global or per unit).
policy_overrideKnown alert suppressed with a recorded justification.
out_of_viewOutside the role view (e.g. drug_disease in the pharmacist view).

Role views (physician × pharmacist)

Send the X-SauBit-Alert-View header (or ?alert_view=) with medico or farmaceutico:

curl -X POST https://api.saubit.com.br/api/v1/interactions/check \
-H "X-API-Key: sm_live_..." \
-H "X-SauBit-Alert-View: farmaceutico" \
-H "Content-Type: application/json" \
-d '{ "medications": [ { "name": "ibuprofeno" } ], "patient_record": { "conditions": ["insuficiência renal"] } }'
  • medico — sees every alert type.
  • farmaceutico — sees operational/dispensing alerts (allergy, duplication, max dose, IV compatibility, drug × lab, renal/hepatic adjustment); diagnostic-reasoning alerts (e.g. drug_disease) leave the list with out_of_view.

Critical alerts are always surfaced, regardless of the view.

Role security: when the API key has a bound role (set by the admin — physician/pharmacist), it is authoritative and the X-SauBit-Alert-View header is ignored (it cannot escalate privilege). The header applies only as a presentation hint when the key has no bound role. Suppression is display-only and never lowers risk — but the authentic role must come from identity, not a free header.

Hospital unit

The unit is inferred from patient_context.setting (e.g. "UTI", "Pediatria", "Oncologia") and normalized to a tag (icu, pediatrics, oncology, emergency, obstetrics). A policy can define per-unit rules.

Policy (per organization / API key)

The policy is a JSON object configured per organization (with per-API-key override). Fields:

FieldTypeEffect
enabledboolWhen false, becomes pass-through (keeps only critical confirmation).
min_severityLEVE·MODERADO·GRAVE·CONTRAINDICADOSuppresses alerts below the threshold.
confirm_min_severitysameSeverity at/above which confirmation is required (default CONTRAINDICADO).
suppressed_typeslistAlert types always suppressed (e.g. ["food_alcohol"]).
suppressed_signatureslistKnown-alert overrides: { "signature": "<id>", "justification": "...", "expires_at"?: "ISO 8601" }. With expires_at, the override expires and the alert resurfaces.
unit_rulesobjectPer-unit override: { "UTI": { "min_severity": "GRAVE" } }.
role_typesobjectVisible types per role: { "pharmacist": ["drug_allergy", "max_dose"] }.

Example policy:

{
"enabled": true,
"min_severity": "MODERADO",
"confirm_min_severity": "CONTRAINDICADO",
"suppressed_types": ["food_alcohol"],
"unit_rules": {
"UTI": { "min_severity": "GRAVE" },
"Pediatria": { "suppressed_types": [] }
},
"suppressed_signatures": [
{ "signature": "duplicate_therapy-1a2b3c4d5e", "justification": "Approved institutional protocol" }
]
}

Configuration (admin routes)

The policy is configured through admin routes (admin JWT, under /api/v1/admin/*), with the API key policy taking precedence over the organization policy. As admin routes, they are documented in the Admin Swagger (/docs/admin), kept separate from the hospital routes — including GET/PUT/DELETE …/organizations/{org_id}/alert-governance and …/api-keys/{key_id}/alert-governance.

Invalid input (severity outside the set, unknown alert type, override without justification) returns 422. Values are normalized (e.g. min_severity upper-cased, unit converted to a tag).

Propagation: API-key authentication is cached for ~60s; policy changes take effect within 60 seconds (a per-key override busts the cache immediately).

Metric: alerts that changed conduct

The headline governance KPI is not "how many alerts were generated" but how many changed the clinical decision. To measure it, the client records the decision taken on each surfaced alert.

Record a decision

POST /api/v1/interactions/alerts/decision (API-key auth, scope interactions:check):

curl -X POST https://api.saubit.com.br/api/v1/interactions/alerts/decision \
-H "X-API-Key: sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"analysis_id": "a1b2c3...",
"alert_id": "drug_disease-1a2b3c4d5e",
"decision": "modified",
"changed_conduct": true,
"justification": "Swapped for a pregnancy-safe alternative"
}'
FieldDescription
analysis_idId of the analysis (check/recheck) that produced the alert.
alert_idThe alert id from clinical_alerts.
decisionacknowledged (saw it, kept), overridden (overrode) or modified (changed conduct).
changed_conducttrue if the alert actually changed the prescription/conduct.
justificationRequired when decision = "overridden".

The server validates that the analysis belongs to the organization and backfills alert_type/severity from the stored analysis.

Query the metric

The aggregated query (changed_conduct_rate = share of decisions where the alert changed conduct, plus by-type/severity breakdowns) is an admin route documented in the Admin Swagger (/docs/admin): GET …/organizations/{org_id}/alert-metrics. The recorded decisions also feed the admin Dashboard/ROI.