# 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 ``` #### Method B: `X-API-Key` Custom Header ```http X-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_` (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(endpoint: string, options: RequestInit = {}, patientId: string): Promise { 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('/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(`/v1/onboarding/${sessionId}/message`, { method: 'POST', body: JSON.stringify({ message }), }, patientId); } export async function completeOnboarding(sessionId: string, patientId: string, confirmed: boolean = true) { return fetchApi(`/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_ 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} ```