Back to Home

API Documentation

Complete reference for the Healthy Habits Index REST + WebSocket API

v3.44 · HHIProduction: https://www.healthyhabitsindex.com · Local: http://localhost:3000

Introduction

The Healthy Habits Index API powers the unified caregiver-facility dashboard (PACE programs and Memory Care communities). It exposes participants, devices, real-time huddle rooms, billing rollups, and night-command triage as JSON over REST, with a WebSocket channel for live collaboration. Every request is scoped to the calling user's facility via the custom:facilityId claim on the Cognito JWT.

ℹ️

Authentication required

All endpoints (except /api/health) require a Cognito JWT in the Authorization: Bearer <idToken> header. In DEV_MODE a synthetic Medical Director identity at Sentinel PACE is injected automatically.

🏥

Personas

Two facility models share the same engine. PACE (Sentinel PACE) ships sleep + speech with capitation framing. Memory Care (Cedar Ridge) activates all six HHI domains (sleep, speech, mobility, hygiene, hydration, routine) with mixed RTM/RPM/CCM billing. Persona is set at facility creation; the dashboard's persona band lets a user toggle their view at runtime.

Authentication

The API uses AWS Cognito for authentication. Include the access token in the Authorization header for all authenticated requests.

POST/api/auth/login

Authenticate user and obtain access tokens

Request Body

{
  "email": "string",      // User email address
  "password": "string"    // User password
}

Response

{
  "success": true,
  "tokens": {
    "accessToken": "string",   // JWT access token (use in Authorization header)
    "idToken": "string",       // JWT ID token (carries claims below)
    "refreshToken": "string",
    "expiresIn": 3600
  },
  "user": {
    "email": "string",
    "name": "string",
    "role": "medical_director" | "care_team" | "on_call_rn" | "facility_admin",
    "organization": "string",       // facility display name
    "facilityId": "sentinel-pace" | "cedar-ridge-mc"
  }
}

// JWT idToken carries the matching Cognito claims:
//   "cognito:groups":   ["MedicalDirectors" | "CareTeam" | "OnCallRN" | "FacilityAdmins"]
//   "custom:role":      "medical_director" | "care_team" | "on_call_rn" | "facility_admin"
//   "custom:facilityId": "sentinel-pace" | "cedar-ridge-mc"

Role permissions

RoleCognito groupCapabilities
medical_directorMedicalDirectorsFull access. Billing, IDT decisions, user management, all clinical writes.
facility_adminFacilityAdminsUser management, devices, billing, ROI. Limited clinical writes.
care_teamCareTeamIDT participants — read all clinical, document care minutes, claim huddle assignments.
on_call_rnOnCallRNNight Command only. Sees after-hours triage queue + escalation actions.

Example Request

curl -X POST https://api.healthyhabitsindex.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "clinician@example.com",
    "password": "SecurePassword123!"
  }'

Error Codes

CodeDescription
400Missing email or password
401Incorrect username or password
403User account not confirmed
GET/api/auth/me

Get current authenticated user information

Headers

Authorization: Bearer <access_token>

Response

{
  "success": true,
  "data": {
    "email": "string",
    "name": "string",
    "role": "clinician" | "admin" | "caregiver",
    "organization": "string",
    "cognitoSub": "string"
  }
}
POST/api/auth/refresh

Refresh access token using refresh token

Request Body

{
  "refreshToken": "string"
}
POST/api/auth/logout

Invalidate current session and tokens

Participants (HHI)

Participants are the unified resource in the HHI dashboard. They supersede the legacy /api/patients resource and add per-domain scores, HHI history, predictive risk, cross-domain correlations, identity-auth events, canary biomarkers, cognitive-stage inference, medication adherence, and billing cycles. Every endpoint is scoped to the caller's facility.

GET/api/participants

List participants in the caller's facility, with optional tier / search filters.

Query parameters

ParameterTypeDescription
facilityIdstringOverride the JWT-scoped facility (admin only).
tierstringOne of excellent, stable, mild, moderate, critical, all.
searchstringSubstring match against name or MRN.

Response

