465 lines
16 KiB
Markdown
465 lines
16 KiB
Markdown
# AI Patient Onboarding API — Complete Frontend Integration Guide
|
|
|
|
**Version**: `1.0.0`
|
|
**Target Audience**: Frontend Engineers (React / React Native / Vue / Next.js / Mobile)
|
|
**Backend Framework**: FastAPI (Python 3.13)
|
|
**Supported Protocols**: HTTP/1.1 REST, JSON, Multipart/Form-Data Formats
|
|
**Interactive API Documentation**:
|
|
- **Swagger UI**: `{BASE_URL}/docs`
|
|
- **ReDoc**: `{BASE_URL}/redoc`
|
|
- **OpenAPI Schema**: `{BASE_URL}/openapi.json`
|
|
|
|
---
|
|
|
|
## 1. Executive System Overview
|
|
|
|
The **AI Patient Onboarding API** is an enterprise multi-modal clinical intake system designed for hospitals, clinics, a
|
|
|
|
nd digital health platforms. It automates patient registration, symptom intake, medical history collection, document extraction, and specialty triage before a physician consultation.
|
|
|
|
### Key Capabilities for Frontend Applications:
|
|
1. **Multi-Modal Onboarding**:
|
|
- **Text-Based Onboarding**: Interactive chat-based intake powered by clinical LLM orchestrator.
|
|
- **Voice-First Onboarding**: Natural conversational voice intake supporting English (`en-IN`), Tamil (`ta-IN`), Hindi (`hi-IN`), Telugu (`te-IN`), Kannada (`kn-IN`), Malayalam (`ml-IN`), and Marathi (`mr-IN`) using Sarvam AI ASR/TTS.
|
|
2. **Medical Document Analysis**: Vision-based processing of lab reports, prescriptions, and discharge summaries (JPEG, PNG, WEBP, PDF up to 10MB).
|
|
3. **Session-Based State Engine**: Stateful intake tracking stored in persistent backend database.
|
|
4. **Structured EHR Output**: Automatic clinical JSON result extraction matching standard Electronic Health Record (EHR) models.
|
|
|
|
---
|
|
|
|
## 2. Server Base URLs & CORS Configuration
|
|
|
|
### Server Base URLs:
|
|
- **Local Development**: `http://localhost:8000` or `http://127.0.0.1:8000`
|
|
- **Staging / Production**: Configured via environment variable (`{BASE_URL}`)
|
|
|
|
### CORS (Cross-Origin Resource Sharing) Policy:
|
|
The backend enforces production-safe `CORSMiddleware`.
|
|
- **Allowed Origins**: `http://localhost:3000`, `http://localhost:5173`, `http://127.0.0.1:3000`, `http://127.0.0.1:5173`, `https://onboarding.skyheal.ai` (configurable via `CORS_ORIGINS`).
|
|
- **Allowed Credentials**: `true` (`Access-Control-Allow-Credentials: true`).
|
|
- **Allowed Headers**: `Authorization`, `Content-Type`, `X-API-Key`, `X-Patient-ID`, `X-Request-ID`, `Accept`, `Origin`.
|
|
- **Exposed Headers**: `X-Request-ID`.
|
|
|
|
---
|
|
|
|
## 3. Quick Start Integration Flow
|
|
|
|
```
|
|
[ Frontend App ]
|
|
│
|
|
├── 1. POST /v1/onboarding/start (or /v1/voice-onboarding/start)
|
|
│ └─► Returns session_id (e.g. "ONB-8F12A9C4" or "VOICE-D3CAEA5C")
|
|
│
|
|
├── 2. POST /v1/onboarding/{session_id}/message (or /turn for voice)
|
|
│ └─► Exchanges multi-turn symptom history & receiving AI responses
|
|
│
|
|
├── 3. POST /v1/documents/{session_id}/upload (Optional)
|
|
│ └─► Uploads medical reports / lab results
|
|
│
|
|
└── 4. POST /v1/onboarding/{session_id}/complete
|
|
└─► Returns final structured EHR result (PatientOnboardingResult)
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Master API Endpoint Directory
|
|
|
|
| HTTP Method | Endpoint Path | Auth Required | Rate Limit | Purpose |
|
|
| :--- | :--- | :--- | :--- | :--- |
|
|
| `GET` | `/health` | No | None | Service health check & AI provider status |
|
|
| `POST` | `/v1/onboarding/start` | **Yes** | 30 req/min | Start text onboarding session |
|
|
| `POST` | `/v1/onboarding/{session_id}/message` | **Yes** | 30 req/min | Send text intake message to AI |
|
|
| `POST` | `/v1/onboarding/{session_id}/complete` | **Yes** | 30 req/min | Finalize text session & output structured result |
|
|
| `POST` | `/v1/voice-onboarding/start` | **Yes** | 30 req/min | Start voice onboarding session |
|
|
| `POST` | `/v1/voice-onboarding/{session_id}/turn` | **Yes** | 30 req/min | Process speech recording or text fallback turn |
|
|
| `POST` | `/v1/voice-onboarding/{session_id}/complete` | **Yes** | 30 req/min | Finalize voice session & output structured result |
|
|
| `GET` | `/v1/voice-onboarding/audio/{audio_id}` | No | None | Stream TTS audio response (WAV/MP3) |
|
|
| `POST` | `/v1/documents/{session_id}/upload` | **Yes** | 10 req/min | Upload medical document / report (10MB max) |
|
|
|
|
---
|
|
|
|
## 5. Authentication & Patient Security
|
|
|
|
### Authentication Mechanisms:
|
|
|
|
#### Method A: HTTP Bearer Token (Standard)
|
|
```http
|
|
Authorization: Bearer <ACCESS_TOKEN>
|
|
```
|
|
|
|
#### Method B: `X-API-Key` Custom Header
|
|
```http
|
|
X-API-Key: <API_KEY>
|
|
```
|
|
|
|
### Supported Access Tokens:
|
|
1. **Service Secret API Key**: `skyheal_secure_api_key_2026` (configurable via `API_SECRET_KEY` in server environment).
|
|
2. **Patient Development Tokens**: `test_token_<PATIENT_ID>` (e.g. `test_token_PAT-10023`). Automatically establishes patient identity context.
|
|
|
|
### Patient Isolation & IDOR Protection Rules:
|
|
1. When starting a session (`/v1/onboarding/start`), `patient.id` is bound as session owner (`session.patient_id`).
|
|
2. Subsequent requests verify caller's authenticated `patient_id` matches session owner.
|
|
3. Access attempts by other patients return **`HTTP 403 Forbidden`**.
|
|
|
|
---
|
|
|
|
## 6. Text Onboarding API Specifications
|
|
|
|
### 6.1. POST `/v1/onboarding/start`
|
|
|
|
Starts a new text-based clinical onboarding intake session.
|
|
|
|
#### Request Headers:
|
|
```http
|
|
Content-Type: application/json
|
|
Authorization: Bearer test_token_PAT-10023
|
|
```
|
|
|
|
#### Request Body (`StartOnboardingRequest`):
|
|
```json
|
|
{
|
|
"patient": {
|
|
"id": "PAT-10023",
|
|
"name": "Kavitha Ramesh",
|
|
"age": 35,
|
|
"gender": "female",
|
|
"phone": "+919876543210",
|
|
"abha_id": "91-1234-5678-9012",
|
|
"insurance_scheme": "PMJAY",
|
|
"dietary_habits": "Vegetarian"
|
|
},
|
|
"category": {
|
|
"type": "general",
|
|
"code": "general_medicine",
|
|
"name": "General Medicine"
|
|
},
|
|
"language": "en"
|
|
}
|
|
```
|
|
|
|
#### Field Descriptions:
|
|
|
|
| Field | Type | Required | Validation Rules | Description |
|
|
| :--- | :--- | :--- | :--- | :--- |
|
|
| `patient.id` | string | **Yes** | Min length 1 | Unique patient identifier |
|
|
| `patient.name` | string | No | Optional | Full name of patient |
|
|
| `patient.age` | integer | No | $0 \le \text{age} \le 120$ | Patient age in years |
|
|
| `patient.gender` | string | No | Optional | Gender identity ("male", "female", "other") |
|
|
| `category.type` | string | **Yes** | `"general"` or `"speciality"` | Onboarding workflow type |
|
|
| `category.code` | string | **Yes** | Min length 1 | Specialty classification code |
|
|
| `category.name` | string | **Yes** | Min length 1 | Category display name |
|
|
| `language` | string | No | Default `"en"` | Preferred intake language |
|
|
|
|
#### Successful Response (`200 OK` - `StartOnboardingResponse`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "ONB-8F12A9C4",
|
|
"patient_id": "PAT-10023",
|
|
"category": {
|
|
"type": "general",
|
|
"code": "general_medicine",
|
|
"name": "General Medicine"
|
|
},
|
|
"language": "en",
|
|
"status": "in_progress",
|
|
"stage": "symptoms",
|
|
"message": "Hello Kavitha Ramesh! I am your clinical onboarding assistant. What symptoms are you experiencing today?"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 6.2. POST `/v1/onboarding/{session_id}/message`
|
|
|
|
Sends a patient chat response to the AI intake orchestrator.
|
|
|
|
#### Request Body (`SendMessageRequest`):
|
|
```json
|
|
{
|
|
"message": "I have had severe chest tightness and shortness of breath for 2 days."
|
|
}
|
|
```
|
|
|
|
#### Successful Response (`200 OK` - `SendMessageResponse`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "ONB-8F12A9C4",
|
|
"stage": "medical_history",
|
|
"message": "Thank you for sharing. Does the chest tightness radiate to your arm or jaw, and do you have any history of high blood pressure?",
|
|
"status": "in_progress",
|
|
"response_time_ms": 1529.74,
|
|
"response_time_sec": 1.53
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 6.3. POST `/v1/onboarding/{session_id}/complete`
|
|
|
|
Finalizes the intake session and outputs the structured clinical EHR payload.
|
|
|
|
#### Request Body (`CompleteOnboardingRequest`):
|
|
```json
|
|
{
|
|
"confirmed": true
|
|
}
|
|
```
|
|
|
|
#### Successful Response (`200 OK` - `CompleteOnboardingResponse`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "ONB-8F12A9C4",
|
|
"status": "completed",
|
|
"result": {
|
|
"patient_id": "PAT-10023",
|
|
"abha_id": "91-1234-5678-9012",
|
|
"phone": "+919876543210",
|
|
"insurance_scheme": "PMJAY",
|
|
"category": {
|
|
"type": "general",
|
|
"code": "general_medicine",
|
|
"name": "General Medicine"
|
|
},
|
|
"chief_complaint": "Chest tightness and shortness of breath for 2 days",
|
|
"symptoms": [
|
|
{
|
|
"name": "Chest tightness",
|
|
"duration": "2 days",
|
|
"severity": "severe",
|
|
"description": "Triggered during exertion"
|
|
}
|
|
],
|
|
"medical_history": ["Prehypertension"],
|
|
"medications": ["Metformin 500mg"],
|
|
"allergies": ["Penicillin"],
|
|
"dietary_habits": "Vegetarian",
|
|
"additional_information": "Patient confirmed details.",
|
|
"language": "en",
|
|
"onboarding_completed": true
|
|
},
|
|
"message": "Onboarding successfully completed and saved to patient record.",
|
|
"response_time_ms": 4075.41,
|
|
"response_time_sec": 4.08
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Voice Onboarding API Specifications
|
|
|
|
### 7.1. POST `/v1/voice-onboarding/start`
|
|
|
|
Starts a voice-first onboarding session with Sarvam AI multilingual speech engine.
|
|
|
|
#### Supported Languages:
|
|
`en-IN` (Indian English), `ta-IN` (Tamil), `hi-IN` (Hindi), `te-IN` (Telugu), `kn-IN` (Kannada), `ml-IN` (Malayalam), `mr-IN` (Marathi).
|
|
|
|
#### Request Body:
|
|
```json
|
|
{
|
|
"patient": {
|
|
"id": "PAT-VOICE-1",
|
|
"name": "Ramesh G",
|
|
"age": 34,
|
|
"gender": "male"
|
|
},
|
|
"category": {
|
|
"type": "general",
|
|
"code": "general_medicine",
|
|
"name": "General Medicine"
|
|
},
|
|
"language": "ta-IN"
|
|
}
|
|
```
|
|
|
|
#### Successful Response (`200 OK`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "VOICE-D3CAEA5C",
|
|
"patient_id": "PAT-VOICE-1",
|
|
"category": {
|
|
"type": "general",
|
|
"code": "general_medicine",
|
|
"name": "General Medicine"
|
|
},
|
|
"language": "ta-IN",
|
|
"status": "in_progress",
|
|
"stage": "greeting",
|
|
"greeting_text": "வணக்கம் Ramesh G, CureSelect மருத்துவமனைக்கு வரவேற்கிறோம். இன்று உங்களுக்கு என்ன சுகவீனம் உள்ளது?",
|
|
"audio_url": "/v1/voice-onboarding/audio/aud_a1b2c3d4e5f6",
|
|
"response_time_ms": 78.32,
|
|
"response_time_sec": 0.08
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 7.2. POST `/v1/voice-onboarding/{session_id}/turn`
|
|
|
|
Processes a conversational voice turn using audio recording or text fallback.
|
|
|
|
#### Multipart Form Data:
|
|
- `audio`: Binary audio recording file (`WAV`, `WEBM`, `MP3`, `OGG` up to 10MB).
|
|
- `text_fallback`: String text transcript (used if WebSpeech STT processed client-side).
|
|
|
|
#### Successful Response (`200 OK`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "VOICE-D3CAEA5C",
|
|
"patient_transcript": "எனக்குகடந்த 3 நாளா நெஞ்சு பாரமா இருக்குங்க.",
|
|
"ai_text": "நன்றி. இந்த நெஞ்சு பாரம் உடற்பயிற்சி செய்யும் போது அதிகமாகிறதா?",
|
|
"stage": "symptoms",
|
|
"completed": false,
|
|
"audio_url": "/v1/voice-onboarding/audio/aud_f9e8d7c6b5a4",
|
|
"audio_base64": null,
|
|
"suggested_specialty": {
|
|
"specialty": "Cardiology",
|
|
"reason": "Chest tightness reported"
|
|
},
|
|
"response_time_ms": 1412.37,
|
|
"response_time_sec": 1.41
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 7.3. GET `/v1/voice-onboarding/audio/{audio_id}`
|
|
|
|
Streams generated TTS audio for browser or mobile playback.
|
|
|
|
```javascript
|
|
const audio = new Audio(`${BASE_URL}/v1/voice-onboarding/audio/${audioId}`);
|
|
await audio.play();
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Medical Document Analysis API
|
|
|
|
### POST `/v1/documents/{session_id}/upload`
|
|
|
|
Uploads a medical report / prescription for vision extraction.
|
|
|
|
- **Content-Type**: `multipart/form-data`
|
|
- **File Limit**: Max `10MB` (`10,485,760 bytes`).
|
|
- **Allowed Formats**: `image/jpeg`, `image/png`, `image/webp`, `application/pdf`.
|
|
|
|
#### Successful Response (`200 OK`):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"session_id": "ONB-8F12A9C4",
|
|
"document_type": "lab_report",
|
|
"summary": "Report indicates elevated HbA1c (7.2%) and stage 1 hypertension (130/85 mmHg).",
|
|
"findings": [
|
|
{
|
|
"test": "HbA1c",
|
|
"value": "7.2",
|
|
"unit": "%",
|
|
"interpretation": "Elevated"
|
|
}
|
|
],
|
|
"medications_found": ["Metformin 500mg"],
|
|
"allergies_found": ["Penicillin"],
|
|
"message": "Medical document analyzed and integrated into onboarding session."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Error Handling & Status Codes
|
|
|
|
| HTTP Status Code | Meaning | Cause & Resolution |
|
|
| :--- | :--- | :--- |
|
|
| `400 Bad Request` | Bad Request | Invalid category or unsupported file format. |
|
|
| `401 Unauthorized` | Unauthorized | Missing or invalid `Authorization: Bearer` or `X-API-Key` header. |
|
|
| `403 Forbidden` | Forbidden (IDOR) | Authenticated `patient_id` does not match session owner. |
|
|
| `404 Not Found` | Not Found | Session ID does not exist in backend database. |
|
|
| `413 Payload Too Large` | File Too Large | Uploaded document exceeds 10MB limit. |
|
|
| `422 Validation Error` | Pydantic Error | Request body violates schema rules (e.g. `age < 0`). |
|
|
| `429 Too Many Requests` | Rate Limited | Exceeded rate limit bucket (30 req/min). Check `Retry-After` header. |
|
|
| `500 Internal Error` | Server Error | Unhandled backend failure. |
|
|
|
|
---
|
|
|
|
## 10. Frontend React & TypeScript Implementation Examples
|
|
|
|
### React API Client (`src/api/onboardingClient.ts`)
|
|
|
|
```typescript
|
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
|
|
|
|
export interface PatientContext {
|
|
id: string;
|
|
name?: string;
|
|
age?: number;
|
|
gender?: string;
|
|
phone?: string;
|
|
abha_id?: string;
|
|
}
|
|
|
|
export interface CategoryContext {
|
|
type: 'general' | 'speciality';
|
|
code: string;
|
|
name: string;
|
|
}
|
|
|
|
async function fetchApi<T>(endpoint: string, options: RequestInit = {}, patientId: string): Promise<T> {
|
|
const token = `test_token_${patientId}`;
|
|
const headers = new Headers(options.headers || {});
|
|
headers.set('Authorization', `Bearer ${token}`);
|
|
if (!(options.body instanceof FormData)) {
|
|
headers.set('Content-Type', 'application/json');
|
|
}
|
|
|
|
const response = await fetch(`${API_BASE_URL}${endpoint}`, { ...options, headers });
|
|
if (!response.ok) {
|
|
const errorBody = await response.json().catch(() => ({ detail: 'Network response error' }));
|
|
throw new Error(errorBody.detail || `HTTP Error ${response.status}`);
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function startOnboarding(patient: PatientContext, category: CategoryContext, language: string = 'en') {
|
|
return fetchApi<any>('/v1/onboarding/start', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ patient, category, language }),
|
|
}, patient.id);
|
|
}
|
|
|
|
export async function sendMessage(sessionId: string, patientId: string, message: string) {
|
|
return fetchApi<any>(`/v1/onboarding/${sessionId}/message`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ message }),
|
|
}, patientId);
|
|
}
|
|
|
|
export async function completeOnboarding(sessionId: string, patientId: string, confirmed: boolean = true) {
|
|
return fetchApi<any>(`/v1/onboarding/${sessionId}/complete`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ confirmed }),
|
|
}, patientId);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Frontend Integration Checklist
|
|
|
|
```text
|
|
[ ] Configure API_BASE_URL in environment (VITE_API_BASE_URL=http://localhost:8000)
|
|
[ ] Verify CORS preflight request from localhost:3000 / localhost:5173
|
|
[ ] Attach Authorization: Bearer test_token_<PATIENT_ID> header
|
|
[ ] Call POST /v1/onboarding/start and store session_id
|
|
[ ] Multi-turn chat message sending via POST /v1/onboarding/{session_id}/message
|
|
[ ] Handle 401 Unauthorized & 403 Forbidden errors
|
|
[ ] Upload medical documents via POST /v1/documents/{session_id}/upload (10MB max)
|
|
[ ] Call POST /v1/onboarding/{session_id}/complete to retrieve final PatientOnboardingResult
|
|
[ ] Test voice onboarding audio streaming via GET /v1/voice-onboarding/audio/{audio_id}
|
|
```
|