API & developers

Last updated: 19 September 2026

What it is for

Build your own booking front end, sync a diary, or connect a tool of yours, while MyNewClinic keeps the diary, the patient records and the clinical notes. Base URL: https://api.mynewclinic.com/api/v1

Authentication

Create a key in the staff app under Settings, Integrations, API keys. The key is shown once. Send it on every request:

Authorization: Bearer myc_live_xxxxxxxxxxxxxxxx

The key identifies the clinic. Keys have a scope, read or read and write. JSON in, JSON out. Limit: 300 requests a minute per key. Times are ISO 8601 with an offset, for example 2026-10-01T09:30:00+01:00.

Errors come back as { "error": "message" } with 400 (bad input), 401 (bad key), 402 (subscription inactive), 403 (scope), 404, 409 (clash) or 429 (rate limit).

The booking flow in five calls

  1. GET /appointment_types for the services and prices.
  2. GET /practitioners for who does them.
  3. GET /availability?practitioner_id=…&appointment_type_id=…&from=2026-10-01&days=7 for live slots.
  4. POST /patients with the patient's details. It returns the existing patient when the email or phone already matches, so you never create duplicates.
  5. POST /appointments with the patient, practitioner, type and start time. The slot is checked again at booking, so two people cannot take it.

Then PATCH /appointments/{id} to move it and POST /appointments/{id}/cancel to cancel. The patient gets the same emails and reminders as a booking made in the app.

Patients

GET/patients?q=smithread

Also ?email= or ?phone=. Returns { patients: [...] }, up to 100.

GET/patients/{id}read

One patient.

POST/patientswrite

Body: first_name, last_name (required), email, phone.

Returns { patient, created }: 201 when created, 200 when matched on email, then phone. Matching is never by name.

Practitioners and services

GET/practitionersread

Active practitioners: { practitioners: [{ id, first_name, last_name, profession, practitioner_appointment_types: [{ appointment_type_id }] }] }. The last field says which services each one offers.

GET/appointment_typesread

The services a patient can book online, as set in the app (group classes are not in this API): { appointment_types: [{ id, name, description, duration_minutes, price_pence }] }.

Availability

GET/availabilityread

Query: practitioner_id, appointment_type_id, from (date), optional days (1 to 31, default 7) and location_id.

Returns { slots: [{ starts_at, ends_at, location_id }] }, honouring the practitioner's hours, breaks, existing bookings, the type's duration and any windows reserved for certain services.

Appointments

GET/appointments?from=&to=&patient_id=&practitioner_id=read

from and to are ISO datetimes.

POST/appointmentswrite

Body: practitioner_id, appointment_type_id, patient_id, starts_at (required), optional notes, location_id, discount_code, send_confirmation (true to email the patient the standard confirmation).

201 with { appointment, discount, discount_error }. 409 when the slot is taken or outside the practitioner's offered times.

PATCH/appointments/{id}write

Body: any of starts_at, practitioner_id (moves the appointment: clash check, reminders rescheduled, patient and practitioner told), notes, location_id. Returns { appointment }. 409 on a clash; an appointment already marked arrived cannot be moved by the API.

POST/appointments/{id}/cancelwrite

Body: optional reason. Drops reminders, tells the patient and the practitioner, offers the slot to the wait list.

POST/validate_coderead

Body: code, appointment_type_id, practitioner_id. Checks a discount code without using it.

Clinical notes

GET/treatment_notes?patient_id=read

A patient's notes.

POST/treatment_noteswrite

Creates a draft SOAP note. Notes are clinical records; only request this scope if your tool needs it.

Webhooks

Under Settings, Integrations, Webhooks, add an HTTPS URL and pick events:

appointment.created   appointment.updated   appointment.cancelled
patient.created       treatment_note.created   invoice.paid

Each delivery is a JSON POST with { event, clinic_id, data, sent_at }, an X-MyNewClinic-Event header naming the event and an X-MyNewClinic-Signature header, an HMAC-SHA256 of the raw body with your webhook secret. Reply 2xx within 10 seconds. Every delivery and its status is logged on the Integrations page.

Good to know

  • Everything is scoped to the clinic that owns the key. There is no cross-clinic access.
  • The public booking page at book.mynewclinic.com/your-clinic uses the same rules as this API, so the two never disagree on a slot.
  • Patient data is health data under UK GDPR. Store the key like a password, use the read scope where write is not needed, and rotate the key from the same settings page if it is ever exposed.
  • Questions or a missing endpoint: hello@mynewclinic.com. Ask and it usually appears.