Drug Safety
Drug Safety
DELPHOS performs drug-safety analysis at two distinct points in the prescription lifecycle:
- Streaming pipeline (pre-persistence, advisory). While the doctor dictates or types, the streaming endpoint runs a 6-gate pipeline in real time. Results stream alongside each extracted medication item. See Streaming Prescription Extraction for the SSE contract and gate-by-gate detail.
- Post-persistence safety check (blocking for critical interactions).
Once a prescription is saved as a
draft, thePOST /v1/prescriptions/{id}/safety-checkendpoint runs the three-tier cascading interaction lookup and stores results on the prescription record. Critical and contraindicated interactions must be acknowledged before the prescription can advance tosigned.
This article covers the post-persistence safety check — the authoritative interaction store. For the real-time streamed gates, see the dedicated Streaming Prescription Extraction article.
The 6-Gate Streaming Pipeline (Pre-Persistence, Advisory)
Before a prescription is saved, the streaming extraction agent runs a
6-gate advisory pipeline. The gates are all advisory — even
critical severity findings inform but do not block — per Lei
12.842/2013 and CFM Code of Ethics Articles 20-21.
| Gate | Name (canonical) | Scope | Blocks streaming? |
|---|---|---|---|
| 1 | Validação de Entrada (Input Validation) | Per-item | Only blocking gate (medication_name required) |
| 2 | Resolução de Medicamento (CMED / ANVISA registry match) | Per-item | Advisory |
| 3 | Interações Medicamentosas (drug-drug interactions) | Cross-item | Advisory |
| 4 | Duplicidade Terapêutica (active ingredient + EPhMRA class) | Cross-item | Advisory |
| 5 | Substâncias Controladas (Portaria 344/98 / RDC 20/2011) | Per-item | Advisory |
| 6 | Cruzamento de Alergias (v1.1) | Per-item | Advisory (when shipped) |
The streaming pipeline returns its results inline in the SSE stream
(item_detected events carry gates 1, 2, 6; gates_complete carries
gates 3, 4). They are diagnostic — to persist them, the doctor
finalizes via POST /v1/prescriptions, after which the
post-persistence safety check described below becomes the
authoritative store.
Post-Persistence Safety Check
DELPHOS performs drug interaction analysis on prescription items using a three-tier cascading lookup. Results are attached to the prescription and must be reviewed — and critical interactions acknowledged — before a prescription can be signed.
Safety Check Endpoint
Run an on-demand interaction analysis on all items in a prescription. This operation is idempotent: any previously stored interactions are cleared and replaced with fresh results on each call.
POST /v1/prescriptions/{prescription_id}/safety-checkThe prescription must not be in a terminal status (dispensed or cancelled).
Status codes
| Code | Meaning |
|---|---|
200 | Analysis complete — response contains interactions and summary |
404 | Prescription not found |
409 | Prescription is in a terminal status (dispensed or cancelled) |
500 | Interaction service error |
curl -X POST "https://your-instance.delphos.app/v1/prescriptions/PRESCRIPTION_ID/safety-check" \ -H "x-api-key: YOUR_API_KEY"import httpx
response = httpx.post( f"https://your-instance.delphos.app/v1/prescriptions/{prescription_id}/safety-check", headers={"x-api-key": "YOUR_API_KEY"},)result = response.json()Response shape
{ "prescription_id": "a7b8c9d0-e1f2-3456-ab01-567890123456", "interactions": [ { "id": "b1c2d3e4-f5a6-7890-bcde-f12345678901", "drug_a": "VARFARINA SODICA", "drug_b": "ASPIRINA", "severity": "critical", "interaction_type": "pharmacodynamic", "description": "Increased bleeding risk due to combined anticoagulant effects", "recommendation": "Avoid concomitant use; consider alternative analgesic", "source": "tier1_matrix" } ], "safety_summary": { "passed": false, "critical_count": 1, "contraindicated_count": 0, "major_count": 0, "moderate_count": 0, "minor_count": 0 }, "items_checked": 3, "ingredients_analyzed": ["VARFARINA SODICA", "ASPIRINA", "LOSARTANA POTASSICA"]}Response fields
InteractionResponse fields:
| Field | Type | Description |
|---|---|---|
id | UUID or null | UUID of the stored interaction record (null for unsaved results) |
drug_a | string | First drug name in the interacting pair |
drug_b | string | Second drug name in the interacting pair |
severity | string | Severity level (see table below) |
interaction_type | string | Pharmacological type, e.g. "pharmacodynamic" |
description | string | Human-readable description of the interaction |
recommendation | string | Prescriber guidance for managing the interaction |
source | string | Which detection tier found this, e.g. "tier1_matrix" |
Severity levels:
| Severity | Blocks signing | Description |
|---|---|---|
critical | Yes | Potentially life-threatening combination |
contraindicated | Yes | Combination should never be used |
major | No | Significant risk; may require dose adjustment |
moderate | No | Moderate risk; monitor closely |
minor | No | Low risk; usually manageable |
Acknowledging Interactions
Before a prescription can be transitioned to signed, all critical and
contraindicated interactions must be explicitly acknowledged by the
prescribing physician.
Acknowledge a single interaction
PATCH /v1/prescriptions/{prescription_id}/interactions/{interaction_id}/acknowledgeRequest body:
| Field | Type | Required | Description |
|---|---|---|---|
doctor_id | UUID | Yes | UUID of the doctor acknowledging the interaction |
curl -X PATCH "https://your-instance.delphos.app/v1/prescriptions/PRESCRIPTION_ID/interactions/INTERACTION_ID/acknowledge" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"doctor_id": "e5f6a7b8-c9d0-1234-efab-345678901234"}'import httpx
response = httpx.patch( f"https://your-instance.delphos.app/v1/prescriptions/{prescription_id}" f"/interactions/{interaction_id}/acknowledge", headers={"x-api-key": "YOUR_API_KEY"}, json={"doctor_id": "e5f6a7b8-c9d0-1234-efab-345678901234"},)acknowledged = response.json()Returns 200 with the updated interaction record. Returns 404 if the
prescription or interaction is not found, or if the interaction has already
been acknowledged.
Acknowledge all interactions at once
POST /v1/prescriptions/{prescription_id}/interactions/acknowledge-allRequest body:
| Field | Type | Required | Description |
|---|---|---|---|
doctor_id | UUID | Yes | UUID of the doctor acknowledging all interactions |
curl -X POST "https://your-instance.delphos.app/v1/prescriptions/PRESCRIPTION_ID/interactions/acknowledge-all" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"doctor_id": "e5f6a7b8-c9d0-1234-efab-345678901234"}'import httpx
response = httpx.post( f"https://your-instance.delphos.app/v1/prescriptions/{prescription_id}" f"/interactions/acknowledge-all", headers={"x-api-key": "YOUR_API_KEY"}, json={"doctor_id": "e5f6a7b8-c9d0-1234-efab-345678901234"},)result = response.json()# {"acknowledged_count": 2}Returns 200 with { "acknowledged_count": N }. Returns 404 if the
prescription is not found.
Checking Signing Readiness
After the safety check and acknowledgments, verify the prescription is ready to sign by fetching its detail:
GET /v1/prescriptions/{prescription_id}The response includes:
| Field | Description |
|---|---|
can_sign | true when no blocking interactions remain unacknowledged |
blocking_interactions_count | Count of unacknowledged critical/contraindicated interactions |
pending_acknowledgements_count | Count of all unacknowledged interactions (any severity) |
When can_sign is true, the prescription can be transitioned to signed
(see Creating Prescriptions).