{
  "success": true,
  "facilityId": "sentinel-pace",
  "count": 12,
  "data": [
    {
      "id": "sentinel-pace-p001",
      "mrn": "C-0001",
      "name": "Dorothy Williams",
      "age": 85, "sex": "F",
      "facilityId": "sentinel-pace",
      "site": "Sentinel Home Care",
      "clinician": "Dr. Sarah Chen, Medical Director",
      "cohort": "frailty",
      "hhi": 51, "baseline": 74, "drift30": -23,
      "chronologicalAge": 85, "functionalAge": 96,
      "domains": { "sleep": { ... }, "speech": { ... } },   // active per persona
      "drivers": [ ... ], "actions": [ ... ],
      "predictiveRisk": { "fall90d": 0.78, "hospitalization90d": 0.65,
                          "cognitiveDecline90d": 0.55, "velocity": "accelerating" },
      "crossDomain": [ ... ],
      "medication": { "mai": 54, "adherencePct": 75, ... },
      "billing":    { "yyyymm": "2026-04", "billed": 154.92, "lost": 99.95, ... },
      "status": "monitoring"
    }
  ]
}
GET/api/participants/{id}

Full participant payload including identity events, canary biomarkers, cognitive-stage inference.

GET/api/participants/{id}/trend?days=30

Daily HHI series for the trend chart. days clamped to 7–90.

Response

{
  "success": true,
  "data": {
    "participantId": "sentinel-pace-p001",
    "baseline": 74, "current": 51, "drift30": -23,
    "forecast": { "d30": 47, "d60": 43, "d90": 38 },
    "series": [
      { "date": "2026-04-10", "hhi": 73, "tier": "mild" },
      { "date": "2026-04-11", "hhi": 71, "tier": "mild" },
      ...
      { "date": "2026-05-09", "hhi": 51, "tier": "critical" }
    ]
  }
}
GET/api/participants/{id}/actions

List care plan actions. Optional ?lifecycle=new|in_progress|monitoring|closed|declined.

POST/api/participants/{id}/actions

Create a care plan action.

Request body

{
  "title": "Initiate hydration coaching",      // required
  "tag": "HYDRATION",                          // optional, free text
  "tier": "mild",                              // tier color band
  "lifecycle": "new",                          // default: new
  "urgency": "soon",                           // today | 48h | week | soon | monitor | trend
  "ownerRole": "care_team",
  "ownerName": "Monica Alvarez RN",
  "dueAt": "2026-05-16T17:00:00Z",
  "revenueImpact": 24.95
}
PATCH/api/participants/{id}/actions/{actionId}

Update an action's lifecycle, owner, urgency, or due date.

POST/api/participants/{id}/care-minutes

Log documented care time. Triggers re-computation of the billing cycle (eligibility for 98980 / 99457 / 99490 unlocks at ≥ 20 minutes).

Request body

{
  "minutes": 12,                  // positive integer
  "note": "Phone check-in with daughter; medication review",
  "userId": "sarah.chen@sentinelpace.example"
}

Response

{
  "success": true,
  "data": {
    "billing": { "yyyymm": "2026-05", "billed": 254.87, "lost": 0,
                 "careMinutes": 24, "status": "optimal", "codes": [ ... ] },
    "addedMinutes": 12,
    "totalMinutes": 24
  }
}

Devices

Sense™ radar fleet management. Each device reports rolling uptime, last-sync timestamp, firmware version, radar SNR (in dB), and the health of its four sub-sensors (radar / mic / ambient / faucet) — each one of ok, warn, or fail.

GET/api/devices

List all devices for the caller's facility.

Response

{
  "success": true,
  "data": [
    {
      "id": "S-SEN-001",
      "patientId": "sentinel-pace-p001",
      "patientName": "Dorothy Williams",
      "facilityId": "sentinel-pace",
      "site": "Sentinel Home Care",
      "status": "online",                       // online | degraded | offline
      "uptime": "99.4%",
      "lastSync": "just now",
      "firmware": "3.7.1",
      "radarSnr": 24,
      "sensors": { "radar": "ok", "mic": "ok",
                   "ambient": "ok", "faucet": "warn" }
    }
  ]
}
GET/api/devices/export

