POST
/transactional-api/book-appointmentBook Appointment
Books an appointment for a patient into a specific diary slot. Use List Available Slots to obtain the diaryId, startTime, and endTime for a bookable slot.
Authorization: Bearer token (JWT). See Authentication.
Request
curl -L -X POST 'https://{tenantId}.api.england.medicus.health/transactional-api/book-appointment' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{
"patientId": "4d59c916-9726-11ec-af3f-0a58a9feac02",
"diaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"appointmentServiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"appointmentTypeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"startTime": "2026-01-15T09:00:00Z",
"endTime": "2026-01-15T09:20:00Z",
"reasonForAppointment": "Follow-up review of blood pressure medication.",
"additionalInformation": "Patient has requested a female clinician if possible.",
"embargoOverrideReason": "Urgent clinical need identified by triage.",
"gpadReportingExceptionReasons": [
"patient-preferred-an-appointment-on-a-future-date-or-at-a-specific-time"
]
}'
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
patientId | string<uuid> | Yes | Medicus patient identifier. |
diaryId | string<uuid> | Yes | Diary to book into. Returned by List Available Slots. |
appointmentServiceId | string<uuid> | Yes | Appointment service for the booking. Must match the service associated with the diary. |
appointmentTypeId | string<uuid> | Yes | Appointment type for the booking. |
startTime | string<date-time> | Yes | Slot start time (ISO 8601, UTC). Must match an available slot and must not be in the past. |
endTime | string<date-time> | Yes | Slot end time (ISO 8601, UTC). Must match the end time of the selected slot. |
reasonForAppointment | string (nullable) | No | Patient-supplied reason for the appointment. |
additionalInformation | string (nullable) | No | Additional information to include with the booking. |
embargoOverrideReason | string (nullable) | No | Reason for overriding a booking embargo, if the slot is embargoed. Required when the slot is embargoed. |
gpadReportingExceptionReasons | array<string> (nullable) | No | GPAD reporting exception reasons, required for certain appointment types. |
Responses
200 Appointment booked successfully.
Response fields
| Field | Type | Description |
|---|---|---|
appointmentId | string<uuid> | The newly created appointment identifier. |
{
"appointmentId": "00000000-0000-0000-0000-000000000000"
}
400 Validation error.
12 possible code values
| Code | Description | When |
|---|---|---|
invalid-patient-id | The patientId is not a UUID | patientId missing or not a UUID |
invalid-diary-id | The diaryId is not a UUID | diaryId missing or not a UUID |
invalid-appointment-service-id | The appointmentServiceId is not a UUID | appointmentServiceId missing or not a UUID |
invalid-appointment-type-id | The appointmentTypeId is not a UUID | appointmentTypeId missing or not a UUID |
invalid-start-time | The startTime is not a valid date/time format | startTime missing or not a valid date/time |
invalid-end-time | The endTime is not a valid date/time format | endTime missing or not a valid date/time |
start-time-in-the-past | The requested startTime is in the past. | startTime is before now |
invalid-gpad-reporting-exception-reason | 'some-value' is not a recognised GPAD reporting exception reason. | a value in gpadReportingExceptionReasons isn't recognised |
appointment-service-mismatch | The appointmentServiceId does not match the appointment service for this diaryId. | appointmentServiceId doesn't match the diary's or appointment type's actual service |
embargo-override-reason-required | The reason for overriding the booking embargo is required. | slot is embargoed and no embargoOverrideReason was supplied |
gpad-reporting-exception-reasons-required | At least one GPAD reporting exception reason is required when booking more than 14 days in advance. | startTime more than 14 days out, category eligible, no reason supplied |
validation-failed | This slot is no longer available. Please choose another. | the slot is already booked by another appointment |
Response fields
| Field | Type | Description |
|---|---|---|
errors[].code | string | |
errors[].description | string |
{
"errors": [
{
"code": "invalid-patient-id",
"description": "The patientId is not a UUID"
}
]
}
404 A referenced resource was not found (patient, diary, appointment type, or slot).
4 possible code values
| Code | Description | When |
|---|---|---|
patient-not-found | Patient not found for the id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 | patientId doesn't exist |
diary-not-found | Diary not found for this diaryId. | diaryId doesn't exist |
appointment-type-not-found | Appointment type not found for this appointmentTypeId. | appointmentTypeId doesn't exist |
slot-not-found | The requested startTime and endTime are outside the diary's scheduled hours for diaryId. | startTime/endTime fall outside the diary's hours, or don't align to a generated slot |
Response fields
| Field | Type | Description |
|---|---|---|
errors[].code | string | |
errors[].description | string |
{
"errors": [
{
"code": "patient-not-found",
"description": "Patient not found for the id: 3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
]
}