CareFlux API
A small REST API for building on top of a clinic running CareFlux — booking widgets, reporting tools, and integrations with whatever else the practice already uses.
This page documents what exists today. It is version 1, and it is deliberately narrow: six endpoints we can support properly rather than thirty we cannot.
Authentication
A clinic administrator creates a key under Settings → API keys. The raw key is shown once and never again — we store only its SHA-256 hash, so a leaked database backup does not leak working credentials.
curl https://your-careflux-domain/api/v1/me \ -H "Authorization: Bearer mfl_xxxxxxxxxxxxxxxx"
Every key belongs to exactly one clinic. There is no cross-clinic key, and no endpoint takes an organisation id — the key is the tenant.
Scopes
A key holds an explicit list of scopes and can do nothing outside them. Scopes marked patient data expose identifying health information — grant them only to systems that genuinely need them, and only for as long as they do.
Endpoints
/api/v1/meWhich clinic this key belongs to and what it can do.
Start here. Needs no scope — holding the key is the point.
Scope: none required
/api/v1/providersThe clinic's doctors and nurses.
Scope: api:read:providers
/api/v1/servicesServices offered, with prices in minor units.
price_minor is an integer — 150000 with currency PKR is Rs 1,500.00. Never a float.
Scope: api:read:services
/api/v1/appointmentspatient dataAppointments in a date range.
?from=&to= as ISO timestamps. Defaults to the next 7 days. 92 days maximum per call.
Scope: api:read:appointments
/api/v1/appointmentspatient dataBook an appointment for an existing patient.
Send client_reference to make the call safe to retry — the same reference always returns the same appointment instead of booking twice.
Scope: api:write:appointments
/api/v1/patientspatient dataFind a patient by MRN, national ID or full name.
Exact match only, and one of those three is required. There is no endpoint that lists every patient.
Scope: api:read:patients
Booking, safely
A booking request that times out is not necessarily a booking that failed. Send a client_reference you generate, and retry with the same value: the second call returns the appointment the first one created, with idempotent_replay: true.
curl -X POST https://your-careflux-domain/api/v1/appointments \
-H "Authorization: Bearer mfl_..." \
-H "Content-Type: application/json" \
-d '{
"patient_id": "019f...",
"provider_id": "019f...",
"starts_at": "2026-08-14T09:30:00Z",
"duration_minutes": 20,
"client_reference": "booking-4417"
}'If the provider is already busy at that time you get 409 slot_unavailable. That check is a database constraint, not application logic, so two simultaneous bookings for the same slot cannot both win.
Errors
Every failure has the same shape:
{ "error": { "code": "insufficient_scope", "message": "..." } }| Status | Code | Means |
|---|---|---|
| 401 | missing_key | No Authorization header, or the scheme was not Bearer. |
| 401 | invalid_key | Unknown, revoked, or wrong key. |
| 401 | key_expired | The key is past its expiry date. |
| 403 | ip_not_allowed | The key has an IP allowlist and you are not on it. |
| 403 | insufficient_scope | The key does not hold the scope this endpoint needs. |
| 429 | rate_limited | Too many requests this minute. Default is 120 per key. |
| 400 | missing_field | A required field was absent. |
| 404 | patient_not_found | No such patient in this clinic. |
| 409 | slot_unavailable | That provider is already booked at that time. |
Rate limits
120 requests per minute per key by default, in fixed one-minute windows. Over the limit you get 429 rate_limited. A clinic can raise the limit on a specific key if an integration genuinely needs more.
What we log
Every request — successful, refused, and unauthenticated — is recorded with the method, path, status, duration, IP and whether the endpoint returns patient data. The clinic can read that log.
We do not log request or response bodies. A body on a patient endpoint is patient data, and a log table is the last place it should accumulate.
Not in v1
Creating patients, clinical records, prescriptions, and billing are all absent, and that is a decision rather than a backlog item.
Patient creation in particular is where duplicate records come from — that is why bulk import goes through a staged review rather than a straight write. A booking integration that can silently mint patients will mint duplicates, and the clinic will find out months later.
If you need something that is not here, ask — a v1 that exposes everything is a v1 that can never change.