CSV inventory export. Returns text/csv with one row per device — used for fleet audits and field-tech routing.

Huddle Rooms

One huddle room per facility per day. The room contains a session record and a set of lane assignments (toc, incidents, silent, operational). Real-time collaboration is delivered through the WebSocket channel huddle:<facilityId>:<yyyy-mm-dd>; the HTTP endpoints below are the durability + replay path.

GET/api/huddle/today

Today's huddle for the caller's facility (auto-created if missing).

Response

{
  "success": true,
  "data": {
    "session": {
      "roomId": "sentinel-pace#2026-05-09",
      "facilityId": "sentinel-pace",
      "date": "2026-05-09",
      "status": "open",
      "openedAt": "2026-05-09T07:30:00Z",
      "attendees": []
    },
    "assignments": [
      {
        "roomId": "sentinel-pace#2026-05-09",
        "participantId": "sentinel-pace-p001",
        "participantName": "Dorothy Williams",
        "lane": "silent",                        // toc | incidents | silent | operational
        "urgency": "today",                      // today | 48h | week
        "headline": "Sleep instability",
        "why": "Cliff inflection 02:14–04:38; 3 near-fall events",
        "recommendedAction": "NP eval before 11:00 · UA + CBC + med rec",
        "ownerName": null,                       // null = unassigned
        "ownerUserId": null,
        "velocity": "accelerating",
        "costExposure": 99.95
      }
    ]
  }
}
POST/api/huddle/{roomId}/assignments

Update a lane assignment (claim ownership, change lane, append decision/note). Last-write-wins per assignment. After the write, the server broadcasts a huddle:assignment_set event on the room channel so all connected IDT members receive the update.

Request body

{
  "participantId": "sentinel-pace-p001",   // required
  "lane": "incidents",                     // optional — drag/drop result
  "ownerName": "Monica Alvarez RN",
  "ownerUserId": "monica.alvarez@sentinelpace.example",
  "decision": "Bring to center · NP eval before 11:00",
  "notes": "Family (Margaret) confirmed ride; transport at 09:15",
  "userId": "sarah.chen@sentinelpace.example"   // who made the edit (broadcast)
}

Night Command

After-hours triage queue. Designed for the on-call RN — each event arrives with advance directives, POLST text, signal-confidence reasoning, live state, recent context timeline, and a recommended action with reassessment timer.

GET/api/night/queue

Active and rising-risk events for the caller's facility.

Response (truncated)

{
  "success": true,
  "data": [
    {
      "id": "sentinel-pace-p001-night-0",
      "participantId": "sentinel-pace-p001",
      "participantName": "Dorothy Williams",
      "type": "sleep_apnea",
      "severity": "critical",
      "timestamp": "2026-05-09T02:31:00Z",
      "elapsed": "12 min",
      "headline": "Suspected central apnea cluster",
      "advanceDirective": "dnh",
      "polst": "Comfort care preferred. No transport unless airway compromise.",
      "confidenceLevel": "high",
      "positiveEvidence": [ "Multi-sensor correlation", "Pattern matches prior episodes" ],
      "negativeEvidence": [ "No vocal distress detected" ],
      "liveState":   { "Position": "supine", "Respiration": "irregular", "SpO2": "87%" },
      "contextTimeline": [
        { "time": "02:14", "desc": "First desat event", "highlight": false },
        { "time": "02:31", "desc": "Cluster begins",    "highlight": true }
      ],
      "primaryAction": "Send Fellow on-call · activate oximeter monitoring",
      "reassessAt": "In 20 min",
      "rationale": "POLST favors home/community treatment. No transport.",
      "secondaryActions": [ "Notify caregiver", "Schedule MD review at 7 AM huddle" ]
    }
  ]
}

Billing & Exports

CMS RTM / RPM / CCM rollups, plus CSV exports suitable for clearinghouse intake QA. The 837P export is a CSV approximation — real X12 EDI conversion happens in the clearinghouse layer.

GET/api/billing/export

CSV download with one row per (participant × CPT code × cycle). Columns: patient_id, mrn, patient_name, dob_year, cycle, cpt_code, rate_usd, billed, reason, care_minutes, tier. Returns text/csv; charset=utf-8 with a Content-Disposition: attachment header.

