3. API Documentation
The current implementation uses mock data read through lib/data.ts. This section defines the production-ready APIs required to support every business workflow. The machine-readable contract is docs/developer/api/openapi.yaml (OpenAPI 3.1); this page is the readable guide to it: conventions first, then each of the 17 resource groups.
3.1 Conventions
Base URL and versioning
https://api.globalclinic.app/v1
The version is in the path (/v1). Breaking changes increment the major version; additive changes do not. The front-end reads the base URL from NEXT_PUBLIC_API_BASE_URL and calls it from the lib/data.ts seam.
Authentication
All endpoints except the public catalogue and the auth endpoints require a bearer access token (OAuth 2.1 / OIDC, short-lived JWT) in the Authorization: Bearer <token> header. Staff roles additionally require that the token was issued through an MFA-completed session. See Security.
Authorization
Every request is authorised server-side by role plus tenant and case scope, deny by default. A patient token resolves to one patient and one case; a clinic token to one clinic; staff tokens to assigned cases. Requests outside scope return 403. The RBAC matrix defines who can call what.
Request and response format
JSON only (Content-Type: application/json). Field names are camelCase and conform to the types in lib/schema.ts. Timestamps are ISO-8601 UTC. Money is an integer minor unit plus an ISO-4217 currency (never a float).
Pagination
List endpoints use cursor pagination: ?limit= (default 25, max 100) and ?cursor=. Responses include data[] and a page object with nextCursor and hasMore.
Idempotency
All POST endpoints that create resources or move money accept an Idempotency-Key header. Re-sending the same key returns the original result, never a duplicate. This is mandatory for payments, refunds, document uploads and visa submission.
Errors
Errors use standard HTTP status codes and a consistent body:
{
"error": {
"code": "validation_error",
"message": "Human-readable summary.",
"details": [{ "field": "documentId", "issue": "must reference a verified document" }],
"requestId": "req_01H..."
}
}
Common codes: 400 validation_error, 401 unauthenticated, 403 forbidden, 404 not_found, 409 conflict (for example a state-machine violation such as submitting an incomplete visa), 422 unprocessable, 429 rate_limited, 5xx server_error. Every response carries a requestId for support and tracing.
Rate limiting
Limits are per token and per IP, returned in RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers; 429 includes Retry-After. Indicative tiers:
| Surface | Limit |
|---|---|
| Public catalogue (unauthenticated) | 60 requests / minute / IP |
| Authenticated reads | 600 requests / minute / token |
| Writes (general) | 120 requests / minute / token |
| Money and document writes | 30 requests / minute / token, idempotency required |
| Auth (login, OTP, reset) | 10 requests / minute / IP, with lockout and backoff |
Webhooks
Outbound webhooks (to clinics, agents and internal consumers) are signed with an HMAC X-GC-Signature header and delivered at-least-once with retry and backoff. Inbound webhooks (from payment, visa and travel partners) are verified by signature and idempotency key. See Integrations.
3.2 Resource groups
The endpoint tables below summarise each group. Full request and response schemas, validation and error responses are in the OpenAPI file. Methods follow REST conventions; :id and :caseId are path parameters.
1. Authentication and authorization
| Method | Path | Purpose |
|---|---|---|
| POST | /auth/register | Create an account (patient or clinic) |
| POST | /auth/verify-email | Verify an email with a code |
| POST | /auth/login | Exchange credentials (and MFA for staff) for tokens |
| POST | /auth/token/refresh | Refresh an access token |
| POST | /auth/logout | Revoke the current session |
| POST | /auth/password/forgot | Begin password reset |
| POST | /auth/password/reset | Complete password reset with a token |
| POST | /auth/mfa/enroll and /auth/mfa/verify | Staff MFA enrolment and step-up |
| GET | /auth/me | Current principal, roles and tenant scope |
Validation: email format, password policy, rate-limited OTP, single-use reset tokens. Errors: 401 on bad credentials, 429 on too many attempts. The reference build models this with a client-side mock (lib/auth.tsx, two demo accounts).
2. Patient management
| Method | Path | Purpose |
|---|---|---|
| GET | /patients/:id | Patient profile (self or authorised staff) |
| PATCH | /patients/:id | Update profile fields |
| GET | /patients/:id/cases | Cases for a patient |
| POST | /cases | Open a case (from an accepted enquiry) |
| GET | /cases/:caseId | Full case with stage, corridor, coordinator |
| GET | /cases/:caseId/journey | The 14-stage progress with owners and SLA state |
| GET | /cases/:caseId/activity | Activity feed |
Authorization: a patient may read and update only their own record and case; staff are case-scoped. Validation: currentStage 0 to 13 and forward-only; attendant count at most two.
3. Clinic management
| Method | Path | Purpose |
|---|---|---|
| GET | /clinics/:id | Public clinic profile |
| PATCH | /clinics/:id | Update profile (own clinic) |
| GET | /clinics/:id/inquiries | Inbound inquiries, filter by status |
| POST | /clinics/:id/inquiries/:inquiryId/quote | Send an itemised quote |
| PATCH | /clinics/:id/inquiries/:inquiryId | Decline or update an inquiry |
| GET | /clinics/:id/cases | Active cases by stage |
| GET/PUT | /clinics/:id/pricing | Read and update indicative procedure prices |
| GET/POST/PATCH | /clinics/:id/team | Manage surgeons and staff |
| POST | /clinics/:id/onboarding | Submit onboarding for review |
Authorization: clinic-tenant isolation. Visibility rule: a clinic is publicly listed only when status = verified.
4. Provider management
Provider management is the clinical and operational side of a clinic: accreditation, empanelment, and milestone confirmation that drives escrow.
| Method | Path | Purpose |
|---|---|---|
| GET/POST | /providers/:id/accreditations | Accreditations held (JCI, NABH, ISO) |
| POST | /providers/:id/empanelment | Submit or update empanelment evidence |
| GET | /providers/:id/cases/:caseId | Shared case data the provider may see |
| POST | /cases/:caseId/milestones/:milestoneId/confirm | Provider confirms a milestone (for example admission, discharge) |
Authorization: empanelment review is owned by the Medical Director; milestone confirmation is restricted to the treating provider for the case. Confirming a milestone emits an event that the Payments service consumes to release escrow.
5. Treatment catalogue
Public, cacheable catalogue powering discovery.
| Method | Path | Purpose |
|---|---|---|
| GET | /catalogue/specialties | Specialties |
| GET | /catalogue/procedures | Procedures with indicative and reference pricing and savings |
| GET | /catalogue/procedures/:key | One procedure with cost breakdown |
| GET | /catalogue/clinics | Marketplace search and filter (specialty, country, price, rating) |
| GET | /catalogue/clinics/:id/pricing | A clinic's indicative procedure prices |
| GET | /catalogue/pricing/:procedureKey | Itemised cost breakdown and home-market savings |
| GET | /catalogue/network | Destinations and considerations |
No authentication; aggressively cached at the CDN. All prices are labelled indicative.
6. Medical records
The documents wallet and secure storage.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/documents | List documents with status |
| POST | /cases/:caseId/documents | Create an upload (returns a pre-signed URL) |
| PUT | (storage pre-signed URL) | Upload the file directly to object storage |
| POST | /cases/:caseId/documents/:docId/finalize | Finalise after upload (triggers scan) |
| POST | /cases/:caseId/documents/:docId/verify | Reviewer marks verified |
| GET | /cases/:caseId/documents/:docId/download | Time-limited, audited download URL |
Validation: type (Identity, Medical, Visa, Financial, Travel), size and MIME checks, virus scan before verified. Authorization: patient uploads; only an authorised reviewer verifies. Every read and write is audited. Verifying a document with a linked visa checklist item updates that item (the signature flow).
7. Consultations
The specialist opinion workflow.
| Method | Path | Purpose |
|---|---|---|
| POST | /cases/:caseId/consultations | Open a consultation, attach records |
| GET | /cases/:caseId/consultations/:id | Consultation status and opinion |
| POST | /cases/:caseId/consultations/:id/opinion | Specialist records the written opinion |
| POST | /cases/:caseId/consultations/:id/request-records | Request specific additional records |
| GET | /cases/:caseId/care-plan | Care-plan phases derived from the opinion |
Authorization: specialist and coordinator, case-scoped. The opinion is the specialist's, recorded by the platform; the API stores authorship.
8. Appointments
Scheduling for consultations, admission, procedure and follow-up tele-consults.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/appointments | All appointments for a case |
| POST | /cases/:caseId/appointments | Schedule (consult, admission, procedure, follow-up 7/30/90) |
| PATCH | /cases/:caseId/appointments/:id | Reschedule or update |
| POST | /cases/:caseId/appointments/:id/cancel | Cancel with reason |
Validation: no-show and reschedule rules; follow-up appointments default to day 7, 30 and 90. Conflicts return 409.
9. Visa management
The flagship engine, driven by Country Packs.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/visa | Application: hero, checklist, timeline |
| GET | /cases/:caseId/visa/checklist | Checklist with derived completion |
| POST | /cases/:caseId/visa/submit | Submit (only when complete) |
| POST | /cases/:caseId/visa/invitation-letter | Generate the invitation letter |
| GET | /corridors/:corridorId/country-pack | Corridor rules: documents, fees, processing, routing |
Validation: submit is rejected with 409 unless every checklist item resolves to done. Required documents come from the corridor Country Pack. Idempotent submit.
10. Travel management
Flights and transfers, coordinator-confirmed.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/travel | Trip plan, options and current selections |
| GET | /cases/:caseId/travel/flights | Flight options for the corridor and dates |
| GET | /cases/:caseId/travel/transfers | Ground-transfer options |
| POST | /cases/:caseId/travel/selection | Submit preferred flight, transfer and add-ons |
| POST | /cases/:caseId/travel/confirm | Travel Desk confirms (staff) |
Authorization: patient selects; Travel Desk confirms. Prices are indicative; confirmation calls airline and transfer providers (see Integrations).
11. Hotel management
Accommodation, attendant-aware.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/travel/stays | Accommodation options near the hospital |
| POST | /cases/:caseId/travel/stays/selection | Select a preferred stay |
| POST | /cases/:caseId/travel/stays/confirm | Travel Desk confirms the booking |
Filtering: attendant bed, halal kitchen, distance to hospital. Confirmation integrates a hotel-booking provider.
12. Payments and refunds
Escrow, milestones, ledger and refunds.
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/payments | Total, held, currency, milestones, ledger |
| POST | /cases/:caseId/payments/escrow/fund | Fund the escrow deposit |
| GET | /cases/:caseId/payments/milestones | Milestone schedule and status |
| POST | /cases/:caseId/payments/milestones/:id/release | Release on a verified trigger (system or finance) |
| POST | /cases/:caseId/payments/refunds | Request a refund |
| GET | /cases/:caseId/payments/ledger | Append-only ledger |
Validation: idempotency required; a milestone releases only on a verified trigger; pre-arrival refunds are full, post-milestone per schedule; ledger entries are immutable. Multi-currency per corridor. Integrates the payment and escrow partner.
13. Notifications
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/notifications | Notifications for a case |
| POST | /cases/:caseId/notifications/:id/read | Mark read |
| PUT | /users/:id/notification-preferences | Channel preferences (in-app, WhatsApp, email, SMS) |
Notifications are emitted by domain events (milestone, visa, travel, message) and delivered omnichannel.
14. Reviews and ratings
| Method | Path | Purpose |
|---|---|---|
| GET | /reviews | Public reviews, filter by clinic or procedure |
| GET | /clinics/:id/reviews | A clinic's verified reviews |
| POST | /cases/:caseId/reviews | Submit a review at close-out (verified, attributed) |
| GET | /reputation | Platform reputation aggregate and distribution |
Rule: a verified review must tie to a completed, attributed case; genuine negative verified reviews are not suppressed.
15. Messaging and communication
| Method | Path | Purpose |
|---|---|---|
| GET | /cases/:caseId/threads | Threads with the care team |
| GET | /threads/:id/messages | Messages in a thread (paged) |
| POST | /threads/:id/messages | Send a message (with attachments) |
| POST | /threads/:id/read | Mark a thread read |
Production is real-time (WebSocket or server-sent events) with an audit trail and omnichannel delivery prioritising WhatsApp; interpreter and translation support is Planned.
16. Administration
| Method | Path | Purpose |
|---|---|---|
| GET/POST/PUT | /admin/country-packs | Versioned, feature-flagged corridor rules |
| POST | /admin/country-packs/:id/publish | Publish a Country Pack version |
| GET/POST | /admin/clinics/empanelment | Manage the hospital panel |
| GET/PUT | /admin/feature-flags | Platform feature flags |
| GET/POST | /admin/users and /admin/roles | Staff users and role assignment |
Authorization: administrator only; all actions audited. Country Packs are versioned with an effective date so corridor rules change without a code release.
17. Reporting and analytics
| Method | Path | Purpose |
|---|---|---|
| GET | /reports/funnel | Lead-to-case funnel by corridor and channel |
| GET | /reports/sla | Stage SLA performance and breaches |
| GET | /reports/conversion | Conversion and time-to-first-response, time-to-quote |
| GET | /reports/affiliates | Referral attribution and payouts |
| GET | /reports/outcomes | Case outcomes and review capture |
Reads are served from the analytics warehouse, not the operational store. Authorization: admin, finance and medical-director roles, scoped to their remit.
3.3 Mapping the data seam to the API
Today lib/data.ts exposes typed getters backed by static JSON. In production each getter becomes a fetch to the matching endpoint, returning the same lib/schema.ts types. For example:
// today
export const documents = documentsJson as unknown as Document[];
// production
export async function getDocuments(caseId: string): Promise<Document[]> {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/cases/${caseId}/documents`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok) throw await toApiError(res);
return res.json();
}
Server Components await the getter; client providers (PortalProvider, ClinicProvider) are seeded from server responses instead of static imports. The types do not change, so no view component changes.