The ICE APIs allow integration with the Healthcode ICE service (Integrated Channel Exchange), which provides a global distribution system (GDS) for managing patient appointments.
Getting started
General aspects of integrating with Healthcode APIs, like authentication and authorisation, naming conventions, data formatting assumptions, error handling requirements, etc. are documented here.
Pay special attention to the aspects of using discovery document, the need to specify site id within the request headers, and the need to specify the exact API version.
Also, be certain you are connecting to the correct environment. If you are trying to integrate into our sandbox (UAT) environment, read instructions here first to understand the requirements.
Some of the real-world integration scenarios are documented in the Workflows document here.
Where this document refers to {ice_URL}, this should be replaced with the relevant URL taken from the discovery document. And where the document refers to {ref_URL}, it should be replaced with the relevant URL from Reference/Master Data APIs.
Individual API definitions below contain a sample request and response messages where applicable. Further code samples are available in the form of a Postman™ collection, which is available to download from here.
Schedule
The Schedule resource handles the availability and non-availability of service and practitioners at a specific location and is a container for time-slots that can be booked using an appointment. Following APIs enable operating against the resource.
Create schedule
Endpoint
Must be looked up from the discovery document using key create_schedule_endpoint.
Request
This API accepts a Schedule resource as input. The high-level structure of the Schedule resources is set out below.
curl --request POST
--url '{create_schedule_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
--data-raw '
{
"resourceType":"Schedule",
"contained":[
{
"resourceType": "HealthcareService",
"extraDetails": "Patient must not eat after midnight, no drinking after 7am",
"availableTime": [
{
"daysOfWeek": [
"fri"
],
"allDay": false,
"availableStartTime": "14:00:00",
"availableEndTime": "16:00:00"
}
],
"NotAvailable":[
{
"description":"reason for non availability",
"during":{
"start":"2023-02-10T18:30:00+00:00",
"end":"2023-02-11T09:30:00+00:00"
}
}
],
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"display":"Third Party Channel",
"identifier":{
"id":"blockPermission",
"value":"booking"
}
}
},
{
"url":"{ref_URL}/extension/frontLoading",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/backLoading",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/allowInPersonAppointment",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/allowRemoteAppointment",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/maximumPatientAge",
"valuePositiveInt":70
},
{
"url":"{ref_URL}/extension/minimumPatientAge",
"valuePositiveInt":18
},
{
"url": "https://ref.api.healthcode.co.uk/extension/bookingNoticeHours",
"valuePositiveInt": 48
},
{
"url": "https://ref.api.healthcode.co.uk/extension/communicationLanguages",
"valueString": "eng,fra"
}
],
"serviceCategory":{
"coding":[
{
"system": "{ref_URL}/valueset/service-category/ISC",
"code":"7600000000",
"display": "Orthopaedic"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
},
{
"coding": [
{
"system": "{ref_URL}/valueset/practitioner-subspecialty/ISC",
"code": "0000L",
"display": "Hip"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
}
],
"identifier": [
{
"use": "usual",
"system": "https://pms/identifier/uid",
"value": "012992"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule. New patients must bring GP referral letter."
}
Where,
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
Start | Period.date | 1-1 | First date on which the Schedule will be applied. (Time element is ignored; should be passed as “T00:00:00+00:00 “) | Schedule.planningHorizon.period.start |
End | Period.date | 1-1 | Last date on which the Schedule will be applied (Time element is ignored; should be passed as “T00:00:00+00:00 “) | Schedule.planningHorizon.period.end |
Specialty | CodeableConcept | 1-* | Specialty and (optionally) sub-specialty of the services provided in the schedule. Multiples of each can be recorded if required. | Schedule.specialty.codeableConcept.code use {ref_URL}/valueset/practitioner-specialty/ISC and {ref_URL}/valueset/practitioner-subspecialty/ISC |
Service Category | CodeableConcept | 0-1 | This is the category of the service present in the Schedule, not the actual service itself | Schedule.serviceCategory.codeableConcept.code {ref_URL}/valueset/service-category/ISC |
Service Type | CodeableConcept | 0-1 | This is the actual service that will be available during the scheduled period, (such as “Initial Consultation”, “Follow-up Consultation”, “Blood Test”, etc) | Schedule.serviceType.codeableConcept.code {ref_URL}/valueset/service-type/ISC |
Practitioner | Reference | 1-1 | The person who will be performing the services in the scheduled period. This is the practitioner’s “SP” reference number. | Schedule.actor.Reference.value{Practitioner} |
Location | Reference | 1-1 | The treatment site or the location where the service will be performed by the practitioner. (*) See note below. | Schedule.actor.Reference.value{Location} |
Healthcare Service | Reference | 1-1 | Healthcare Service provided in the schedule | Schedule.actor.Reference.value{HealthcareService} |
extraDetails | String | 0-1 | Extra details that the patient MUST be made aware of about this service | Schedule.contained.HealthcareService.extraDetails |
Telecom | ContactPoint | 0-* | Telecom services like phone/email/url provided as contact details in case of queries with this schedule or it’s appointments. This field is optional, but highly recommended. If an email address is specified, it MUST be a valid address. (NOTE: The “period” element is not currently supported) | Schedule.contained.HealthcareService.telecom |
Available Time | BackboneElement | 1-* | Healthcare Service Availability. Note that the "availableStartTime" :"hh:mm:ss" and "availableEndTime":"hh:mm:ss" must align to whole minutes. (ie, seconds MUST be “:00”). Times are specified in LOCAL time at the location where the service will be performed. "allDay":true can be used instead to specify full 24 hour period. (allDay cannot be true if also using availableStartTime/ availableEndTime) | Schedule.contained.HealthcareService.availableTime |
Not-available | BackboneElement | 0-* | Healthcare Service Non-Availability | Schedule.contained.HealthcareService.notAvailable |
Channel | extension | 0-* | Channels with restrictions to search/book permissions for slots within schedule.(see blockPermissions below) | Schedule.Extension.referenceValue URL = {ref_URL}/extension/channel |
Front Loading | extension | 0-1 | If frontLoading is true, appointments must be filled from the FIRST available slot forwards leaving no gaps. (default is false ) | Schedule.Extension.valueAsBoolean URL = {ref_URL}/extension/frontLoading |
Back Loading | extension | 0-1 | If backLoading is true, appointments must be filled from the LAST available slot backwards, leaving no gaps. (default is false ) | Schedule.Extension.valueAsBoolean URL = {ref_URL}/extension/backLoading |
Is walkin | extension | 0-1 | Is walkin Slot (walk-in allowed) (default is false ) | Schedule.Extension.valueAsBoolean URL = {ref_URL}/extension/isWalkin |
Allow In-Person Appointment | extension | 0-1 | Does this schedule allow for in-person appointments (ie, physical face-to-face) (default is true ) | Schedule.Extension.valueAsBoolean URL = {ref_URL}/extension/allowInPersonAppointment |
Allow Remote Appointment | extension | 0-1 | Does this schedule allow for remote appointments? (ie, video consultations) (default is false ) | Schedule.Extension.valueAsBoolean URL = {ref_URL}/extension/allowRemoteAppointment |
Minimum patient age | extension | 0-1 | Minimum patient age accepted – range 0 to 150 yrs (default is 0) | Schedule. Extension.valueAsInt URL ={ref_URL}/extension/minimumPatientAge |
Maximum patient age | extension | 0-1 | Maximum patient age accepted – range 0 to 150 yrs (default is 150) | Schedule. Extension.valueAsInt URL ={ref_URL}/extension/maximumPatientAge |
Booking Notice Hours | extension | 0-1 | Minimum number of hours prior to appointment start time that the appointment can be booked – range 0 to 1500 hours. (default is 24 hours). Note that these are “actual” hours, not “business hours”, and so do not take into consideration weekends/public holidays/etc) | Schedule. Extension.valueAsInt URL ={ref_URL}/extension/bookingNoticeHours |
Communication Languages | extension | 0-1 | List of languages that the practitioner is able to communicate using. Default is “eng” (English) if not specified. Codes must comply with ISO-693-3 (3 letters each) and can be comma-separated if multiple languages are specified. | Schedule. Extension.valueAsInt URL ={ref_URL}/extension/communicationLanguages |
Slot Duration | extension | 1-1 | Slot duration (in minutes) NOT including any admin interval. | Schedule. Extension.valueAsInt URL ={ref_URL}/extension/slotDuration |
Admin Interval | extension | 0-1 | Admin interval (in minutes) – Period of time to be left between appointments for administrative activities. | Schedule.Extension.valueAsInt URL = {ref_URL}/extension/adminInterval |
Estimated Price | extension | 0-1 | Estimated price in £GBP for service | Schedule.Extension.valueAsDecimal URL = {ref_URL}/extension/estimatedPrice |
Booking Limit | extension | 0-1 | Booking limit – Maximum number of patients able to book into ONE slot, such as group classes (default=1) | Schedule.Extension.valueAsInt URL ={ref_URL}/extension/bookingLimit |
Comment | StringType | 0-1 | Comments/notes to make booking party aware of before making bookings. | Schedule.comment |
Identifier | Resource | 0-* | One or more identifiers supplied by 3rd parties to help track this Schedule |
Each Schedule can have only one HealthcareService, Practitioner, and Location resource enriched.
As per FHIR specifications for a Schedule, “A schedule controls the dates and times available for the performance of a service and/or the use of a resource. One schedule applies to one service or resource, since each service or resource can be reserved independently of the others.”
Because of this, if different types of service are to be offered within the same time period, then a different schedule should be created for each service type.
(*) “Location” is the HP number that defines the physical address where the service will be carried out by the practitioner. This location MUST be listed in the practitioner’s PPR record, otherwise it will be rejected. This check is to ensure that practitioners only conduct services at locations where they have been authorised to work from. If they are performing remote/virtual consultations from within a hospital, that hospital should be still be specified as the treatment location. The only exception to this rule is when Healthcode publish one or more “Remote Location” HP codes for when a practitioner conducts consultations from home. These special remote codes do not need to be present in the PPR record, and will be accepted by ICE.
“Walk-in” sessions are returned as a single slot for the entire session rather than being broken down into individual appointments of ‘x’ minutes. This can be used in conjunction with the “Booking Limit” setting to control how many people can use the walk-in facility.
Use cases around specifying practitioner availability
Use case | Field mapping description |
---|---|
Practitioner provides services weekly on a specific day (e.g. Monday). | Use schedule.Healthcareservice.availableTime.daysOfWeek[] to specify the days of week the practitioner is available. If the planning horizon dates span for more than one week, the days specified will recur for every occurrence of those days that fall within the planning horizon (see note below). |
Practitioner is available for the full day on a specific day of week. | Set field schedule.Healthcareservice.availableTime.allDay to true to specify the full 24hr period of availability. By default, this field is false if not specified. |
Practitioner is available for a few hours in a day. | Use fields schedule.Healthcareservice.availableTime.availableStartTime and schedule.availableTime.availableEndTime to define the period of availability. |
Schedule needs to be for a specific period. | Use fields schedule.planningHorizon.start and schedule.planningHorizon.end to define the date range where this schedule period is applied. |
Define multiple timings for different days of the week in a schedule. | Use schedule.availableTime[] to add multiple availability records. Each record can have different days and timings. |
Specific instructions to make the patient aware of before booking this slot. | Use schedule.contained[].HealthcareService(ResourceType).extraDetails field to set the instructions as StringType. For example, “GP referral letter must be brought to the appointment.” |
If you are creating a recurring schedule (one with a planning horizon that spans more than a week) from a PMS (Practice Management System) it’s STRONGLY advised that you allow your PMS to handle the recurrense, and to create a new schedule for each week. This allows your PMS to manage exceptions such as public holidays.
Use cases around specifying the slot configurations in a schedule
Slot configuration should be defined in a schedule as extensions.
Use case | Field mapping description |
---|---|
Specify a slot duration as 20 mins. | Use extension slotDuration to set the duration of each slot in the schedule. |
Specify that there should be a gap of 10 mins between slots in the schedule. | Use extension adminInterval to set the interval between slots in the schedule. |
Each day in the schedule should allow patients on first come first serve basis in a specific period of the day. | Define the slots of the service as Walkin . Use isWalkin extension. |
Specify maximum bookings per slot in the schedule. | Use extension bookingLimit to set the maximum number of bookings that can be made per slot for the service. ie, a gym session may be able to accommodate 20 people in the class, so will have a booking limit of 20. After 20 bookings are made into that slot, further bookings will be rejected. This should be set to 1 for normal one-on-one appointments. (For existing appointments, the AppointmentCount field gives the number of bookings currently made into that slot.) |
Use cases around specifying slot visibility and access levels / blockPermissions
Use case | FHIR field mapping description |
---|---|
Specify permission restrictions on schedule by third-party channels. | Use the field schedule.extension.channel to set the unique identifier of the channel for which this configuration applies. These channel ID can be found from the Search Channel API |
Specify which channel should be restricted from booking the slots of the schedule. | Use the field schedule.extension.identifier to set the property blockPermission to booking where extension.reference=’channel’ . |
Specify if the channel can search the slots but not be allowed to book the slots in the schedule. | Use the field schedule.extension.identifier to set the property blockPermission to search where extension.reference=’channel’ . |
Example code which prevents the specified channel from being able to view or make bookings:
"extension":[ { "url":"{ref_URL}/extension/channel", "valueReference":{ "reference":"Channel/202101062126122282KE30000", "display":"Third Party Channel", "identifier":{ "id":"blockPermission", "value":"booking" } } } ]
When a schedule is created with no channels specified in the request, all channels registered with the ICE service will be able to make bookings into this schedule.
Response
On successful creation of the schedule, the API returns the instance of the persisted Schedule resource with a new unique id enriched. The integrating systems should store the id value to be able to update or cancel the schedule at a later point in time.
{
"resourceType":"Schedule",
"id":"202102011418269561T1t0030",
"contained":[
{
"resourceType":"HealthcareService",
"id":"202102011418269001Ncb0028",
"type":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"extraDetails":"Fasting required for 3 hrs before appointment",
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
"availableTime":[
{
"daysOfWeek":[
"tue"
],
"allDay":false,
"availableStartTime":"14:00:00",
"availableEndTime":"16:00:00"
}
],
"notAvailable":[
{
"id":"202102011418269561T1b2332",
"description":"reason for non availability",
"during":{
"start":"2023-02-10T18:30:00+00:00",
"end":"2023-02-11T09:30:00+00:00"
}
}
]
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"identifier":{
"id":"blockPermission",
"value":"booking"
},
"display":"Third Party Channel"
}
},
{
"url":"{ref_URL}/extension/frontLoading",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/backLoading",
"valueBoolean":false
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
},
{
"url": "https://ref.api.healthcode.co.uk/extension/communicationLanguages",
"valueString": "eng,fra"
}
],
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"202102011418269561T1t0030"
}
],
"serviceCategory":{
"coding":[
{
"code":"7600000000"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
},
{
"reference":"HealthcareService/#202102011418269001Ncb0028",
"display":"Consultation, Initial"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule setup"
}
Where,
Field | Type | Description |
---|---|---|
Schedule.id | String | Schedule ID |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
400 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
400 | INVALID_RESOURCE | Schedule resource is not valid |
400 | MSG_CANT_PARSE_CONTENT | Schedule failed to process |
422 | MSG_CANT_TRANSFORM_CONTENT_TO_ENTITY | Failed to read service category from FHIR |
422 | RESOURCE_NOTT_FOUND_TEXT | Requested resource does not exist in booking system |
422 | DATA_INCONSISTENCY | Submitted resource is inconsistent with the data in booking system |
403 | UNAUTHORISED | Request authorisation failed |
Update Schedule
Endpoint
Must be looked up from the discovery document using key update_schedule_endpoint.
Request
This API accepts a Schedule resource as input. You should always use an instance obtained from either the Get Schedule or Search Schedules APIs as base for forming the input for the update call, to avoid any unintended errors or data omissions.
curl --request PUT
--url '{update_schedule_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
--data-raw '
{
"resourceType":"Schedule",
"id":"202102011418269561T1t0030",
"contained":[
{
"resourceType":"HealthcareService",
"id":"202102011418269001Ncb0028",
"type":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"extraDetails":"Fasting required for 3 hrs before appointment",
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
"availableTime":[
{
"daysOfWeek":[
"tue"
],
"allDay":false,
"availableStartTime":"14:00:00",
"availableEndTime":"16:00:00"
}
],
"notAvailable":[
{
"description":"reason for non availability",
"during":{
"start":"2023-02-10T18:30:00+00:00",
"end":"2023-02-11T09:30:00+00:00"
}
}
]
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"identifier":{
"id":"blockPermission",
"value":"booking"
},
"display":"Third Party Channel"
}
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
}
],
"active":true,
"serviceCategory":{
"coding":[
{
"code":"7600000000"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
},
{
"reference":"HealthcareService/#202102011418269001Ncb0028",
"display":"Consultation, Initial"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule setup"
}
Extending available-time of a schedule or adding unavailability to the schedule is only accepted when it does not conflict with any slots already booked under the specific schedule.
Response
On successful update of the schedule, the API will return the updated schedule resource.
{
"resourceType":"Schedule",
"id":"202102011418269561T1t0030",
"contained":[
{
"resourceType":"HealthcareService",
"id":"202102011418269001Ncb0028",
"type":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"extraDetails":"Fasting required for 3 hrs before appointment",
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
"availableTime":[
{
"daysOfWeek":[
"tue"
],
"allDay":false,
"availableStartTime":"14:00:00",
"availableEndTime":"16:00:00"
}
],
"notAvailable":[
{
"id":"202102011418269561T1b2332",
"description":"reason for non availability",
"during":{
"start":"2024-02-10T18:30:00+00:00",
"end":"2024-02-11T09:30:00+00:00"
}
}
]
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"identifier":{
"id":"blockPermission",
"value":"booking"
},
"display":"Third Party Channel"
}
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
}
],
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"202102011418269561T1t0030"
}
],
"active":true,
"serviceCategory":{
"coding":[
{
"code":"7600000000"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
},
{
"reference":"HealthcareService/#202102011418269001Ncb0028",
"display":"Consultation, Initial"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule setup"
}
ICE service uses a volatile id for the notAvailable resource. Accordingly, the id value of the resource may change during each update transaction, even if the resource itself had no changes during the update.
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_OP_NOT_ALLOWED | Slots are already in use, cannot delete schedule |
400 | INVALID_GDS_USERID | GDS UserID Invalid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
422 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
Delete Schedule
The Delete Schedule API enables submitting delete requests for existing schedules.
Delete schedule is not possible if any active bookings exist for the schedule. To delete a schedule all the appointments need to be cancelled first.
Endpoint
Must be looked up from the discovery document using key delete_schedule_endpoint.
Request
A sample DELETE request for deleting a schedule is provided below.
curl --request DELETE
--url'{delete_schedule_endpoint}/{schedule.id}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
Schedule id | String | M | Schedule that has to be removed from the system |
Response
On successful deletion of the schedule, the status of the schedule is returned using OperationOutcome resource as a response to API.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"coding": [
{
"system": "{ref_URL}/identifier/schedule",
"code": "202105251948504691o3F1264",
"display": "MSG_DELETED"
}
]
},
"diagnostics": "schedule deleted",
"location": [
"Schedule"
],
"expression": []
}
]
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
422 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
Get Schedule
The Get Schedule API can be used to retrieve a single schedule instance for a known id.
Endpoint
Must be looked up from the discovery document using key get_schedule_endpoint.
Request
A sample GET request for this is shown below.
curl --request GET
--url '{get_schedule_endpoint}/{schedule.id}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Response
If a schedule instance was found matching the supplied id, the API returns the corresponding schedule resource.
{
"resourceType":"Schedule",
"id":"202102011418269561T1t0030",
"contained":[
{
"resourceType":"HealthcareService",
"id":"202102011418269001Ncb0028",
"type":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"extraDetails":"Fasting required for 3 hrs before appointment",
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
"availableTime":[
{
"daysOfWeek":[
"tue"
],
"allDay":false,
"availableStartTime":"14:00:00",
"availableEndTime":"16:00:00"
}
],
"notAvailable":[
{
"id":"202102011418269561T1b2332",
"description":"reason for non availability",
"during":{
"start":"2024-02-10T18:30:00+00:00",
"end":"2024-02-11T09:30:00+00:00"
}
}
]
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"identifier":{
"id":"blockPermission",
"value":"booking"
},
"display":"Third Party Channel"
}
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
}
],
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"202102011418269561T1t0030"
}
],
"active":true,
"serviceCategory":{
"coding":[
{
"code":"7600000000"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
},
{
"reference":"HealthcareService/#202102011418269001Ncb0028",
"display":"Consultation, Initial"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule setup"
}
Search Schedules
The Search Schedule API enables searching for schedules using different filter criteria.
This API is not for finding availability for booking appointments. Instead, the integrating systems should use the Search Slots API.
Endpoint
Must be looked up from the discovery document using key search_schedule_endpoint.
Request
A sample GET request for searching the Schedule is provided below. Please note that the example request below is intentionally exaggerated to show all optional parameters – typical requests from integrating systems are expected to normally use only a subset of the parameters during a given transaction.
curl --request GET
--url '{search_schedule_endpoint}?
practitioner=SP09000&
location=HP005000&
start-date=2024-11-06T00:00:00&
end-date=2024-12-26T00:00:00&
service-category=7600000000&
specialty=0003A&
available-day=mon,tue,fri,sun&
near=51.406607:-0.493937:20:km&
address-postalcode=W1H 3DA&
estimated-price=le100.00&
service-type=E0000610&
available-start-time=14:30:00&
allow-remote-appointment=false&
allow-in-person-appointment=true&
_since=2024-03-01T09:00:00&
_sort=start&
_include=practitioner,location&
_summary=true&
page=1&
count=10'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw ''
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
practitioner | String | O | Practitioner for the schedule |
location | String | O | Location for the schedule |
start-date | String | O | Date when the schedule starts |
end-date | String | O | Date when the schedule ends |
id | String | O | The schedule id |
service-category | String | O | Category of the service |
specialty | String | O | Type of specialty associated with this schedule |
available-day | String | O | Day(s) of the week to include. Possible values are mon , tue , wed , thu , fri , sat , sun (always lower case). Multiple days of the week can be specified (each separated by a comma and no spaces), to search for different days. |
near | String | O | Latitude and longitude of the location (in Decimal Degrees, excluding degree symbol), search radius (distance) and units of distance. Each parameter (including latitude and longitude) should be separated by either a colon ‘:’ or pipe symbol “|”. Valid units are “mi ” or “mi_us ” (miles), “km ” (kilometres), “m “(meters). If units aren’t specified, “km” is assumed. If no distance is specified, 33 is assumed. |
address-postalcode | String | O | Postcode of location where service is available |
estimated-price | String | O | Estimated price of the service. Supports le (less than or equal to) and ge (greater or equal) and ap (approximately, +/- 10%). Schedules with NO price specified by the owner will NOT be included if estimated-price search is used. |
service-type | String | O | Service provided by the schedule |
allow-remote-appointment | boolean | O | if true, only return schedules that are marked as allowing remote appointments (virtual consultation). If not specified, all slots will be returned regardless of allow-remote-appointment value. |
allow-in-person-appointment | boolean | O | If true, only return schedules that are marked as allowing in-person (face-to-face) appointments. If not specified, all slots will be returned regardless of allow-in-person-appointment value. |
_sort | String | O | Sort results by start/end. Use _sort=start to sort results on start date in ascending order, or _sort=-start for descending order |
_include | String | O | Tell the API to include Practitioner or Location resource in the result |
_summary | String | O | Tell API to return only summary fields in response. |
page | String | O | Page index to be fetched {1,2,3..} |
count | String | O | Maximum records in a page |
available-start-time | String | O | Start time of availability |
_since | String | O | Last Updated datetime of records |
Response
The API returns a list of schedules in response.
{
"resourceType":"Bundle",
"meta":{
"tag":[
{
"code":"count",
"display":"1"
},
{
"code":"page",
"display":"1"
},
{
"code":"maxCount",
"display":"12"
}
]
},
"type":"searchset",
"total":1,
"entry":[
{
"resource":{
"resourceType":"Schedule",
"id":"202102011418269561T1t0030",
"contained":[
{
"resourceType":"HealthcareService",
"id":"202102011418269001Ncb0028",
"type":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"extraDetails":"Fasting required for 3 hrs before appointment",
"telecom":[
{
"system":"phone",
"value":"020 7789 0123",
"use":"work"
},
{
"system":"url",
"value":"https://onlineconsultation.com",
"use":"work"
}
],
"availableTime":[
{
"daysOfWeek":[
"tue"
],
"allDay":false,
"availableStartTime":"14:00:00",
"availableEndTime":"16:00:00"
}
],
"notAvailable":[
{
"id":"202102011418269561T1b2332",
"description":"reason for non availability",
"during":{
"start":"2024-02-10T18:30:00+00:00",
"end":"2024-02-11T09:30:00+00:00"
}
}
]
}
],
"extension":[
{
"url":"{ref_URL}/extension/channel",
"valueReference":{
"reference":"Channel/202101062126122282KE30000",
"identifier":{
"id":"blockPermission",
"value":"booking"
},
"display":"Third Party Channel"
}
},
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":10
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":150.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":15
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
}
],
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"202102011418269561T1t0030"
}
],
"active":true,
"serviceCategory":{
"coding":[
{
"code":"7600000000"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000610",
"display":"Consultation, Initial"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"actor":[
{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
},
{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
},
{
"reference":"HealthcareService/#202102011418269001Ncb0028",
"display":"Consultation, Initial"
}
],
"planningHorizon":{
"start":"2024-02-10T00:00:00+00:00",
"end":"2024-02-20T00:00:00+00:00"
},
"comment":"Sample schedule setup"
}
}
]
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
422 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
Slot
Slot resources are used to provide time slots that an appointment can be booked into, as defined by the published schedules. Following APIs enable operating against the resource.
Search Slots
Endpoint
Must be looked up from the discovery document using key search_slots_endpoint.
Request
A sample GET request searching for slots is below. Please note that this example is hugely exaggerated to include many more optional parameters than would normally be used in a single request.
curl --request GET
--url '{search_slots_endpoint}?
date-from=2024-12-10&
date-to=2024-12-20&
practitioner=SP09002&
last-name=Smith&
first-name=Martina&
gender=female&
service-type=E0000640&
location=HP005002&
service-category=1400000000&
specialty=00032&
subspecialty=0000M&
schedule=SC1&
near=51.406607:-0.493937:20:mi&
first-available-slot-only=true&
in-person-appointment=true&
remote-appointment=true&
estimated-price=le140.00&
patient-age=25&
duration=ge30&
available-day=wed,thu,fri,sat&
available-start-time=09:00:00&
available-end-time=11:00:00&
communication-language=eng&
_sort=start& (-start for descending order)
_include=schedule&
_revinclude=practitioner:schedule&
_revinclude=location:schedule&
_revinclude=healthcareservice:schedule&
_summary=true&
page = 1&
count=10'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Where,
Name | Type | Mandatory/ Optional | Description |
---|---|---|---|
date-from | String | M | Start date from when the slots need to be retrieved (Note: Any slots prior to “now” will NOT be included in the results, as it’s not possible to book an appointment for past dates/times) |
date-to | String | M | End date up to when the slots need to be retrieved. If a date in the past is specified, today’s date will be used instead. |
location | String | O (#) | Location code(s) where the service is to be performed. Multiple location codes can be specified, comma separated. |
practitioner | String | O | Practitioner(s) who will be performing the services. Multiple practitioner IDs can be specified, comma separated. The practitioner ID is also known as their “SP” number, and takes the format “SPnnnnnn” |
profession (*) | String | O | Profession (practitioner-role) code |
specialty | String | O | Specialty (practitioner-specialty) code for the type of practitioner you wish to find. |
subspecialty | String | O | Sub-specialty code (practitioner-subspecialty)for the type of practitioner you wish to find. |
last-name (*) | String | O | Last name of the practitioner |
first-name (*) | String | O | First (given) name of the practitioner |
gender (*) | String | O | Practitioner’s gender – options male /female /other /unknown |
service-type | String | O | The service-type code being provided by the Schedule |
schedule | String | O | Schedule ID that this Slot belongs to |
duration | String | O | Required appointment duration in minutes. If specified, must be an integer value between 1 and 1440 minutes. It can be prefixed with “le ” (less than or equal to), “ge ” (greater or equal to), “ap ” (approximate to within +/- 10%), or “eq ” (exactly equal to). example: “ge15 “. If a prefix is NOT specified, “eq ” is assumed and results will only include slots exactly equal to the number of minutes specified. |
service-category | String | O | Service Category ID used while creating the Schedule |
communication-language | String | O | If specified, this must contain a single 3-character ISO 639.3 code for a “living” language. Only slots where the practitioner has published a matching language will be returned. |
near | String | O (#) | Latitude and longitude of the location (in Decimal Degrees, excluding degree symbol), search radius (distance) and units of distance. Each parameter (including latitude and longitude) should be separated by a either a colon ‘:’ or pipe symbol “|”. Valid units are “mi ” or “mi_us ” (miles), “km ” (kilometres), “m “(meters). If units aren’t specified, “km” is assumed. If no distance is specified, 33 is assumed. [Note: use “_revinclude:location ” and “near ” to include the coordinates of each location along with the exact distance in the results] |
first-available-slot-only | String | O | If “true “, only the first available slot for each service-type for each practitioner will be returned. Default=false (ALL available slots returned) |
_include | String | O | Tell the API to include additional resources in the results. Currently, the only option is ‘schedule ‘. |
_summary | String | O | If ‘true ‘ the API only returns summary fields in the results. This also overrides requests for both _include and _revinclude, and returns only minimal fields. (Default = false ) |
estimated-price | String | O | The estimated price of service. Supports prefixes ‘le ‘ (less than or equal to), ‘ge ‘ (greater than or equal to) or ‘ap ‘ (approximately, +/-10%). Services with NO price specified by the owner will NOT be included if estimated-price search is used. |
available-day | String | O | Search for days of the week. Possible values are mon , tue , wed , thu , fri , sat , sun (always lowercase). Multiple days of the week can be specified (each separated by a comma and no spaces), to search for different days. |
available-start-time | String | O | Search for slots where the start time is greater or equal to available-start-time |
available-end-time | String | O | Search for slots where the end time is greater or equal to available-end-time |
in-person-appointment | Boolean | O | If true, only slots marked as being available for in-person (face-to-face) appointment will be returned. If false, in-person appointments will be excluded. If not specified, the in-person-appointment value is ignored. |
remote-appointment | Boolean | O | If true, only slots marked as being available for in-person (face-to-face) appointments will be returned. If false, in-person appointments will be excluded. If not specified, the in-person-appointment value is ignored. |
patient-age | Integer | O | If specified, only slots that permit the specified patient age to be booked will be returned. |
_sort | String | O | Sort slot list according to a specified field. Use “_sort=start ” to sort results on start date in ascending order, or “_sort=-start ” for descending order. Also end and -end |
_revinclude | String | O | Tell the server to also include additional resources matching the search criteria. Options are Practitioner , Location , and HealthcareService . |
page | String | O | Page index to be fetched {1,2,3..} |
count | String | O | Maximum number of records to be returned in a single page |
NOTES:
- Search parameters marked with “(*)” indicate that these criteria are fields which are not directly recorded within a Slot. To use these fields, ensure that “_include=practitioner” or “_revinclude=practitioner” is used so that the fields are included in the results, and are therefore searchable.
- Search parameters marked with “(#)” are mutually exclusive; you can not specify exact location codes AND geographic coordinates.
As with all search APIs, the time taken to process the request may vary hugely depending on the parameters used for the search, and therefore, the number of results returned. Care should be taken to tailor your search parameters to return the minimum number of results that you require, i.e., restrict the date range of the results, don’t use _include
parameters unless needed, apply sensible geographic restrictions (using the near
parameter), etc. It’s recommended that integrators experiment with different search parameters and find an acceptable balance between functionality and response time.
Any past time slots are omitted from the results, regardless of the start date specified under the input search criteria, as it’s not possible to book a time slot that has already passed.
Be careful when using the estimated-price filter, as it will exclude results if the diary owners have not published an estimated price.
The slots within a schedule may not all be the same and can be different depending on the services offered.
Requesting inclusion of schedule information
Where the integrating system wants to obtain service attributes like booking limit, admin interval, etc., it will need to request the schedule resource associated with the current slot. This can be done by specifying _include=schedule
in search parameters.
To identify the schedule resource in the returned dataset, use the fullUrl
field with a value as "fullUrl": "Schedule/20201221221433892LoRH0003"
.
Requesting inclusion of practitioner information
The integrating system may request the inclusion of practitioner details by specifying either _revinclude=practitioner:schedule
or _include=schedule:actor:practitioner
in the search parameters.
As the practitioner has no direct reference with the slot, the Practitioner resource needs to be identified through its reference within the schedule resource. A schedule resource is, therefore, also added to the result to maintain the connectivity and hierarchy between the resources. The practitioner is referenced as an actor of the schedule resource as below.
"actor": [
{
"reference": "Practitioner/20201203130810745Dz390004",
"display":"{practitioner Name}"
},
]
To identify the Practitioner resource in the bundle, use the fullUrl
field with a value as "fullUrl": "Practitioner/20201203130810745Dz390004"
.
Requesting inclusion of location information
The integrating system may request the inclusion of location details by specifying either _revinclude=location:schedule
or _include=schedule:actor:location
in the search parameters.
As the location has no direct reference with the slot, the Location resource needs to be identified through its reference within the Schedule resource. A schedule resource is, therefore, also added to the result to maintain the connectivity and hierarchy between the resources. The location resource is referenced as an actor of the schedule resource as below.
"actor": [
{
"reference": "Location/202012031305290792BHs0001",
"display":"{location Name}"
},
]
To identify the Location resource in the bundle, use the fullUrl
field with a value as "fullUrl": "Location/202012031305290792BHs0001"
.
Requesting inclusion of healthcare service information
The integrating system may request the inclusion of healthcare service details by specifying either _revinclude=healthcareservice:schedule
or _include=schedule:actor:healthcareservice
in the search parameters.
As the healthcare service has no direct reference with the slot, the HealthcareService resource needs to be identified through its reference within the schedule resource. A schedule resource is, therefore, also added to the result to maintain the connectivity and hierarchy between the resources. The healthcare service resource is referenced as an actor of the schedule resource as below.
"actor": [
{
"reference": "HealthcareService/#20201210001128151jYLE0001",
"display":"{service Name}"
},
]
To identify the HealthcareService resource in the bundle, use the fullUrl
field with a value as "fullUrl": "Schedule/2020121000211773116yq0635#20201210001128151jYLE0001"
.
Response
The API returns a list of Slot resources in FHIR JSON format.
{
"resourceType":"Bundle",
"meta":{
"tag":[
{
"code":"count",
"display":"100"
},
{
"code":"page",
"display":"1"
},
{
"code":"maxCount",
"display":"75"
}
]
},
"type":"searchset",
"total":75,
"entry":[
{
"resource":{
"resourceType":"Slot",
"id":"20201222155629070WEk50005",
"extension":[
{
"url":"{ref_URL}/extension/minutesDuration",
"valuePositiveInt": 15
},
{
"url":"{ref_URL}/extension/AppointmentCount",
"valueReference":{
"reference":"AppointmentCount/0"
}
}
],
"serviceCategory":{
"coding":[
{
"system":"{ref_URL}/valueset/service-category/ISC",
"code":"1400000000",
"display":"Gastro-intestinal system"
}
]
},
"serviceType":[
{
"coding":[
{
"system":"{ref_URL}/valueset/service-type/ISC",
"code":"E0000640",
"display":"Consultation, Follow Up"
}
]
}
],
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0004B",
"display":"Gastrointestinal Surgery"
}
]
}
],
"appointmentType":{
"coding":[
{
"system":"http://terminology.hl7.org/CodeSystem/v2-0276",
"code":"walkin",
"display":"A previously unscheduled walk-in visit"
}
]
},
"schedule":{
"reference":"Schedule/20201221221433892LoRH0003"
},
"status":"free",
"start":"2024-02-14T10:45:00.000+00:00",
"end":"2024-02-14T11:00:00.000+00:00"
}
},
{
"fullUrl":"Schedule/20210105182245781PQze0002",
"resource":{
"resourceType":"Schedule",
"id":"20210105182245781PQze0002",
"extension":[
{
"url":"{ref_URL}/extension/adminInterval",
"valuePositiveInt":5
},
{
"url":"{ref_URL}/extension/estimatedPrice",
"valueDecimal":100.00
},
{
"url":"{ref_URL}/extension/bookingLimit",
"valuePositiveInt":2
},
{
"url":"{ref_URL}/extension/slotDuration",
"valuePositiveInt":5
},
{
"url":"{ref_URL}/extension/isWalkin",
"valueBoolean":false
}
],
"active":true,
"actor":[
{
"reference":"Practitioner/SP09002",
"display":"Mr Charles Caine"
},
{
"reference":"Location/HP005002",
"display":"The Gastro Clinic"
},
{
"reference":"HealthcareService/#202101051822436961veh0001",
"display":"Consultation, Follow Up"
}
]
},
"search":{
"mode":"include"
}
}
]
.
. etc...
.
}
Where,
Field | Type | Description |
---|---|---|
Slot.id | String | Slot ID |
Schedule.id | String | Schedule ID |
Reminder: All dates/times are recorded in UTC time format. The calling application must convert these times into local time when displaying them to the user, taking into account changes for Daylight Saving Time etc.
A slot can have more than one appointment allocated to it. A scheduling system may permit multiple allocations up to a specific number of places. An example of this type of usage could be where the slot is being used for a group service that permits, for example, five participants at the same time. This is defined by the bookingLimit
attribute within a schedule and the current number of bookings into that slot can be accessed by the slot’s AppointmentCount
field.
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | The referenced resource is not found |
422 | INVALID_PARAMETER | The submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | The identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | The identifier value is not valid |
422 | INVALID_RESOURCE | The submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | One or more mandatory elements are missing |
422 | INVALID_EXTENSION | The submitted extension is not valid |
422 | INVALID_REFERENCE | The reference used is not valid |
Reserve Slot
The Reserve Slot API enables temporarily reserving a specific appointment slot.
A slot reservation expires in 5 minutes. You can extend it once by calling the Extend Slot Reservation API.
Endpoint
Must be looked up from the discovery document using key reserve_slot_endpoint.
Request
A sample POST request for reserving a slot is below. The API expects the integrating system to supply the slot resource as obtained from the result of the Search Slots API.
curl --request POST
--url '{reserve_slot_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw '
{
"resourceType": "Slot",
"schedule": {
"reference": "Schedule/2020121000211773116yq0635"
},
"start": "2024-01-13T01:00:00.000+00:00",
"end": "2024-01-13T02:00:00.000+00:00"
}
Where,
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
Schedule | Reference | 1-1 | Schedule where this slot belongs to | Slot.schedule.reference |
Start | Date | 1-1 | Start date/time of the slot | Slot.start |
End | Date | 1-1 | End date/time of the slot | Slot.end |
Response
On the successful reservation of the requested slot, a reservation id is returned using OperationOutcome resource as a response to API. This reservation id returned should be retained as it will need to be supplied as input later when creating appointment against the reserved slot.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"coding": [
{
"system": "{ref_URL}/identifier/slot/reserve",
"code": "202202111326150162I8J0930",
"display": "MSG_CREATED"
}
]
},
"diagnostics": "slot reserved successfully",
"location": [
"Slot"
],
"expression": []
}
]
}
Where,
Field | Type | Description |
---|---|---|
details.coding.code | String | Slot Reservation ID |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
422 | MSG_LIMIT_EXCEEDED | Slot is already at its maximum capacity |
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
422 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
Cancel Slot Reservation
The Cancel Slot Reservation API enables cancelling the slot reservation.
Endpoint
Must be looked up from the discovery document using key cancel_slot_reservation_endpoint.
Request
A sample DELETE request for cancelling a previously reserved slot is provided below.
curl --request DELETE
--url '{cancel_reserveslot_endpoint}/{resevation-id}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
Reservation id | String | M | Reservation id received from earlier Reserve Slot API call. |
Response
On successful cancellation of the reserved slot, the status is returned using OperationOutcome resource as a response to the API.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"coding": [
{
"system": "{ref_URL}/identifier/slot/reserve",
"code": "MSG_DELETED",
"display": "Reserve cancelled"
}
]
},
"diagnostics": "slot reserve removed",
"location": [
"Slot"
],
"expression": []
}
]
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource is found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
422 | INACTIVE_RESOURCE | Reservation ID has already been cancelled and is inactive. |
Extend Slot Reservation
The Extend Slot Reservation API enables extending a slot reservation.
You can extend a reservation only once.
A reservation can only be extended before the end of the existing reservation period. For example, in the above case, the extend-reservation API must be called before 10:55:00. If the reservation has expired, you will need to request a new reservation by calling the Reserve Slot API.
Extending a reservation resets the reservation period; it does not add extra time to the end of the current reservation period. i.e., if you have reserved a slot at 10:50:00 am (which would expire at 10:55:00), and then call the extend slot reservation API at 10:51:00, the new reservation window will be from 10:51:00 to 10:56:00.
Endpoint
Must be looked up from the discovery document using key extend_slot_reservation_endpoint.
Request
A sample PUT request for the API is provided below.
curl --request PUT
--url '{extend_reserve_slot_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw '{
"resourceType": "Slot",
"id": "202404020817285951u4K0127",
"schedule": {
"reference": "Schedule/2023120810135956125Ld2561",
"display": "schedule"
},
"start": "2024-04-02T19:15:00.000+00:00",
"end": "2024-04-02T19:30:00.000+00:00"
}'
Where,
Name | DataType | Description | FHIR Field |
---|---|---|---|
id | String | Reservation id received from earlier Reserve Slot API call. | id |
reference | String | Schedule reference, as used in the earlier Reserve Slot call. | |
start | Date | Slot start time, as used in the earlier Reserve Slot call | slot.start |
end | Date | Slot end time, as used in the earlier Reserve Slot call | slot.end |
Response
On the successful extension of reservation, the slot reserve identifier is returned using OperationOutcome resource as a response to API.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"coding": [
{
"system": "{ref_URL}/identifier/slot/reserve",
"code": "202202111326150162I8J0930",
"display": "RESERVE_EXTENDED"
}
]
},
"diagnostics": "slot reserve extended successfully.",
"location": [
"Slot"
],
"expression": []
}
]
}
Where,
Field | Type | Description |
---|---|---|
details.coding.code | String | Slot Reservation ID |
Note that the extend slot reserve can be done only one time and the API will throw an error if tried more than once. Below is the example response of API when tried more than once.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "processing",
"details": {
"coding": [
{
"system": "URL",
"code": "INACTIVE_RESOURCE",
"display": "Resource is inactive"
}
]
},
"diagnostics": "Extending slot reservation is not allowed more than once.",
"location": [
"Slot"
],
"expression": []
}
]
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
422 | INACTIVE_RESOURCE | Extending slot reservation is not allowed more than once. |
400 | INVALID_GDS_USERID | GDS UserID is not valid |
422 | REFERENCE_NOT_FOUND | Referenced resource is not found |
422 | INVALID_PARAMETER | Submitted parameter is not valid |
400 | INVALID_IDENTIFIER_SYSTEM | Identifier system is not valid |
400 | INVALID_IDENTIFIER_VALUE | Identifier value is not valid |
422 | INVALID_RESOURCE | Submitted resource is not valid |
422 | MISSING_MANDATORY_ELEMENT | Mandatory element is missing |
422 | INVALID_EXTENSION | Submitted extension is not valid |
422 | INVALID_REFERENCE | Reference used is not valid |
Appointment
Appointment resources are used to provide information about a planned appointment.
The resource only describes a single appointment; a series of repeating visits would require an additional resource to be created for each instance. A full list of fields contained within the Appointment resource can be found at http://hl7.org/fhir/R4/appointment-definitions.html
Note, ICE service does not keep a central patient database, instead, a patient’s details exist only in context of a given appointment. Patient data is kept to a minimum and is limited to only recording sufficient information to facilitate the appointment booking process. It’s not a mechanism to exchange patient notes or clinical details. As there is no universal patient identifier in the UK Private Healthcare market, the integrating systems can add one or more identifying numbers into the appointment record to help assist the diary owners in matching the patient into their own systems. However, it’s the responsibility of the integrating systems to match the patient with their own records if it’s a returning patient. This could be done using one of the stored identifying numbers, matching surname/forename/date of birth/postcode, or a combination of all of these.
Create Appointment using a Reserved Slot
Out of the two variants of the create-appointment APIs (the current API, creating API with slot reservation, and creating an appointment without prior slot reservation), this is the recommended workflow as is by far the easiest.
In order to call this API, the integrating system must have first reserved a slot using the Reserve Slot API. The API expects the reservation ID obtained from calling that API to be supplied within the request. This also has the added advantage wherein, most of the information needed to create the appointment is already fed into the system when the slot is reserved. The appointment creation itself, in this case, only needs to submit a minimum set of information (mainly patient demographic details) and the system will obtain the rest from the reserved slot (schedule, start time, end time, practitioner, location, service, etc).
Endpoint
Must be looked up from the discovery document using key create_appointment_endpoint.
Request
The API enables submitting an Appointment resource into the ICE platform. Patient details need to be enriched as a resource Patient under the contained
array.
curl --request POST
--url '{create_appointment_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw '
{
"resourceType": "Appointment",
"contained": [
{
"resourceType": "Patient",
"id": "1",
"extension": [
{
"url": "{ref_URL}/extension/patient/referralType",
"valueString": "{referral string if known to calling application}"
},
{
"url": "{ref_URL}/extension/patient/insurer",
"valueString": "{insurerId}"
},
{
"url": "{ref_URL}/extension/patient/registrationid",
"valueString": "{patient insurance registration id recognised by calling application}"
},
{
"url": "{ref_URL}/extension/patient/authorizationno",
"valueString": "{insurance authorization number recognised by calling application}"
},
{
"url": "{ref_URL}/extension/patient/nhsNumber",
"valueString": "1234567887"
}
],
"name": [
{
"family": "Anan",
"given": [
"Marylyn"
],
"prefix": [
"Miss"
]
}
],
"telecom": [
{
"system": "phone",
"value": "01865 777888",
"use": "home",
"rank": 1
},
{
"system": "email",
"value": "m.marylyn@patient.com",
"use": "home"
},
{
"system": "phone",
"value": "07711 123456",
"use": "mobile",
"rank": 1
},
{
"system": "sms",
"value": "07711 123456",
"use": "mobile",
"rank": 1
}
],
"gender": "female",
"birthDate": "1955-11-15",
"address": [
{
"use": "home",
"text": "75 Lime Avenue, Badgers Estate, Buckingham, Buckinghamshire",
"line": [
"75 Lime Avenue",
"Badgers Estate"
],
"district": "Buckingham",
"city": "Buckinghamshire",
"country": "UK",
"postalCode": "MK18 0DD"
}
]
}
],
"slot": [
{
"identifier": {
"use": "usual",
"system": "{ice_URL}/identifier/slot/reserve",
"value": "20201210085217666Y1M00002"
}
}
],
"identifier": [
{
"use": "usual",
"system": "https://pms/identifier/uid",
"value": "012992"
},
{
"use": "usual",
"system": "https://pms2/identifier/uid",
"value": "013552"
}
],
"priority": 5,
"description": "Patient complains of intermittent hip pain whilst walking and climbing stairs. Xrays suggest early onset OA",
"comment": "Business comments about this patient/appointment. NOT to be displayed to the patient.",
"participant": [
{
"actor": {
"reference": "Patient/#1"
}
}
],
"extension": [
{
"url": "https://{ref_URL}/extension/remoteAppointment",
"valueBoolean": true
}
]
}
Where,
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
Reservation ID | Reference | 1-1 | Reservation id received from earlier Reserve Slot API call. | Appointment.identifier |
Comment | StringType | 0-1 | Comments relating to this appointment – These are for business use only to pass information between booking channel/hospital/practitioner and must NOT be displayed to the patient. | Appointment.comment |
Participant | Array | 1-* | Participants of appointment e.g. practitioner, healthcareService, location etc (only Patient is mandatory) | Appointment.participant |
Patient | Reference | 1-1 | Reference of Patient Resource within this Appointment (usually “Patient/#1 ”) | Appointment.participant.actor.patient |
Reason | Reference | 0-1 | Optional “Reason” resource (provides more detailed information than just the ReasonCode below, but usually not required for booking purposes) | Appointment.reasonReference |
ReasonCode | CodeableConcept | 0-1 | Optional (but recommended) “Reason” code for the appointment (also known as “Presenting Condition”, “Admission Diagnosis” or “Impairment Code”) taken from ICD9 coding system | Appointment.reasonCode |
Description | StringType | 0-1 | Free-text description of why the appointment has been made. This could include patient symptoms, injury details, type of procedure or treatment the patient wishes to discuss. (max 1000 characters) | |
Slot | Identifier | 1-1 | Slot resource containing reservation identifier | |
Identifier | Identifier | 0-* | One or more identifiers supplied by 3rd parties to help track this appointment. | Appointment.Identifier.value |
Priority | unsignedInt | 0-1 | Priority can be used to make informed decisions if appointments need to be prioritised – the iCal Standard specifies 0 as undefined (default), 1 as highest and 9 as lowest priority | Appointment.priority |
remoteAppointment | Boolean | 0-1 | Set to “true” if this is to be a video consultation. (default=false). If true, the returned appointment will include URLs for the patient and practitioner to join the video consultation. |
Below are the fields of the Patient which are supported in the appointment request and response.
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
Patient ID | String | 1-1 | Internal Patient ref within THIS Appointment (usually ‘1’) | Patient.id |
Referral Type | Extension | 0-1 | Free text string to describe where the referral is from, e.g. “GP referral” | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/referralType |
Insurer | Extension | 0-1 | Healthcode ID for patient’s insurance company | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/insurer |
Registration ID | Extension | 0-1 | Patient’s insurance registration ID or patient ID recognised by calling application | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/registrationid |
Authorization No | Extension | 0-1 | Insurer’s Authorisation number for patient (Pre-auth) | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/authorizationno} |
Given | String | 1-1 | Patient’s first name | Patient.Humanname.given |
Family | String | 1-1 | Patient’s last name | Patient.Humanname.family |
Prefix | String | 0-1 | Patient’s title | Patient.Humanname.prefix |
Telecom | ContactPoint | 1-* | Patient’s contact telecom details | Patient.Telecom.Value (Where system = phone, fax, email, pager, URL, SMS, or other). Each patient MUST have one “email” or one “phone” telecom record as a minimum. If an email address is specified, it MUST be a valid address. (NOTE: “period” elements are not currently supported) |
Gender | AdministrativeGender | 1-1 | Patient’s gender | Patient.gender |
BirthDate | String | 1-1 | Patient’s date of birth (YYYY-MM-DD) (*) | Patient.birthdate |
Address | Address | 1-1 | Patient’s address | Patient.address (FHIR address field “period” is not supported, as the address is always assumed to be current) |
nhsNumber | String | 0-1 | Patient’s NHS | If specified, must be a valid 10-digit number. Space, hyphens, etc are removed. Invalid numbers (not 10 digits and don’t meet NHS number check-digit validation) will be rejected. This field can also be used for CHI (Scotland) and HSC (Ireland) as all share the same validation. |
(*) BirthDate is defined by FHIR as allowing dates in the format YYYY, YYYY-MM and YYYY-MM-DD to allow for cases where an exact date of birth is not know. However, most patient administration systems require a fully formatted year/month/day. Therefore, if BirthDate is supplied as just “YYYY”, it will be stored in ICE as “YYYY-01-01”. Equally, specifying a BirthDate as just “YYYY-MM” will be stored as “YYYY-MM-01”.
Note: If the slot’s parent schedule specifies a minimum or maximum patient age, and the patient’s age on the DATE OF THE APPOINTMENT (not today) is outside of the allowed range, the appointment will be rejected.
Response
On successful creation of the appointment, the API will return a unique identifier for the new appointment. It’s recommended the calling system stores this identifier value to update or cancel the appointment if required at a later point in time.
{
"resourceType": "AppointmentResponse",
"id": "202004221527071572JiM0000",
"extension": [
{
"url": "https://{ICE_URL}/extension/patientUrl",
"valueString": "https://ice.api.healthcode.co.uk/meetingURL?mId={Unique meeting joining code}"
},
{
"url": "https://{ICE_URL}/extension/practitionerUrl",
"valueString": "https://ice.api.healthcode.co.uk/meetingURL?mId={Unique meeting joining code}"
},
],
"appointment": {
"reference": "Appointment/{Identifier of appointment}"
},
"start": {appointment start date time},
"end": {appointment end date time},
"actor": {
"reference": "Practitioner/{identifier of practitioner in appointment}"
},
"participantStatus": {status of appointment}
}
Where,
Field | Type | Description |
---|---|---|
AppointmentResponse.id | String | New unique ID for the newly created appointment |
ParticipantStatus | String | Status of appointment. This is always “accepted” for newly booked appointments. |
patientUrl | String | Link for patient to open when joining video consultation. Not included for face-to-face appointments. |
practitionerUrl | String | Link for practitioner to open when starting the video consultation. Not included for face-to-face appointments. |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable entity |
400 | MSG_INVALID_ID – “Slot does not allow remote appointments” | Appointment was created using “remoteAppointment=true” but the schedule only allows for face-to-face appointments. |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Create Appointment without using a Reservation Identifier
While the recommended workflow is to book appointments against a prior reserved slot, an appointment can be booked without prior use of reservation.
Without a reservation identifier, it’s mandatory to use the same schedule reference, start date/time, end date/time, and slot ID as returned in the Search Slot API.
Endpoint
Must be looked up from the discovery document using key create_appointment_endpoint.
Request
The API enables submitting an Appointment resource into the ICE platform. Patient details need to be enriched as a resource Patient under the contained
array.
curl --request POST
--url '{create_appointment_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw '
{
"resourceType":"Appointment",
"contained":[
{
"resourceType":"Patient",
"id":"1",
"extension":[
{
"url":"{ref_URL}/extension/patient/referralType",
"valueString":"{referral string if known to calling application}"
},
{
"url":"{ref_URL}/extension/patient/insurer",
"valueString":"{insurerId}"
},
{
"url":"https://{ref_URL}/extension/patient/registrationid",
"valueString":"{patient registration id recognised by calling application}"
},
{
"url":"https://{ref_URL}/extension/patient/authorizationno",
"valueString":"{authorization number recognised by calling application}"
}
],
"name":[
{
"family":"Anan",
"given":[
"Marylyn"
],
"prefix":[
"Miss"
]
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home"
},
{
"system":"email",
"value":"m.marylyn@patient.com",
"use":"home"
},
{
"system":"phone",
"value":"07711 123456",
"use":"mobile"
"rank":1
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrew's Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"identifier":[
{
"use":"external_identifier",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"use":"external_identifier",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"appointmentType":{
"coding":[
{
"system":"http://terminology.hl7.org/CodeSystem/v2-0276",
"code":"routine",
"display":"Routine appointment"
}
]
},
"priority":5,
"description":"Discussion on the results of your recent MRI",
"comment":"Business comments about this patient/appointment. NOT to be displayed to the patient.",
"supportingInformation": [
{
"reference": "Schedule/202312011105056091nUx0173",
"display": "schedule"
}
],
"slot":[
{
"reference":"Slot/202012100750474442BST0004"
}
],
"start":"2024-01-13T13:00:00.000+00:00",
"end":"2024-01-13T14:00:00.000+00:00",
"participant":[
{
"actor":{
"reference":"Patient/#1"
}
}
]
}
Where,
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
Appointment Type | Codeable Concept | 0-1 | Appointment type – “style” of appointment, NOT the actual service type (i.e. walk-in, routine, emergency, etc) – all type codes are lowercase. | Appointment.appointmenttype |
Description | StringType | 0-1 | Description of appointment, similar to the subject line of an email | Appointment.descriphttps://www.hl7.org/fhir/R4/appointment-definitions.html#Appointment.descriptiontion |
Start | Date | 0-1 | Start date of appointment | Appointment.start |
End | Date | 0-1 | End date of the appointment | Appointment.end |
Comment | StringType | 0-1 | Comments relating to this appointment – These are for business use only and must NOT be displayed to the patient. (Reminder: String types in FHIR do not support formatting or line breaks) | Appointment.comment |
Participant | Array | 1-* | Participants of appointment e.g. practitioner, healthcareService, location etc (only Patient is mandatory) | Appointment.participant |
Patient | Reference | 1-1 | Reference of Patient Resource within this Appointment (usually “Patient/#1 ”) | Appointment.participant.actor.patient |
Required | Boolean | 0-1 | Required status of participant (assumes “required” if not specified) | Appointment.participant.required |
Participant Status | Codeable Concept | 0-1 | Status of participant (assumes “accepted” if not specified) | Appointment.participant.status |
Reason | Reference | 0-1 | Optional “Reason” resource (provides more detailed information than just the ReasonCode below, but usually not required for booking purposes) | Appointment.reasonReference |
ReasonCode | Codeable Concept | 0-1 | Optional (but recommended) “Reason” code for the appointment (also known as “Presenting Condition”, “Admission Diagnosis” or “Impairment Code”) taken from ICD9 coding system | Appointment.reasonCode |
Identifier | 0-* | One or more external identifiers supplied by 3rd parties to help track this appointment. | Appointment.Identifier.value |
Below are the fields of a Patient resource which are supported in the appointment request and response.
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
id | String | 1-1 | Internal Patient ref within THIS Appointment (usually ‘1’) | Patient.id |
Referral Type | Extension | 0-1 | Free text string to describe where the referral is from, e.g. “GP referral” | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/referralType |
Insurer | Extension | 0-1 | Healthcode ID for patient’s insurance company | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/insurer |
Registration ID | Extension | 0-1 | Patient’s insurance registration ID or patient ID recognised by calling application | Appointment.Patient.Extension.valueString URL = {ref_URL}extension/patient/registrationid |
Authorization No | Extension | 0-1 | Insurer’s Authorisation number for patient (Pre-auth) | Appointment.Patient.Extension.valueString URL = {ref_URL}/extension/patient/authorizationno |
Given | String | 1-1 | Patient’s first name | Patient.Humanname.given |
Family | String | 1-1 | Patient’s last name | Patient.Humanname.family |
Prefix | String | 0-1 | Patient’s title | Patient.Humanname.prefix |
phone | Telecom | ?-1 | Patient’s telephone number (*) | Patient.Telecom.Value (Where system = ‘phone’) |
Telecom | ?-1 | Patient’s email address. If specified, this MUST be a valid address. (*) | Patient.Telecom.Value (Where system = ‘email’) | |
gender | AdministrativeGender | 1-1 | Patient’s Gender | Patient.gender |
birth date | String | 1-1 | Patient’s date of birth (YYYY-MM-DD) | Patient.birthdate |
address | Address | 1-1 | Patient’s address | Patient.address |
(*) Phone and email are not both mandatory, but at least one of them has to be recorded.
(**) BirthDate is defined by FHIR as allowing dates in the format YYYY, YYYY-MM and YYYY-MM-DD to allow for cases where an exact date of birth is not know. However, most patient administration systems require a fully formatted year/month/day. Therefore, if BirthDate is supplied as just “YYYY”, it will be stored in ICE as “YYYY-01-01”. Equally, specifying a BirthDate as just “YYYY-MM” will be stored as “YYYY-MM-01”.
Response
On successful creation of the appointment, the API will return a unique identifier for the new appointment. It’s recommended the calling system stores this identifier value to update or cancel the appointment at a later point in time.
{
"resourceType": "AppointmentResponse",
"id": "202004221527071572JiM0000",
"appointment": {
"reference": "Appointment/{Identifier of appointment}"
},
"start": {appointment start date time},
"end": {appointment end date time},
"actor": {
"reference": "Practitioner/{identifier of practitioner in appointment}"
},
"participantStatus": {status of appointment}
}
Where,
Field | Type | Description |
---|---|---|
Id | String | Appointment Response ID |
ParticipantStatus | String | Status of appointment |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Create Appointment (as a diary owner)
In addition to the normal “Create Appointment using a Reserved Slot” and “Create Appointment Without Reserve Slot”, the diary owner can create appointments directly into ICE without having to complete the normal Search/Reserve/Book cycle, instead just specifying the required date/time instead of a slot/schedule ID.
The endpoint, request, response and error handling are the same as the Create Appointment Without Reservation detailed above, with the exception that no Slot-ID is required.
Appointments made using this method will BYPASS some of ICE’s normal validation checks. For example, you are NOT warned if a new appointment creates a double booking or if the start/end times are outside of scheduled hours. This is so that diary owners can deliberately create exceptional bookings, as they would in a paper diary.
For most appointments, the regular Create Appointment With/Without Reservation flows are recommended.
Non-diary owners (such as booking channels) are NOT permitted to use this function, and trying to create an appointment without a valid Slot-ID will result in an error.
Patch Appointment
Patch Appointment API enables quick changes to common appointment fields, without the need to re-submit the entire appointment record (as required by Update Appointment).
Endpoint
Must be looked up from the discovery document using key patch_appointment_endpoint.
Request
A sample PATCH request is provided below.
curl --request PATCH
--url '{patch_appointment_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
--data-raw '
{
"resourceType":"Appointment",
"id":"20201127172539895LfDJ0022",
"priority": 2,
"description": "Updated description",
"comment": "Updated comment",
"status": "cancelled",
"cancelationReason": {
"coding": [
{
"system":"{ref_URL}/appointment-cancellation-reason",
"code": "pat-fb"
}
]
}
Where,
Name | DataType | Card. | Description | FHIR Field |
---|---|---|---|---|
ID | Reference | 1-1 | Appointment ID of an existing appointment | Appointment.identifier |
Status | StringType | 0-1 | Valid options include “proposed, pending, booked, arrived, fulfilled, cancelled, noshow” | Appointment.status |
Comment | StringType | 0-1 | Comments relating to this appointment – These are for business use only to pass information between booking channel/hospital/practitioner and must NOT be displayed to the patient. | Appointment.comment |
Description | StringType | 0-1 | Description of appointment, similar to the subject line of an email | Appointment.description |
Priority | unsignedInt | 0-1 | Priority can be used to make informed decisions if appointments need to be prioritised – the iCal Standard specifies 0 as undefined (default), 1 as highest and 9 as lowest priority | Appointment.priority |
cancelationReason | CodeableConcept | 0-1 | FHIR Reason code for why an appointment was cancelled. Optional. Should only be used when the Status is “cancelled”. Note the American spelling of “cancelation”. | Appointment.cancelationReason |
Only appointment status
, priority
, description, cancelationReason
and comment
can be patched, as these are the most common fields that require regular updating. If the date/time or any other details need to be changed then the appointment should be marked as cancelled and recreated with the correct information.
Important:
Attempting to update fields other than those listed above will be ignored without returning an error. The appointment record returned in the results body should be checked to ensure that the required fields have been updated correctly.
When updating the “comments” field, care should be taken to append new information rather than over-writing any existing important comments.
Care should be taken when setting the “status” to “cancelled”. Once set to “cancelled”, the appointment status can no longer be changed. This process cannot be reversed.
Setting a “cancelationReason” does NOT automatically set the appointmentStatus to cancelled. Both fields should be set individually.
Response
On successful completion of the update, the API returns the persisted appointment resource in response.
{
"resourceType":"Appointment",
"text":{
"status":"arrived"
},
"contained":[
{
"resourceType":"Patient",
"id":"P10",
"name":[
{
"use":"official",
"prefix":"Miss",
"given":"Marylyn",
"family":"Anan"
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home"
},
{
"system":"email",
"value":"m.marylyn@patient.com",
"use":"home"
},
{
"system":"phone",
"value":"07711 123456",
"use":"mobile"
"rank":1
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrea's Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"comment":"Updated comment",
"description":"Updated description",
"priority":2
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Update Appointment
The Update Appointment API enables submitting changes to already created appointments by submitted a complete (updated) appointment record. If you only wish to update certain fields, consider using “patch appointment” instead.
Endpoint
Must be looked up from the discovery document using key update_appointment_endpoint.
Request
A sample PUT request for an update appointment is provided below. You should always use an instance obtained from either the Get Appointment or Search Appointments APIs as base for forming the input for the update call, to avoid any unintended errors or data omissions.
curl --request PUT
--url '{update_appointment_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--data-raw '
{
"resourceType":"Appointment",
"id":"20201127172539895LfDJ0022",
"contained":[
{
"resourceType":"Patient",
"id":"1",
"name":[
{
"family":"Anan",
"given":[
"Marylyn"
],
"prefix":[
"Miss"
]
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home"
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrew's Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"status":"booked",
"comment":"Business comments about this patient/appointment. NOT to be displayed to the patient.",
"participant":[
{
"actor":{
"reference":"Patient/#1"
}
}
]
}
Only patient name, patient address, date of birth, appointment status and comments can be modified. These fields will be updated, but attempts to change any other fields within the same request will be ignored without error notification. If the date/time or any other details need to be changed then the appointment should be cancelled and recreated with the correct information.
When updating the “comments” field, care should be taken to append new information rather than over-writing any existing important comments.
Response
On successful completion of the update, the API returns the persisted appointment resource in response.
{
"resourceType":"Appointment",
"text":{
"status":"arrived"
},
"contained":[
{
"resourceType":"Patient",
"id":"P10",
"name":[
{
"use":"official",
"prefix":"Miss",
"given":"Marylyn",
"family":"Anan"
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home",
"rank":1
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrea's Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"comment":"Business comments about this patient/appointment. NOT to be displayed to the patient."
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
400 | INVALID_RESOURCE | Unprocessable Entity – |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Cancel Appointment [Deprecated]
This API has now been deprecated. Instead, please use the Patch Appointment API to set the appointment status to “cancelled” and (optionally) supply a cancellation reason code.
Get Appointment
The Get Appointment API enables retrieving a single appointment instance for a known id.
Note, the appointment details can only be retrieved by the practitioners and/or hospitals that are associated with the specific appointment or the distribution system that created the booking.
Endpoint
Must be looked up from the discovery document using key get_appointment_endpoint.
Request
A sample GET request for this is shown below.
curl --request GET
--url '{get_appointment_endpoint}/{appointment_ID}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Response
If an appointment instance was found matching the supplied id, the API returns the corresponding appointment resource.
{
"resourceType":"Appointment",
"id": "202407301609107181UkB0006",
"meta": {
"lastUpdated": "2024-07-30T16:09:39.825+00:00"
},
"contained":[
{
"resourceType":"Patient",
"id":"2024073016074225028k70005",
"extension": [
{
"url": "{ref_URL}/extension/patient/referralType",
"valueString": "GP"
},
{
"url": "{ref_URL}/extension/patient/insurer",
"valueString": "insurer10"
},
{
"url": "{ref_URL}/extension/patient/registrationid",
"valueString": "registrationid10"
},
{
"url": "{ref_URL}/extension/patient/authorizationno",
"valueString": "AUTH12321"
},
{
"url": "{ref_URL}/extension/patient/nhsNumber",
"valueString": "1234567812"
}
],
"identifier": [
{
"value": "2024073016074225028k70005"
}
],
"name":[
{
"use":"official",
"prefix":"Miss",
"given":"Marylyn",
"family":"Anan"
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home",
"rank":1
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrea's Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"status": "booked",
"serviceType": [
{
"coding": [
{
"system": "{ref_URL}/valueset/service-type/ISC",
"code": "E0000260",
"display": "Pure Tone Test"
}
]
}
],
"specialty": [
{
"coding": [
{
"system": "{ref_URL}/valueset/specialty/ISC",
"code": "00033",
"display": "Maxillo-Facial Surgery"
}
]
}
],
"priority": 1,
"description": "Discussion on the results of your reports",
"start": "2024-07-30T17:00:00.000+00:00",
"end": "2024-07-30T17:10:00.000+00:00",
"minutesDuration": 10,
"created": "2024-07-30T16:09:38+00:00",
"comment": "Business comments about this patient/appointment. NOT to be displayed to the patient."
"participant": [
{
"actor": {
"reference": "Location/HP003536",
"display": "Jero Hospital 1"
}
},
{
"actor": {
"reference": "HealthcareService/202407301602526151Fd70000",
"display": "Pure Tone Test"
}
},
{
"actor": {
"reference": "Patient/#2024073016074225028k70005",
"display": "Mr. Klasen Smith"
}
},
{
"actor": {
"reference": "Practitioner/#SP017456",
"display": "Mr. Malcolm Hopper"
}
}
]
}
Search Appointments
The Search Appointments API enables the searching of appointments that have already been booked using different filter criteria.
Note, the appointment details can only be retrieved by the practitioners and/or hospitals that are associated with the specific appointment or the distribution system that created the booking.
Endpoint
This must be looked up from the discovery document using key search_appointment_endpoint.
Request
A sample GET request searching for an appointment is provided below.
curl --request GET
--url '{search_appointment_endpoint}?
location=HP005000&
specialty=0003A&
service-category=7600000000&
appointment-status=arrived,booked&
patient=20200422152707137spLF0000
date-from={datetime ‘yyyy-MM-ddTHH:mm:ss’}&
date-to={datetime ‘yyyy-MM-ddTHH:mm:ss’}&
schedule={scheduleId}&
service-type=E0000610&
_since={datetime ‘yyyy-MM-ddTHH:mm:ss’}&
_sort= date-lastupdated&
_include = schedule,practitioner,location'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Where,
Response
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
Specialty | String | O | The specialty code of a practitioner that would be required to perform the service requested in this appointment |
Practitioner | String | O | Practitioner ID who is attending the appointment |
Location | String | O | Location ID where the appointment will be held |
appointment-status | String | O | Status of appointment Multiple statuses may be specified, comma-separated. |
service-category | String | O | Service category code for appointments |
service-type | String | O | Service Type code for appointments |
Patient | String | O | Internal Patient ID used for appointment |
date-from | String | O | Date from which the search needs to be done |
date-to | String | O | Date up to which the search needs to be done |
identifier | String | O | Match any external (3rd party/business) identifier |
nhs-number | String | O | Match patient NHS number (includes CHI/IHI) recorded against appointments. This should be a 10-digit number with no punctuation. |
Schedule | String | O | Only return appointments matching the Schedule ID specified. |
_sort | String | O | “date-lastupdated ” causes the results to be sorted by the last updated date/time (ascending). Prefix with ‘- ‘ to reverse the order to descending. If not specified, results are in order of date/time created (ascending). |
_include | String | O | Request server to return additional resources in the response. Valid options are: schedule , practitioner , location . Multiple options can be used, comma separated. |
_since | String | O | Only return results that have been updated since the date/time specified (Format YYYY-M-DDThh:mm:ss ) |
_summary | String | O | If “true “, instructs API to only return reduced/summary details. Default is “false “ |
page | String | O | Page index to be fetched {1,2,3..} |
count | String | O | Maximum number of records to be returned in a single page |
On successful search of the appointment, the API will return search results as a Bundle resource.
{
"resourceType":"Bundle",
"meta":{
"tag":[
{
"code":"max-records",
"display":"10"
},
{
"code":"page-index",
"display":"1"
},
{
"code":"TotalRecords",
"display":"1"
}
]
},
"type":"searchset",
"total":1,
"entry":[
{
"resource":{
"resourceType":"Appointment",
"id":"202312100903236891Cce0010",
"meta":{
"lastUpdated":"2023-12-20T11:27:16.969"
},
"contained":[
{
"resourceType":"Patient",
"id":"#202012100903235931nk30009",
"extension":[
{
"url":"{ref_URL}/extension/patient/referralType",
"valueString":"referral10"
},
{
"url":"{ref_URL}extension/patient/insurer",
"valueString":"insurer10"
},
{
"url":"{ref_URL}/extension/patient/registrationid",
"valueString":"registrationid10"
},
{
"url":"{ref_URL}/extension/patient/authorizationno",
"valueString":"authorizationno10"
}
],
"identifier":[
{
"value":"202012100903235931nk30009"
}
],
"name":[
{
"family":"Anan",
"given":[
"Marylyn"
],
"prefix":[
"Miss"
]
}
],
"telecom":[
{
"system":"phone",
"value":"01865 777888",
"use":"home"
}
],
"gender":"female",
"birthDate":"1955-11-15",
"address":[
{
"use":"home",
"text":"75 St Andrew’s Way, Fordingdyke, Oxford",
"line":[
"75 St Andrew’s Way, Fordingdyke"
],
"city":"Oxford",
"postalCode":"OX2 0DD"
}
]
}
],
"extension": [
{
"url": "{ref_URL}/extension/channel",
"valueReference": {
"reference": "Channel/20201206131528806279q0000",
"display": "Patient Booking Portal"
}
}
],
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"202105031640191891DRF0030"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms2/identifier/uid",
"value":"013552"
},
{
"use":"usual",
"system":{ref_URL}/identifier/slot/reserve",
"value":"20201210090230273119P0007"
}
],
"status":"booked",
"serviceCategory":{
"coding":[
{
"system":"{ref_URL}/valueset/service-category/ISC",
"code":"7600000000",
"display":"Orthopaedic"
}
]
},
"specialty":[
{
"coding":[
{
"system":"{ref_URL}/valueset/practitioner-specialty/ISC",
"code":"0003A",
"display":"Trauma & Orthopaedics"
}
]
}
],
"appointmentType":{
"coding":[
{
"system":"http://terminology.hl7.org/CodeSystem/v2-0276",
"code":"routine",
"display":"Routine appointment"
}
]
},
"priority":0,
"supportingInformation":[
{
"valueReference":{
"reference":"Schedule/20200422082532465OnRZ0000"
}
}
],
"start":"2024-01-13T01:00:00.000+00:00",
"end":"2024-01-13T02:00:00.000+00:00",
"minutesDuration":"60",
"slot":[
{
"reference":"Slot/20201210085217666Y1M00002"
}
],
"created":"2023-12-10T09:03:23",
"comment":"Business comments about this patient/appointment. NOT to be displayed to the patient.",
"patientInstruction":"instructions",
"participant":[
{
"actor":{
"reference":"Practitioner/SP09000",
"display":"Mr Warren Clinton"
}
},
{
"actor":{
"reference":"Location/HP005000",
"display":"St Elsewhere Hospital"
}
},
{
"actor":{
"reference":"HealthcareService/202012100021172482JOY0634",
"display":"Consultation, Initial"
}
},
{
"actor":{
"reference":"Patient/#202012100903235931nk30009",
"display":"Miss Marylyn Anan"
}
}
]
}
}
]
}
Where,
Field | Type | Description |
---|---|---|
Appointment.id | String | Appointment ID |
/extension/channel | String | Channel id and name of system where booking originated |
patientInstruction | String | This is the same information as specified in the schedule’s HealthcareService.extraDetails, and is information that the patient MUST be made aware of regarding this appointment/service. |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse Appointment |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Unavailability (NotAvailable)
NotAvailable is a custom FHIR resource introduced for managing the non-availability of practitioners at different locations. NotAvailable records in the booking system are managed for a given practitioner and optionally, a given location.
Unavailability can be configured for a given schedule by specifying one or more NotAvailable resources during the create or update schedule API calls.
Alternatively, the unavailability can be configured outside the schedule context, in which case it’s applied across all schedules that overlap with the time period specified. The below APIs under this section support this global unavailability management workflow.
Create NotAvailable
Endpoint
Must be looked up from the discovery document using key patch_add_notavailable_endpoint.
Request
A sample POST request for the API is provided below.
curl --request POST
--url '{patch_add_notavailable_endpoint}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
--data-raw '
{
"resourceType":"NotAvailable",
"identifier":[
{
"use":"usual",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"use":"usual",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"description":"Reason for non availability",
"period":{
"start":"2024-07-29T00:00:00+00:00",
"end":"2024-07-30T15:00:00+00:00"
},
"practitioner":{
"reference":"Practitioner/SP09001"
},
"location":{
"reference":"Location/HP005001",
"display":"Fordingdyke Hospital"
}
}'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
practitioner | String | M | Practitioner ID that needs to be applied |
location | String | O | Location that will be marked as being unavailable for this practitioner. If omitted, the NotAvailable record will be applied across ALL locations. |
description | String | M | Description/reason for notAvailable record |
Start | String | M | Start datetime of the notAvailable |
End | String | M | End datetime of the notAvailable |
identifier | String | O | Business identifier(s) – specified by the 3rd party PMS system – for tracking this notAvailable record |
When location id is not supplied in the request, the unavailability is applied across all locations for the given practitioner.
Response
The API will return the newly created notAvailable resource.
{
"resourceType":"NotAvailable",
"id":"20210610203145219blVr0011",
"meta":{
"lastUpdated":"2023-06-10T20:31:46.366",
"profile":[
"http://hl7.org/fhir/Profile/NotAvailable"
]
},
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"20210610203145219blVr0011"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"active":true,
"description":"reason for non availability",
"createdon":"2023-06-10T20:31:46.366",
"lastupdatedon":"2023-06-10T20:31:46.366",
"period":{
"start":"2024-07-29T00:00:00+00:00,
"end":"2024-07-30T15:00:00+00:00"
},
"practitioner":{
"reference":"Practitioner/SP09001",
"display":"Mrs Betty Dean"
},
"location":{
"reference":"Location/HP005001",
"display":"Fordingdyke Hospital"
}
}
Where,
Field | Type | Description |
---|---|---|
id | String | Non-availability ID |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse NotAvailable |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID is not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Cancel NotAvailable
The Cancel NotAvailable API enables removing a previously created unavailability.
Endpoint
Must be looked up from the discovery document using key cancel_notavailable_endpoint.
Request
A sample DELETE request for the API is provided below.
curl --request DELETE
--url '{cancel_notavailable_endpoint}/{notavailable.id}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
notavailable.id | String | M | NotAvailable ID that must be cancelled |
Response
On successful cancellation, the status is returned using OperationOutcome resource.
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "information",
"code": "informational",
"details": {
"coding": [
{
"system": "{ref_URL}/identifier/notavailable",
"code": "202105251948504691o3F1264",
"display": "MSG_DELETED"
}
]
},
"diagnostics": "NotAvailable deleted",
"location": [
"NotAvailable"
],
"expression": []
}
]
}
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse NotAvailable |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Get NotAvailable
The Get NotAvailable API enables retrieving a single unavailability instance for a known id.
Endpoint
Must be looked up from the discovery document using key get_notavailable_endpoint.
Request
A sample GET request for this is shown below.
curl --request GET
--url '{get_notavailable_endpoint}/{notavailable_ID}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
Response
If an unavailability instance was found matching the supplied id, the API returns the corresponding NotAvailable resource.
{
"resourceType":"NotAvailable",
"id":"20210610203145219blVr0011",
"meta":{
"lastUpdated":"2023-06-10T20:31:46.366",
"profile":[
"http://hl7.org/fhir/Profile/NotAvailable"
]
},
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"20210610203145219blVr0011"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"active":true,
"description":"reason for non availability",
"createdon":"2023-06-10T20:31:46.366",
"lastupdatedon":"2023-06-10T20:31:46.366",
"period":{
"start":"2024-07-29T00:00:00+00:00",
"end":"2024-07-30T15:00:00+00:00"
},
"practitioner":{
"reference":"Practitioner/SP09001",
"display":"Mrs Betty Dean"
},
"location":{
"reference":"Location/HP005001",
"display":"Fordingdyke Hospital"
}
}
Search NotAvailable
The Search NotAvailable API enables searching for unavailability records using different filter criteria.
Endpoint
Must be looked up from the discovery document using key search_notavailable_endpoint.
Request
A sample GET request for the API is provided below.
curl --request GET
--url '{search_notavailable_endpoint}'?
practitioner=SP09001&
location=HP005001&
_since=2024-03-01T09:00:00&
booking_identifier='20210609173840897vJIP0000'&
external_identifier='012992' '
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
--header 'SU-SiteId: {SiteID}'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
practitioner | String | O | Practitioner for whom the non-availability is defined |
location | String | O | Location where the non-availability is applicable |
_since | String | O | Date from which the search needs to be performed |
booking_identifier | String | O | Default booking ID for the resource |
external_identifier | String | O | External ID used while creating the resource in ICE by the calling application |
page | String | O | Page index to be fetched {1,2,3..} |
count | String | O | Maximum number of records to be returned in a single page |
Response
On successful search of the NotAvailable, the API will return matched results.
{
"resourceType":"Bundle",
"meta":{
"tag":[
{
"code":"count",
"display":"10"
},
{
"code":"page",
"display":"1"
},
{
"code":"maxCount",
"display":"2"
}
]
},
"type":"searchset",
"total":2,
"entry":[
{
"resource":{
"resourceType":"NotAvailable",
"id":"20210609173840897vJIP0000",
"meta":{
"lastUpdated":"2023-06-09T17:38:42.398",
"profile":[
"http://hl7.org/fhir/Profile/NotAvailable"
]
},
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"20210609173840897vJIP0000"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"active":false,
"description":"Reason for non availability",
"createdon":"2023-06-09T17:38:42.398",
"lastupdatedon":"2023-06-09T17:38:42.39",
"period":{
"start":"2023-12-31T00:00:00+00:00",
"end":"2023-12-31T15:00:00+00:00"
},
"practitioner":{
"reference":"Practitioner/SP09001",
"display":"Mrs Betty Dean"
},
"location":{
"reference":"Location/HP005001",
"display":"Fordingdyke Hospital"
}
}
},
{
"resource":{
"resourceType":"NotAvailable",
"id":"20210610203145219blVr0011",
"meta":{
"lastUpdated":"2023-06-10T20:31:46.366",
"profile":[
"http://hl7.org/fhir/Profile/NotAvailable"
]
},
"identifier":[
{
"id":"booking_identifier",
"use":"official",
"system":"{ref_URL}/identifier",
"value":"20210610203145219blVr0011"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms/identifier/uid",
"value":"012992"
},
{
"id":"external_identifier",
"use":"official",
"system":"https://pms2/identifier/uid",
"value":"013552"
}
],
"active":true,
"description":"reason for non availability",
"createdon":"2023-06-10T20:31:46.366",
"lastupdatedon":"2023-06-10T20:31:46.366",
"period":{
"start":"2023-07-29T00:00:00+00:00",
"end":"2023-07-30T15:00:00+00:00"
},
"practitioner":{
"reference":"Practitioner/SP09001",
"display":"Mrs Betty Dean"
},
"location":{
"reference":"Location/HP005001",
"display":"Fordingdyke Hospital"
}
}
}
]
}
Where,
Field | Type | Description |
---|---|---|
id | String | NotAvailabe ID |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse NotAvailable |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID not found |
422 | MSG_DATE_FORMAT | Date format is not valid |
Channels
Channel is a custom FHIR resource containing a list of third-party appointment consumers, such as insurers, bookings websites, etc.
Get Channel
The Get Channel API enables retrieving a single channel instance for a known channel ID.
Endpoint
Must be looked up from the discovery document using the get_channel_endpoint key.
Request
A sample GET request for this is shown below.
curl --request GET
--url '{get_channel_endpoint}/{channel_ID}'
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Response
If a channel matching the specified ID was found, the API returns the corresponding Channel resource.
{
"resourceType":"Channel",
"id":"{channel_ID}",
"meta":{
"lastUpdated":"2023-06-10T20:31:46.366",
},
"active":true,
"name":"Test Channel",
"alias":"ICE Test Channel",
}
Search Channels
The Search Channels API enables searching for a channel ID using the channel’s name or returning a list of all channels.
Endpoint
Must be looked up from the discovery document using key search_channel_endpoint.
Request
A sample GET request for the API is provided below.
curl --request GET
--url '{search_channel_endpoint}'?
_since=2024-03-01T09:00:00&
--header 'Authorization: Bearer abCdE12...89mNopq0r'
--header 'Content-Type: application/fhir+json'
Where,
Field | Type | Mandatory/ Optional | Description |
---|---|---|---|
name | String | O | Exact name of channel to search for |
_since | String | O | Only search records created/updated since date specified (YYYY-MM-DDTHH:mm:SS) |
page | String | O | Page index to be fetched {1,2,3..} |
count | String | O | Maximum number of records to be returned in a single page |
Note: There is no “channel_id” parameter to Search Channel; instead use the “Get Channel” API.
Response
On successful search of the NotAvailable, the API will return matched results.
{
"resourceType":"Bundle",
"meta":{
"tag":[
{
"code":"count",
"display":"100"
},
{
"code":"page",
"display":"1"
},
{
"code":"maxCount",
"display":"1"
}
]
},
"type":"searchset",
"total":1,
"entry":[
{
"resource":{
identifier": [
{
"value": "epractice_19Dec2023063927"
}
],
"active": true,
"name": "epractice_19Dec2023063927",
"alias": [
"DEMO CHANNEL for api-booking",
]
}
},
]
}
Where,
Field | Type | Description |
---|---|---|
value | String | Channel ID |
name | String | Actual name of Channel |
alias | String | Alternative name for this Channel |
Error handling
HTTP Code | Error Code | Description |
---|---|---|
400 | MSG_CANT_PARSE_CONTENT | Failed to parse NotAvailable |
400 | MSG_MISSING_MANDATORY_PARAM | Mandatory parameter is missing |
400 | MSG_INVALID_FORMAT | Submitted parameter is not valid |
400 | INVALID_RESOURCE | Unprocessable Entity |
422 | MSG_FAILED_TO_READ_ENTITY | Failed to read entity from database |
404 | MSG_ENTITY_NOT_FOUND_IN_DATABASE | No matching resource found |
422 | MSG_PARAM_INVALID | Parameter content is not valid |
422 | MSG_REFERENCE_ID_NOT_FOUND | Reference ID not found |
422 | MSG_DATE_FORMAT | Date format is not valid |