CPT codes generated

CodeDescriptionTriggered by
98977RTM device supply (musculoskeletal)Active monitoring
99454RPM device supply / data transmissionActive monitoring
98980RTM treatment management · first 20 min≥ 20 documented care minutes
99457RPM care management · first 20 min≥ 20 documented care minutes
99490CCM · 20+ min/month≥ 20 minutes & tier ≤ moderate
98976RTM device supply (respiratory)Pending CMS classification of mmWave nocturnal respiration
GET/api/devices/export

CSV inventory export — see Devices section above.

GET/api/dashboard/sidebar-counts

Aggregate counts powering the sidebar badges.

Response

{
  "tierCounts": { "excellent": 4, "stable": 3, "mild": 2,
                  "moderate": 2, "critical": 1, "all": 12 },
  "flaggedSleep": 3,
  "flaggedMedication": 2,
  "flaggedDevices": 2,
  "unacknowledgedAlerts": 2
}

User Management

Restricted to medical_director and facility_admin. Backed by Cognito — creating a user provisions them in the user pool, sets custom:role + custom:facilityId, and adds them to the matching group (MedicalDirectors / CareTeam / OnCallRN / FacilityAdmins).

GET/api/admin/users

List users at the caller's facility.

POST/api/admin/users

Invite a new user. They receive a temporary password.

Request body

{
  "name": "Dr. Priya Shah",
  "email": "priya.shah@sentinelpace.example",
  "role": "facility_admin",
  "facilityId": "sentinel-pace"
}

WebSocket Events

Live updates flow over a single WebSocket endpoint. Clients subscribe to channels and receive typed broadcast messages. The huddle room channel powers the IDT collaboration view; alert / session channels feed the dashboard's push notifications.

WS/api/_ws

WebSocket upgrade endpoint. JWT is sent as the first message after connection ({"type":"auth","token":"<idToken>"}).

Client → Server messages

// 1) Authenticate
{ "type": "auth", "token": "<idToken>" }

// 2) Subscribe to a channel
{ "type": "subscribe", "channel": "huddle:sentinel-pace:2026-05-09" }

// 3) Heartbeat
{ "type": "ping" }

// 4) Unsubscribe
{ "type": "unsubscribe", "channel": "huddle:sentinel-pace:2026-05-09" }

Server → Client broadcast envelope

{
  "type": "broadcast",
  "channel": "huddle:sentinel-pace:2026-05-09",
  "data": {
    "type": "huddle:assignment_set",     // event type — see table below
    "assignment": { ... }                // payload varies per event
  },
  "timestamp": "2026-05-09T07:42:13Z"
}

Channels & events

ChannelEventsNotes
huddle:<facilityId>:<yyyy-mm-dd>huddle:assignment_set
huddle:lane_move
huddle:note_append
huddle:presence_join
huddle:presence_leave
huddle:close
Real-time IDT collaboration. Last-write-wins per assignment.
alertsalert:created · alert:acknowledged · alert:resolvedFacility-wide alert feed.
dashboarddashboard:stats_updatedSidebar counts refresh trigger.
patient:<participantId>patient:updated · session:metrics_updated · event:respiratory_addedSubscribe when a participant detail page is open.

HTTP fallback

Every event has a corresponding REST endpoint that produces the same state change (e.g. POST /api/huddle/{roomId}/assignments emits huddle:assignment_set). Clients that can't open a WebSocket should poll the GET endpoints instead — no functionality is gated on the WebSocket transport.

Patients (legacy)

⚠️

Deprecated

