Documentation Index
Fetch the complete documentation index at: https://docs.hana.health/llms.txt
Use this file to discover all available pages before exploring further.
Overview
HANA’s EHR Proxy provides a standardized REST API that abstracts the differences between EHR systems. Write once against HANA’s API, and the Proxy handles translation to Epic, Cerner, Athena, AllScripts, or any FHIR-enabled system.
Base URL: https://api.hana.health/v1
Authentication: All requests require an X-API-KEY header and X-ORG-ID header.
curl https://api.hana.health/v1/patients \
--header 'X-API-KEY: <your-api-key>' \
--header 'X-ORG-ID: <your-organization-id>'
Patients
List Patients
Retrieves a list of patients for a practitioner.
Parameters:
| Name | In | Type | Required | Description |
|---|
| X-API-KEY | header | string | Yes | API key |
| X-ORG-ID | header | string | Yes | Organization ID |
| practitioner_id | query | string | No | Filter by practitioner |
| practitioner_email | query | string | No | Alternative practitioner lookup |
| count | query | integer | No | Results to return (default: 20) |
| include_fhir | query | boolean | No | Include raw FHIR in response |
Response (200):
{
"status": "ok",
"data": [
{
"id": "pat_abc123",
"first_name": "Maria",
"last_name": "Garcia",
"date_of_birth": "1985-03-14",
"gender": "female",
"phone": "+1-555-0142",
"email": "maria.garcia@email.com",
"primary_provider_id": "prov_xyz789"
}
],
"count": 1,
"total": 1
}
Create Patient
Request Body:
{
"first_name": "string",
"last_name": "string",
"date_of_birth": "YYYY-MM-DD",
"gender": "male | female | other | unknown",
"email": "string",
"phone_numbers": ["string"],
"address": {
"street": "string",
"city": "string",
"state": "string",
"postal_code": "string",
"country": "string"
},
"practitioner_id": "string"
}
Response (201): Created patient object.
Confirm Patient Identity
Validates if a patient exists. Requires either (first_name + last_name + date_of_birth) OR (phone_number).
Response (200): Patient found with matching record.
Response (404): Patient not found.
Patient Records
Get Patient Record
Retrieves a comprehensive patient record.
Parameters: Patient identified by (first_name + last_name + date_of_birth) OR (phone_number).
Response (200):
{
"status": "ok",
"data": {
"demographics": { },
"conditions": [
{
"code": "I10",
"display": "Essential hypertension",
"status": "active",
"onset_date": "2020-06-15"
}
],
"medications": [
{
"name": "Lisinopril",
"dosage": "10mg",
"frequency": "daily",
"status": "active",
"prescriber": "Dr. Smith"
}
],
"allergies": [
{
"substance": "Penicillin",
"reaction": "rash",
"severity": "moderate"
}
],
"vital_signs": [ ],
"lab_results": [ ],
"encounter_notes": [ ],
"insurance": { }
}
}
Get Vital Signs
GET /v1/patients/record/vital-signs
Update Vital Signs
PUT /v1/patients/record/vital-signs
Get Lab Results
GET /v1/patients/record/lab-results
Get Medications
GET /v1/patients/record/medications
Get Insurance
GET /v1/patients/record/insurance
Update Insurance
PUT /v1/patients/record/insurance
Practitioners
List Practitioners
Parameters:
| Name | In | Type | Required | Description |
|---|
| count | query | integer | No | Results to return (default: 20) |
| include_fhir | query | boolean | No | Include FHIR format |
Response (200):
{
"status": "ok",
"data": [
{
"id": "prov_xyz789",
"first_name": "Sarah",
"last_name": "Johnson",
"email": "sjohnson@clinic.com",
"specialty": "Family Medicine",
"npi": "1234567890",
"locations": ["loc_main", "loc_satellite"]
}
]
}
Appointments
List Appointments
Parameters:
| Name | In | Type | Required | Description |
|---|
| start_date_time | query | string | Yes | Start of range (ISO 8601) |
| end_date_time | query | string | Yes | End of range (ISO 8601) |
| practitioner_id | query | string | No | Filter by practitioner |
| patient identifiers | query | various | No | Filter by patient |
| count | query | integer | No | Results to return |
Response (200):
{
"status": "ok",
"data": [
{
"id": "appt_001",
"patient_id": "pat_abc123",
"practitioner_id": "prov_xyz789",
"start": "2026-02-10T09:00:00Z",
"end": "2026-02-10T09:30:00Z",
"status": "confirmed",
"type": "follow-up",
"reason": "Hypertension management"
}
]
}
Book Appointment
Request Body:
{
"patient_id": "string",
"practitioner_id": "string",
"start_date_time": "ISO 8601",
"end_date_time": "ISO 8601",
"reason": "string",
"notes": "string"
}
Reschedule Appointment
Request Body:
{
"patient_id": "string",
"appointment_start_date_time": "ISO 8601 (original)",
"new_start_date_time": "ISO 8601",
"new_end_date_time": "ISO 8601",
"reason": "string"
}
Cancel Appointment
Get Open Slots
GET /v1/appointments/open-slots
Parameters:
| Name | In | Type | Required | Description |
|---|
| start_date_time | query | string | Yes | Start of search window |
| end_date_time | query | string | No | End of search window |
| practitioner_id | query | string | No | Filter by practitioner |
Pre-Visit Notes
GET /v1/appointments/pre-visit/notes
PUT /v1/appointments/pre-visit/notes
Encounters & Clinical Notes
Get Encounter Notes
GET /v1/appointments/encounters/notes
Retrieves clinical notes for a given encounter or patient.
Create Encounter Note
POST /v1/appointments/encounters/notes
Request Body:
{
"text_content": "string (markdown or plain text)",
"json_content": {
"subjective": "string",
"objective": "string",
"assessment": "string",
"plan": "string"
}
}
Update Encounter Note
PUT /v1/appointments/encounters/notes
Delete Encounter Note
DELETE /v1/appointments/encounters/notes
SOAP Note Sections
Get or update individual SOAP sections:
GET /v1/appointments/encounters/notes/soap/sections/{section_id}
PUT /v1/appointments/encounters/notes/soap/sections/{section_id}
Add Chief Complaints
POST /v1/appointments/encounters/notes/chief-complaints
Request Body: ["string"]
Add Intake Questionnaire
POST /v1/appointments/encounters/notes/intake-questionnaire
Clinical Codes
Add ICD-10 Codes
POST /v1/appointments/encounters/notes/codes/icd10
Request Body: ["I10", "E11.9", "F32.1"]
Add CPT Codes
POST /v1/appointments/encounters/notes/codes/cpt
Request Body: ["99213", "99490", "96127"]
Medications & Patient Instructions
Add Medications
POST /v1/appointments/encounters/notes/medications
Request Body: ["Lisinopril 10mg daily", "Metformin 500mg BID"]
Add Patient Instructions
POST /v1/appointments/encounters/notes/patient-instructions
Request Body: ["Schedule follow-up in 2 weeks", "Monitor blood pressure daily"]
Conversations
Create Conversation
Initiate an AI-driven patient conversation.
Request Body:
{
"patient_id": "string",
"protocol": "intake | follow_up | ccm_checkin | bhi_screen | care_gap | custom",
"protocol_config": {
"custom_protocol_id": "string (if protocol=custom)"
},
"channel": "voice_outbound | voice_inbound | sms",
"scheduled_at": "ISO 8601 (optional, for scheduled outbound)",
"priority": "normal | high | urgent",
"metadata": {}
}
Response (201):
{
"status": "ok",
"data": {
"conversation_id": "conv_abc123",
"status": "scheduled",
"scheduled_at": "2026-02-10T14:00:00Z",
"patient_id": "pat_abc123",
"protocol": "ccm_checkin"
}
}
Get Conversation
GET /v1/conversations/{conversationId}
Response (200):
{
"status": "ok",
"data": {
"id": "conv_abc123",
"status": "completed",
"patient_id": "pat_abc123",
"protocol": "ccm_checkin",
"started_at": "2026-02-10T14:00:12Z",
"completed_at": "2026-02-10T14:07:45Z",
"duration_seconds": 453,
"outcome": {
"goals_completed": 4,
"goals_total": 5,
"escalated": false,
"quality_score": 4.5,
"extracted_data": { }
},
"transcript_url": "https://api.hana.health/v1/conversations/conv_abc123/transcript"
}
}
List Conversations
Parameters: Filter by patient, protocol, status, date range.
Get Transcript
GET /v1/conversations/{conversationId}/transcript
List Protocols
List Note Templates
GET /v1/appointments/encounters/notes/templates
List Note Fields
GET /v1/appointments/encounters/notes/fields
Monitoring
Health Check
EHR Connection Health
Response (200):
{
"status": "connected",
"ehr_system": "Epic",
"last_sync": "2026-02-07T13:45:00Z",
"latency_ms": 145
}
Error Handling
All errors follow a consistent format:
{
"status": "error",
"error": {
"code": "PATIENT_NOT_FOUND",
"message": "No patient found matching the provided identifiers.",
"details": {}
}
}
Common Error Codes:
| Code | HTTP Status | Description |
|---|
| UNAUTHORIZED | 401 | Invalid or missing API key |
| FORBIDDEN | 403 | Insufficient permissions |
| PATIENT_NOT_FOUND | 404 | No matching patient |
| APPOINTMENT_NOT_FOUND | 404 | No matching appointment |
| INVALID_INPUT | 400 | Malformed request |
| EHR_UNAVAILABLE | 503 | EHR system temporarily unreachable |
| RATE_LIMITED | 429 | Too many requests |
Rate Limits
| Tier | Requests/minute | Burst |
|---|
| Standard | 60 | 100 |
| Scale | 300 | 500 |
| Enterprise | 1,000 | 2,000 |