API Reference
The SightSync REST API lets you push patient records, trigger AI recall calls, and pull appointment outcomes — directly from your practice management system.
Authentication
All requests must include a valid API key in the Authorization header as a Bearer token. API keys are generated in Dashboard → Settings → API Keys.
Authorization: Bearer nvc_live_xxxxxxxxxxxxxxxxxxxx
Base URL
https://sightsync.cloud/api/v1
All endpoints use HTTPS. HTTP requests are redirected. Your API key authenticates to your practice account — all data is isolated by practice.
Rate limits
Each API key is limited to 120 requests per minute across all endpoints combined.
Exceeding the limit returns 429 Too Many Requests. The response includes a Retry-After header with the number of seconds to wait, and a reset ISO timestamp. Recall triggers additionally enforce UK calling regulations (see Compliance).
Errors
All error responses are JSON with an error string field.
| Status | Meaning |
|---|---|
| 400 | Bad request — missing or invalid fields |
| 401 | Unauthorised — invalid or missing API key |
| 402 | Payment required — subscription not active |
| 404 | Not found — patient or resource does not exist |
| 409 | Conflict — patient has opted out |
| 422 | Unprocessable — e.g. invalid UK phone number |
| 425 | Too early — outside OFCOM-permitted calling hours |
| 429 | Too many requests — rate limit or call cap reached |
| 451 | Unavailable for legal reasons — TPS/CTPS registered |
| 500 | Internal error — please report to dev@sightsync.cloud |
Patients
Add or update a patient
/patientsUpsert a patient recordCreates a new patient or updates an existing one if the phone number already exists for this practice. Conflict key: practice_id + phone_number.
Body parameters
| first_name* | string | Patient's first name. |
| last_name | string | Patient's surname. |
| phone_number* | string | UK mobile or landline. Accepted formats: 07700900000, +447700900000, 020 7946 0000. |
| string | Patient email address (optional). | |
| last_eye_test_date | date | ISO 8601 date of last eye examination. Used to calculate recall due date. |
| risk_category | string | One of: standard, diabetic, glaucoma_suspect, myopia_child, contact_lens, other_clinical. Defaults to standard. |
| clinical_notes | string | Free-text clinical notes passed to the AI for context. |
POST /api/v1/patients
Authorization: Bearer nvc_live_...
{
"first_name": "Jane",
"last_name": "Smith",
"phone_number": "07700900001",
"last_eye_test_date": "2024-01-15",
"risk_category": "diabetic"
}
// 200 OK
{
"success": true,
"patient": {
"id": "pat_01HXYZ...",
"first_name": "Jane",
"last_name": "Smith",
"phone_number": "+447700900001",
"risk_category": "diabetic",
"last_eye_test_date": "2024-01-15",
"next_clinical_due_date": "2025-01-15",
"opted_out": false,
"created_at": "2026-03-11T09:00:00Z",
"updated_at": "2026-03-11T09:00:00Z"
}
}List patients
/patientsList patients due for recallQuery parameters
| limit | integer | Max results to return. Default 100, max 500. |
| offset | integer | Pagination offset. Default 0. |
| risk_category | string | Filter by risk category. |
| overdue_only | boolean | If true, only return patients whose recall is past due. |
GET /api/v1/patients?overdue_only=true&risk_category=diabetic&limit=50
// 200 OK
{
"patients": [ ... ],
"total": 23,
"limit": 50,
"offset": 0
}Recall
Trigger a recall call
/recallTrigger an AI recall call for a patientInitiates a compliant AI voice call to the specified patient. The call is subject to OFCOM hours (Mon–Fri 9am–6pm UK), TPS/CTPS screening, 24h call spacing, and the practice's monthly call quota.
Returns 202 Accepted once the call has been dispatched to the telephony provider. Use the call_id to track status via webhooks.
Body parameters
| patient_id* | string | The patient's ID (returned by POST /patients). |
POST /api/v1/recall
Authorization: Bearer nvc_live_...
{ "patient_id": "pat_01HXYZ..." }
// 202 Accepted
{
"success": true,
"call_id": "c_01HABC...",
"patient_id": "pat_01HXYZ...",
"status": "calling"
}
// 425 — Outside OFCOM hours
{
"error": "Outside permitted calling hours",
"reason": "Calls permitted Mon–Fri 9am–6pm UK time only",
"next_allowed_at": "2026-03-12T09:00:00Z"
}
// 451 — TPS registered
{ "error": "Patient number is registered on the TPS/CTPS — call blocked per PECR regulations" }
// 429 — Monthly call quota
{ "error": "Monthly call limit reached", "calls_used": 300, "monthly_limit": 300 }Appointments
List appointments
/appointmentsList appointments booked via AI recallQuery parameters
| limit | integer | Max results. Default 100, max 500. |
| offset | integer | Pagination offset. Default 0. |
| status | string | Filter by status: booked | confirmed | cancelled | no_show. |
| from_date | date | ISO 8601 — appointments on or after this date. |
| to_date | date | ISO 8601 — appointments up to and including this date. |
| patient_id | string | Filter by a specific patient. |
GET /api/v1/appointments?from_date=2026-03-01&status=booked
// 200 OK
{
"appointments": [
{
"id": "apt_01H...",
"patient_id": "pat_01H...",
"appointment_date": "2026-03-15",
"appointment_time": "10:30",
"status": "booked",
"appointment_type": "routine_eye_exam",
"patients": {
"first_name": "Jane",
"last_name": "Smith",
"phone_number": "+447700900001",
"risk_category": "diabetic"
},
"created_at": "2026-03-11T09:15:00Z"
}
],
"total": 1,
"limit": 100,
"offset": 0
}Usage
Get usage stats
/usageCurrent billing period usageReturns quota consumption, overage, and a daily call breakdown for the current calendar month.
GET /api/v1/usage
// 200 OK
{
"period": { "start": "2026-03-01", "end": "2026-03-31" },
"plan": "practice",
"status": "active",
"calls": {
"used": 312,
"limit": 750,
"remaining": 438,
"overage": 0
},
"daily": [
{ "date": "2026-03-01", "total": 18, "completed": 15, "failed": 3 },
{ "date": "2026-03-02", "total": 24, "completed": 21, "failed": 3 }
]
}Compliance & regulations
The API automatically enforces UK telecommunications regulations on every recall trigger. You do not need to implement these checks yourself.
OFCOM permitted hours
Calls are only placed Monday–Friday, 9am–6pm UK time. Requests outside these hours return 425 with a next_allowed_at timestamp.
TPS / CTPS screening
Every number is checked against the Telephone Preference Service and Corporate TPS registers before a call is placed. Registered numbers return 451 and the patient is flagged in your dashboard.
24-hour call spacing
A minimum 24-hour gap is enforced between calls to the same patient. Requests that would violate this return 429 with a next_allowed_at ISO timestamp.
30-day call cap
No more than 3 calls are placed to any patient within a rolling 30-day window, per UK direct marketing guidance.
Opt-out handling
Patients who have opted out (via keypress during a call, SMS reply, or the opt-out portal) cannot be triggered. Attempts return 409.
Webhooks (coming soon)
Outbound webhooks deliver real-time call events to your endpoint — no polling required. Configure a webhook URL in Dashboard → Settings → Webhooks.
Events fired:
call.completed— call ended, includes transcript summary and outcomeappointment.booked— patient confirmed an appointment date/timepatient.opted_out— patient opted out during a call or via the portalcall.failed— call could not be placed (busy, no-answer, carrier error)