The /api/patients family is preserved for the legacy Sleep HHI and General HHI dashboards (/legacy/*). New integrations should use /api/participants, which returns a richer payload and is scoped by facility. The schemas below remain valid.

Manage patient records, demographics, and monitoring status.

GET/api/patients

List all patients with optional filtering and sorting

Query Parameters

ParameterTypeDescription
statusstringFilter by patient status: active, inactive, discharged
riskLevelstringFilter by risk level: critical, high, moderate, low
organizationstringFilter by organization ID
assignedClinicianstringFilter by assigned clinician ID
searchstringSearch by patient name, MRN, or device ID (min 2 characters)
sortBystringField to sort by (default: lastName)
sortOrderstringSort direction: asc or desc (default: asc)

Response

{
  "success": true,
  "data": [
    {
      "id": "string",
      "mrn": "string",
      "firstName": "string",
      "lastName": "string",
      "dateOfBirth": "string",
      "gender": "male" | "female" | "other",
      "status": "active" | "inactive" | "discharged",
      "riskLevel": "critical" | "high" | "moderate" | "low",
      "healthyHabitsIndex": number,
      "deviceId": "string",
      "enrollmentDate": "string",
      "lastSessionDate": "string",
      "assignedClinician": "string",
      "organization": "string",
      "contact": {
        "email": "string",
        "phone": "string",
        "address": "string"
      },
      "conditions": string[],
      "medications": string[]
    }
  ]
}

Example Request

curl -X GET 'https://api.healthyhabitsindex.com/api/patients?status=active&riskLevel=high&sortBy=healthyHabitsIndex&sortOrder=asc' \
  -H "Authorization: Bearer <access_token>"
GET/api/patients/:id

Get detailed information for a specific patient

Path Parameters

ParameterTypeDescription
idstringPatient unique identifier

Example Request

curl -X GET https://api.healthyhabitsindex.com/api/patients/PAT-001 \
  -H "Authorization: Bearer <access_token>"
POST/api/patients

Create a new patient record (validated against the standard patient schema)

Request Body

{
  "mrn": "string",              // Medical Record Number (required)
  "firstName": "string",        // First name (required)
  "lastName": "string",         // Last name (required)
  "dateOfBirth": "YYYY-MM-DD",  // Date of birth (required)
  "gender": "male" | "female" | "other",
  "deviceId": "string",         // Monitoring device ID
  "assignedClinician": "string",
  "organization": "string",
  "contact": {
    "email": "string",
    "phone": "string",
    "address": "string"
  },
  "conditions": string[],       // Pre-existing conditions
  "medications": string[]       // Current medications
}

Response

{
  "success": true,
  "data": { /* full Patient object */ },
  "message": "Patient created successfully"
}
POST/api/patients/create

Enrollment endpoint used by the in-app enrollment flow. Creates a patient and binds a monitoring device in a single call. Use this endpoint when onboarding from a device pairing workflow; use POST /api/patients for standard EHR-style creation.

Request Body

{
  "firstName": "string",        // Required
  "lastName": "string",         // Required
  "dateOfBirth": "YYYY-MM-DD",  // Required (age is computed server-side)
  "sex": "M" | "F",             // Required
  "mrn": "string",              // Required — Medical Record Number
  "organization": "string",     // Required
  "email": "string",            // Required
  "phone": "string",            // Required
  "deviceId": "string",         // Required — paired monitoring device ID
  "deviceSerial": "string",     // Required — device serial number
  "notes": "string"             // Optional clinical notes
}

Response

{
  "success": true,
  "patient": {
    "id": "string",             // Generated patient ID (e.g., patient-1700000000000-ab12cd34e)
    "firstName": "string",
    "lastName": "string",
    "mrn": "string",
    "email": "string"
  },
  "message": "Patient enrolled successfully"
}

Example Request

curl -X POST https://api.healthyhabitsindex.com/api/patients/create \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Helen",
    "lastName": "Marsh",
    "dateOfBirth": "1942-08-14",
    "sex": "F",
    "mrn": "MRN-001241",
    "organization": "EVMS Pilot",
    "email": "helen.marsh@example.com",
    "phone": "+1-555-0142",
    "deviceId": "SENSE-HM-241",
    "deviceSerial": "SN-2024-241"
  }'

Error Codes

CodeDescription
400Missing required field (response message identifies the field)
409A patient with this MRN or email already exists
500Failed to enroll patient (internal error)
PUT/api/patients/:id

Update patient information

DELETE/api/patients/:id

Delete (archive) a patient record

GET/api/patients/:id/metrics

Get patient health metrics and trends

Response

