The ChartChat server is an Express application. All routes are registered in packages/server/src/app.ts.
Route Groups​
| Prefix | Router file | Purpose |
|---|
/healthcheck | healthcheck.ts | Liveness probe — returns 200 OK |
/openapi.json | openapi.ts | OpenAPI spec |
/.well-known/ | wellknown/ | OIDC discovery, JWKS |
/auth/ | auth/routes.ts | Authentication (login, register, MFA, external) |
/oauth2/ | oauth/routes.ts | OAuth2 token endpoints |
/fhir/R4/ | fhir/routes.ts | FHIR R4 resource CRUD and operations |
/fhir/R4/Binary | fhir/binary.ts | Binary file upload/download |
/fhir/ehr-import/ | ehr-import/routes.ts | EHR OAuth connect, callback, disconnect, sync |
/fhir/ (custom) | fhir/customRoutes.ts | ChartChat-specific FHIR extensions |
/fhir/ (export) | fhir/exportPatient.ts | Patient data export |
/fhir/ (import) | fhir/importPatient.ts | Patient data import |
/smart/ | smart/routes/launch.ts | SMART on FHIR launch |
/smart/patient-summary | smart/routes/patient-summary.ts | AI patient summary |
/admin/ | admin/routes.ts | Admin API (users, bots, secrets, etc.) |
/api/admin/queues | workers/bullboard.ts | BullMQ queue dashboard |
/api/audit/ | audit/audit-routes.ts | Audit log query |
/support/v1/ | support/routes.ts | Support ticket system |
/email/v1/ | email/routes.ts | Email sending |
/dicom/PS3/ | dicom/routes.ts | DICOM image handling |
/scim/v2/ | scim/routes.ts | SCIM user provisioning |
/keyvalue/v1/ | keyvalue/routes.ts | Key-value store |
/storage/ | storage/routes.ts | Binary storage |
/webhook/ | webhook/routes.ts | Webhook receivers |
/fhircast/STU2/ | fhircast/routes.ts | FHIRcast STU2 |
/fhircast/STU3/ | fhircast/routes.ts | FHIRcast STU3 |
/mcp/ | mcp/routes.ts | Model Context Protocol (if enabled) |
All Endpoints​
Complete flat reference of every endpoint exposed by the ChartChat server.
| Method | Path | Auth | Description |
|---|
GET | /healthcheck | None | Liveness probe — returns 200 OK |
GET | /openapi.json | None | OpenAPI spec |
Auth & MFA​
| Method | Path | Auth | Description |
|---|
POST | /auth/login | None | Email + password login |
POST | /auth/register | None | New user registration |
POST | /auth/mfa/status | Bearer | Returns MFA enrollment state and QR code URI if not enrolled |
POST | /auth/mfa/enroll | Bearer | Confirms TOTP enrollment with a 6-digit code |
POST | /auth/mfa/verify | None | Verifies TOTP during login flow |
POST | /auth/mfa/disable | Bearer | Disables MFA after verifying current TOTP code |
| Method | Path | Auth | Description |
|---|
POST | /oauth2/token | None | Issues access / refresh tokens |
POST | /oauth2/revoke | None | Revokes a refresh token |
GET | /.well-known/openid-configuration | None | OIDC discovery document |
GET | /.well-known/jwks.json | None | JSON Web Key Set for token verification |
EHR Import​
| Method | Path | Auth | Description |
|---|
POST | /fhir/ehr-import/start | Patient | Begins EHR OAuth for a built-in provider — returns authorizeUrl |
POST | /fhir/ehr-import/hospital-start | Patient | Begins EHR OAuth for a HospitalIntegration using dynamic SMART discovery |
GET | /fhir/ehr-import/callback | None | OAuth callback — exchanges code, creates/updates PatientEHRConnection, triggers sync |
GET | /fhir/ehr-import/smart-discovery | None | Probes a FHIR base URL for its SMART .well-known/smart-configuration |
POST | /fhir/ehr-import/disconnect/:connectionId | Patient | Revokes an EHR connection and clears its Redis token cache |
EHR Sync​
| Method | Path | Auth | Description |
|---|
POST | /fhir/referesh/all-ehrs | Patient | Queues a background sync of all active EHR connections for the patient |
POST | /fhir/referesh/single/:connectionId | Patient | Queues a background sync for one specific EHR connection |
GET | /fhir/referesh/status | Patient | Returns current sync state (idle / syncing) and last result |
SMART on FHIR (Provider Launch / SSO)​
| Method | Path | Auth | Description |
|---|
GET | /smart/launch | None | Entry point for EHR-initiated SMART launch — validates iss + launch params and redirects to EHR auth |
GET | /smart/callback | None | OAuth callback for SMART launch — exchanges code and creates session |
GET | /smart/medplum/login | None | Initiates Medplum SSO login flow |
GET | /smart/medplum/callback | None | Handles Medplum SSO OAuth callback |
POST | /smart/medplum/resume | None | Resumes Medplum login after MFA challenge |
GET | /smart/sync/patient | Bearer | Manually triggers a patient data sync (admin/provider use) |
POST | /smart/patient-summary | Bearer | Generates an AI-powered patient summary |
Document Proxy​
| Method | Path | Auth | Description |
|---|
GET | /fhir/binary-proxy/:binaryId | Patient | Streams a FHIR Binary file from S3 — enforces access policy server-side |
GET | /fhir/url-proxy | Patient | Proxies a pre-signed storage URL — prevents exposing S3 URLs to the browser |
FHIR R4​
| Method | Path | Auth | Description |
|---|
* | /fhir/R4/* | Bearer | Standard FHIR R4 CRUD and search for all resource types |
* | /fhir/R4/Binary | Bearer | Binary file upload and download |
GET | /fhir/get-access-policy | Bearer | Returns the access policy ID assigned to the authenticated user's project membership |
GET | /fhir/hospitals/search | Patient | Searches Organization + Endpoint resources by name, state, city, or postal code |
POST | /fhir/epic/exchange-token | None | Exchanges an Epic authorization code for tokens server-side |
DELETE | /fhir/deletePatient/:id | Admin | Deletes a patient and all associated FHIR resources |
POST | /fhir/import/bulk-patient | Admin | Bulk-imports patient data from NDJSON export URLs |
| Method | Path | Auth | Description |
|---|
GET | /api/audit/logs | Admin | Queries AuditEvent resources with filters |
Support Tickets​
| Method | Path | Auth | Description |
|---|
POST | /support/v1/create-ticket | Patient | Creates a support ticket and sends a confirmation email |
PATCH | /support/v1/admin/tickets/:id | Admin | Updates ticket status, priority, or internal notes |
POST | /support/v1/admin/tickets/:id/reply | Admin | Sends a reply to the patient and creates an in-app notification |
| Method | Path | Auth | Description |
|---|
* | /admin/* | Admin | Admin API — user management, bots, secrets, project config |
GET | /api/admin/queues | Admin | BullMQ queue dashboard (Bull Board UI) |
EHR Import Routes​
These are ChartChat's custom routes for EHR OAuth and sync. All under /fhir/ehr-import/.
| Method | Route | Auth | Description |
|---|
POST | /fhir/ehr-import/start | Patient token | Begins EHR OAuth — returns authorizeUrl for a built-in EHR provider (epic, healow, meditech) |
POST | /fhir/ehr-import/hospital-start | Patient token | Begins EHR OAuth for a HospitalIntegration — discovers SMART endpoints dynamically |
GET | /fhir/ehr-import/callback | None (browser redirect) | OAuth callback — exchanges code for token, creates/updates PatientEHRConnection, triggers background sync |
POST | /fhir/ehr-import/disconnect/:connectionId | Patient token | Sets connection status: revoked and clears Redis token cache |
Audit Routes​
| Method | Route | Auth | Description |
|---|
GET | /api/audit/logs | Admin token | Query audit events with filters |
Support Routes​
| Method | Route | Auth | Description |
|---|
POST | /support/v1/create-ticket | Patient token | Create a support ticket (rate limited 10/15 min) |
PATCH | /support/v1/admin/tickets/:id | Admin token | Update ticket status, priority, or internal notes |
POST | /support/v1/admin/tickets/:id/reply | Admin token | Send a reply to the patient and email notification |
See Custom API Routes for full request/response documentation.
Middleware Stack​
Every request passes through this middleware chain (in order):
standardHeaders — Sets security headers: Cache-Control, Strict-Transport-Security, Content-Security-Policy, Permissions-Policy, Referrer-Policy, X-Content-Type-Options, X-Frame-Options, X-XSS-Protection
- CORS — Configured in
cors.ts — restricts origins to allowed domains
- CSRF protection —
csrf.ts — validates CSRF token on non-GET requests
- Compression — gzip response compression
- Request context —
attachRequestContext — sets up per-request logging and user context
- Request logging —
requestLogMiddleware — writes every request to the RequestLog DB table
- Rate limiting —
rateLimitHandler — per-IP limits (stricter on auth endpoints)
- Body parsers — URL-encoded, JSON (up to
maxJsonSize), HL7 v2 text
Error Handling​
Unhandled errors are caught by the global errorHandler middleware at the end of the chain:
| Error type | Response |
|---|
FHIR OperationOutcome | Returned as-is with appropriate HTTP status |
entity.parse.failed | 400 Bad Request — invalid JSON/body |
entity.too.large | 400 Bad Request — payload over size limit |
UnsupportedMediaTypeError | 415 Unsupported Media Type |
| Other | 500 Internal Server Error |