{
  "success": true,
  "data": {
    "healthyHabitsIndex": {
      "current": number,
      "trend": "improving" | "stable" | "declining",
      "changePercent": number,
      "history": Array<{date: string, value: number}>
    },
    "sleepQuality": {
      "avgDuration": number,
      "avgEfficiency": number,
      "totalSessions": number
    },
    "respiratoryHealth": {
      "avgRespiratoryRate": number,
      "apneaEvents": number,
      "apneaProbability": number
    },
    "alerts": {
      "critical": number,
      "high": number,
      "total": number
    }
  }
}
GET/api/patients/:id/sleep-sessions

Get all sleep sessions for a patient

Query Parameters

ParameterTypeDescription
startDatestringFilter sessions from this date (ISO 8601)
endDatestringFilter sessions until this date (ISO 8601)
limitnumberMaximum number of sessions to return (default: 30)

Sleep Sessions

Access detailed sleep session data including respiratory events, metrics, and quality scores.

GET/api/sleep-sessions/:id

Get detailed sleep session information

Response

{
  "success": true,
  "data": {
    "id": "string",
    "patientId": "string",
    "startTime": "string",
    "endTime": "string",
    "duration": number,              // Duration in minutes
    "qualityScore": number,          // 0-100
    "sleepEfficiency": number,       // Percentage
    "respiratoryRate": {
      "avg": number,
      "min": number,
      "max": number,
      "stdDev": number
    },
    "apneaEvents": {
      "total": number,
      "obstructive": number,
      "central": number,
      "mixed": number,
      "ahiScore": number             // Apnea-Hypopnea Index
    },
    "stages": {
      "awake": number,
      "light": number,
      "deep": number,
      "rem": number
    },
    "heartRate": {
      "avg": number,
      "min": number,
      "max": number
    },
    "spo2": {
      "avg": number,
      "min": number,
      "desaturationEvents": number
    }
  }
}
GET/api/sleep-sessions/:id/events

Get respiratory events for a sleep session

Response

{
  "success": true,
  "data": [
    {
      "id": "string",
      "sessionId": "string",
      "timestamp": "string",
      "eventType": "apnea" | "hypopnea" | "snoring" | "desaturation",
      "severity": "mild" | "moderate" | "severe",
      "duration": number,           // Duration in seconds
      "respiratoryRate": number,
      "spo2Drop": number,          // Oxygen saturation drop
      "classification": "obstructive" | "central" | "mixed"
    }
  ]
}
POST/api/sleep-sessions/:id/events

Create a new respiratory event (device upload)

PUT/api/sleep-sessions/:id

Update sleep session (e.g., add clinical notes)

POST/api/sleep-sessions

Create a new sleep session

Request Body

{
  "patientId": "string",          // Required
  "deviceId": "string",
  "startTime": "string",          // ISO 8601 timestamp
  "endTime": "string",            // ISO 8601 timestamp
  "rawData": object               // Device-specific raw data
}

Dashboard & Analytics

Get aggregated statistics and analytics for clinical dashboards.

GET/api/dashboard/stats

Get dashboard statistics and overview metrics

Response

{
  "success": true,
  "data": {
    "patients": {
      "total": number,
      "active": number,
      "inactive": number,
      "newThisMonth": number
    },
    "riskDistribution": {
      "critical": number,
      "high": number,
      "moderate": number,
      "low": number
    },
    "alerts": {
      "total": number,
      "unacknowledged": number,
      "critical": number,
      "byType": {
        "respiratory": number,
        "apnea": number,
        "heartRate": number,
        "spo2": number
      }
    },
    "sessions": {
      "totalToday": number,
      "avgDuration": number,
      "avgQuality": number,
      "dataCoverage": number      // Percentage of patients with data today
    },
    "trends": {
      "hhiImproving": number,
      "hhiDeclining": number,
      "hhiStable": number
    }
  }
}
GET/api/dashboard/alerts

Get recent alerts requiring attention

Query Parameters

ParameterTypeDescription
statusstringFilter by status: active, acknowledged, resolved
severitystringFilter by severity: critical, high, medium, low
limitnumberMaximum number of alerts (default: 50)

Response

{
  "success": true,
  "data": [
    {
      "id": "string",
      "patientId": "string",
      "patientName": "string",
      "type": "respiratory_decline" | "apnea_threshold" | "heart_rate" | "spo2_low" | "hhi_drift",
      "severity": "critical" | "high" | "medium" | "low",
      "message": "string",
      "timestamp": "string",
      "status": "active" | "acknowledged" | "resolved",
      "acknowledgedBy": "string",
      "acknowledgedAt": "string",
      "metadata": {
        "value": number,
        "threshold": number,
        "sessionId": "string"
      }
    }
  ]
}

Alerts

Manage clinical alerts and notifications.

POST/api/alerts/:id/acknowledge

Acknowledge an alert

Request Body

{
  "clinicianId": "string",
  "notes": "string"              // Optional clinical notes
}

Response

{
  "success": true,
  "data": {
    "id": "string",
    "status": "acknowledged",
    "acknowledgedBy": "string",
    "acknowledgedAt": "string",
    "notes": "string"
  }
}
POST/api/alerts/:id/resolve

Mark an alert as resolved

Request Body

{
  "clinicianId": "string",
  "resolution": "string",        // Description of resolution action
  "followUpRequired": boolean
}

Medication Panel

Endpoints powering the Medication Adherence Index (MAI) and Guided Medication Assistance (GMA) workflow. Adherence is captured automatically by the Sense device through radar + voice authentication and cloned-voice prompts. The MAI score is a 0–100 weighted measure of scheduled doses taken on time, with recent days weighted more heavily.

💊

MAI Tier Bands

Stable 85+ · Mild 70–84 · Moderate 55–69 · High Risk 0–54. Patients with no regimen on file are excluded from MAI ranking.

GET/api/medication/adherence

Returns all GMA-enrolled patients with their current MAI score, today's dose progress, 7-day adherence trend, cloned-voice metadata, and full regimen. Powers the Medication Panel ranking table.

Query Parameters

ParameterTypeDescription
tierstring Filter by MAI tier: stable, mild, moderate, critical, or all (default).
sitestringFilter by site name (e.g. EVMS Pilot, Carilion Home).

Response

{
  "success": true,
  "data": [
    {
      "id": "patient-001",
      "name": "Dorothy Williams",
      "age": 85,
      "sex": "F",
      "site": "Carilion Home",
      "mai": {
        "score": 58,                      // 0-100 weighted adherence
        "tier": "moderate",               // excellent | stable | mild | moderate | critical
        "todaysTaken": 2,                 // doses taken so far today
        "todaysTotal": 5,                 // doses scheduled today
        "todaysMissed": 3,
        "dailyAdherence": [62,55,71,50,68,58,43]  // 7-day % timeline (oldest -> today)
      },
      "regimen": {
        "clonedVoice": {
          "speakerName": "Margaret Williams",
          "relationship": "Daughter",
          "consentDate": "2026-01-14"
        },
        "medications": [
          {
            "name": "Donepezil",
            "dose": "10 mg",
            "color": "white",
            "shape": "oval",
            "purpose": "memory and cognitive function",
            "schedule": ["08:00"]
          }
        ]
      }
    }
  ]
}

Example Request

curl -X GET 'https://api.healthyhabitsindex.com/api/medication/adherence?tier=critical' \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
GET/api/medication/summary

Aggregate cohort metrics for the Medication Panel hero header and stratification cards.

Response

{
  "success": true,
  "data": {
    "enrolledCount": 6,
    "todaysScheduled": 14,
    "todaysTaken": 11,
    "todaysMissed": 3,
    "buckets": {
      "stable": 3,        // MAI 85+
      "mild": 2,          // MAI 70-84
      "moderate": 0,      // MAI 55-69
      "critical": 1       // MAI 0-54
    },
    "averageMAI": 81,
    "lastUpdated": "2026-05-02T12:34:56.000Z"
  }
}
GET/api/medication/regimens/:patientId

Returns the active medication regimen and cloned-voice metadata for a single GMA-enrolled patient. Used by the patient detail Operations tab.

Path Parameters

ParameterTypeDescription
patientIdstringPatient identifier (e.g. patient-001)

Response

{
  "success": true,
  "data": {
    "patientId": "patient-001",
    "clonedVoice": {
      "speakerName": "Margaret Williams",
      "relationship": "Daughter",
      "consentDate": "2026-01-14"
    },
    "medications": [
      {
        "name": "Donepezil",
        "dose": "10 mg",
        "color": "white",
        "shape": "oval",
        "purpose": "memory and cognitive function",
        "schedule": ["08:00"]
      }
    ]
  }
}

Error Codes

CodeDescription
400Missing patientId path parameter
404Patient is not enrolled in GMA / no regimen on file
GET/api/medication/sessions/:patientId

Returns dose-by-dose GMA session log for a patient over a configurable rolling window. Each entry corresponds to one scheduled dose with its taken / missed status.

Path Parameters

ParameterTypeDescription
patientIdstringPatient identifier (e.g. patient-001)

Query Parameters

ParameterTypeDescription
daysnumberRolling window length in days, 1–7 (default: 7)

Response

{
  "success": true,
  "data": {
    "patientId": "patient-001",
    "windowDays": 7,
    "sessions": [
      {
        "date": "2026-04-26",
        "dateLabel": "Sun, Apr 26",
        "medication": "Donepezil",
        "dose": "10 mg",
        "scheduledTime": "08:00",
        "taken": true,
        "takenAt": "08:00",
        "dayIndex": 0
      }
    ]
  }
}

Sleep Data

Access raw and processed sleep data for analysis.

GET/api/sleep-data

Get sleep data records with filtering

Query Parameters

ParameterTypeDescription
patientIdstringFilter by patient ID
startDatestringStart date for date range (ISO 8601)
endDatestringEnd date for date range (ISO 8601)
metricsstringComma-separated list of metrics to include
GET/api/sleep-data/:id

Get specific sleep data record by ID

Health Check

Monitor API availability and status.

GET/api/health

Check API health status (no authentication required)

Response

{
  "status": "ok",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "service": "nasoni-dashboard"
}

Example Request

curl -X GET https://api.healthyhabitsindex.com/api/health

Error Handling

All API errors follow a consistent format and use standard HTTP status codes.

Error Response Format

{
  "success": false,
  "statusCode": number,
  "message": "string",
  "error": "string",              // Error type/name (optional)
  "details": object               // Additional error details (optional)
}

HTTP Status Codes

CodeStatusDescription
200OKRequest successful
201CreatedResource created successfully
400Bad RequestInvalid request parameters or body
401UnauthorizedMissing or invalid authentication token
403ForbiddenInsufficient permissions for requested resource
404Not FoundRequested resource does not exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Example Error Response

{
  "success": false,
  "statusCode": 404,
  "message": "Patient not found",
  "error": "NotFoundError"
}

Rate Limiting

API requests are rate-limited to ensure fair usage and system stability.

⚠️

Rate Limits

Standard tier: 1000 requests per hour
Premium tier: 5000 requests per hour
Exceeding rate limits returns a 429 Too Many Requests response.

Rate Limit Headers

All responses include rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1642248000

Best Practices

🔒 Security

  • Always use HTTPS for API requests
  • Store access tokens securely (never in client-side storage)
  • Implement token refresh before expiration
  • Use environment variables for sensitive configuration
  • Rotate API credentials regularly

⚡ Performance

  • Use pagination and filtering to limit response sizes
  • Cache responses when appropriate
  • Implement exponential backoff for retries
  • Batch API requests when possible
  • Monitor rate limit headers

🛠️ Development

  • Use the health check endpoint to verify connectivity
  • Implement comprehensive error handling
  • Log all API interactions for debugging
  • Validate data before sending requests
  • Test with production-like data volumes

SDKs & Libraries

Official and community-maintained client libraries for common programming languages.

JavaScript / TypeScript

npm install @hhi/api-client
View Documentation →

Python

pip install hhi-api
View Documentation →

Java

// Maven dependency
<dependency>
  <groupId>com.hhi</groupId>
  <artifactId>api-client</artifactId>
</dependency>
View Documentation →

REST API

Use any HTTP client to interact with the API directly

View cURL Examples →