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,

NameDataTypeCard.Description FHIR Field
StartPeriod.date1-1First 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
EndPeriod.date1-1Last 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
SpecialtyCodeableConcept1-*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 CategoryCodeableConcept0-1This is the category of the service present in the Schedule, not the actual service itselfSchedule.serviceCategory.codeableConcept.code
{ref_URL}/valueset/service-category/ISC
Service TypeCodeableConcept0-1This 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
PractitionerReference1-1The person who will be performing the services in the scheduled period. This is the practitioner’s “SP” reference number.Schedule.actor.Reference.value{Practitioner}
LocationReference1-1The treatment site or the location where the service will be performed by the practitioner. (*) See note below.Schedule.actor.Reference.value{Location}
Healthcare ServiceReference1-1Healthcare Service provided in the scheduleSchedule.actor.Reference.value{HealthcareService}
extraDetailsString0-1Extra details that the patient MUST be made aware of about this serviceSchedule.contained.HealthcareService.extraDetails
TelecomContactPoint 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 BackboneElement1-*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
Channelextension0-*Channels with restrictions to search/book permissions for slots within schedule.(see blockPermissions below)Schedule.Extension.referenceValue
URL = {ref_URL}/extension/channel
Front Loadingextension0-1If 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 Loadingextension0-1If 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 walkinextension0-1Is walkin Slot (walk-in allowed) (default is false)Schedule.Extension.valueAsBoolean
URL = {ref_URL}/extension/isWalkin
Allow In-Person Appointmentextension0-1Does 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 Appointmentextension0-1Does this schedule allow for remote appointments? (ie, video consultations) (default is false)Schedule.Extension.valueAsBoolean
URL = {ref_URL}/extension/allowRemoteAppointment
Minimum patient ageextension0-1Minimum patient age accepted – range 0 to 150 yrs (default is 0)Schedule. Extension.valueAsInt
URL ={ref_URL}/extension/minimumPatientAge
Maximum patient ageextension0-1Maximum patient age accepted – range 0 to 150 yrs (default is 150)Schedule. Extension.valueAsInt
URL ={ref_URL}/extension/maximumPatientAge
Booking Notice Hoursextension0-1Minimum 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 Languagesextension0-1List 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 Durationextension1-1Slot duration (in minutes) NOT including any admin interval.Schedule. Extension.valueAsInt
URL ={ref_URL}/extension/slotDuration
Admin Intervalextension0-1Admin interval (in minutes) – Period of time to be left between appointments for administrative activities.Schedule.Extension.valueAsInt
URL = {ref_URL}/extension/adminInterval
Estimated Priceextension0-1Estimated price in £GBP for serviceSchedule.Extension.valueAsDecimal
URL = {ref_URL}/extension/estimatedPrice
Booking Limitextension0-1Booking 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
CommentStringType0-1Comments/notes to make booking party aware of before making bookings.Schedule.comment
IdentifierResource0-*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,

FieldTypeDescription
Schedule.idStringSchedule ID

Error handling

HTTP Code Error Code Description
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
400INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference used is not valid
400INVALID_RESOURCESchedule resource is not valid
400MSG_CANT_PARSE_CONTENTSchedule failed to process
422MSG_CANT_TRANSFORM_CONTENT_TO_ENTITYFailed to read service category from FHIR
422RESOURCE_NOTT_FOUND_TEXTRequested resource does not exist in booking system
422DATA_INCONSISTENCYSubmitted resource is inconsistent with the data in booking system
403UNAUTHORISEDRequest 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
400MSG_OP_NOT_ALLOWEDSlots are already in use, cannot delete schedule
400INVALID_GDS_USERIDGDS UserID Invalid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
422INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference 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 idStringMSchedule 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
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
422INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference 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 StringOPractitioner for the schedule
location String OLocation for the schedule
start-date String ODate when the schedule starts
end-date String ODate when the schedule ends
id String OThe schedule id
service-category String OCategory of the service
specialty String OType of specialty associated with this schedule
available-day String ODay(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 OLatitude 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 OPostcode of location where service is available
estimated-price String OEstimated 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 OService provided by the schedule
allow-remote-appointmentbooleanOif 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-appointmentbooleanOIf 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 OSort results by start/end. Use _sort=start to sort results on start date in ascending order, or _sort=-start for descending order
_include String OTell the API to include Practitioner or Location resource in the result
_summary String OTell API to return only summary fields in response.
page String OPage index to be fetched {1,2,3..}
count String OMaximum records in a page
available-start-time String OStart time of availability
_since String OLast 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
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
422INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference 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 StringMStart 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 StringMEnd 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 OPractitioner(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 (*)StringOProfession (practitioner-role) code
specialty String OSpecialty (practitioner-specialty) code for the type of practitioner you wish to find.
subspecialtyStringOSub-specialty code (practitioner-subspecialty)for the type of practitioner you wish to find.
last-name (*)StringOLast name of the practitioner
first-name (*)StringOFirst (given) name of the practitioner
gender (*)StringOPractitioner’s gender – options male/female/other/unknown
service-type String OThe service-type code being provided by the Schedule
schedule String OSchedule ID that this Slot belongs to
durationStringORequired 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 OService Category ID used while creating the Schedule
communication-languageStringOIf 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-onlyStringOIf “true“, only the first available slot for each service-type for each practitioner will be returned. Default=false (ALL available slots returned)
_include String OTell the API to include additional resources in the results. Currently, the only option is ‘schedule‘.
_summary String OIf ‘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 OThe 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 OSearch 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 OSearch for slots where the start time is greater or equal to available-start-time
available-end-time String OSearch for slots where the end time is greater or equal to available-end-time
in-person-appointmentBooleanOIf 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-appointmentBooleanOIf 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-ageIntegerOIf specified, only slots that permit the specified patient age to be booked will be returned.
_sort String OSort 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 OTell the server to also include additional resources matching the search criteria. Options are Practitioner, Location, and HealthcareService.
pageStringOPage index to be fetched {1,2,3..}
countStringOMaximum 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,

FieldTypeDescription
Slot.idStringSlot ID
Schedule.idStringSchedule 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
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDThe referenced resource is not found
422INVALID_PARAMETERThe submitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMThe identifier system is not valid
400INVALID_IDENTIFIER_VALUEThe identifier value is not valid
422INVALID_RESOURCEThe submitted resource is not valid
422MISSING_MANDATORY_ELEMENTOne or more mandatory elements are missing
422INVALID_EXTENSIONThe submitted extension is not valid
422INVALID_REFERENCEThe 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
ScheduleReference1-1Schedule where this slot belongs toSlot.schedule.reference
StartDate1-1Start date/time of the slotSlot.start
EndDate1-1End date/time of the slotSlot.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,

FieldTypeDescription
details.coding.codeStringSlot Reservation ID

Error handling

HTTP Code Error Code Description
422MSG_LIMIT_EXCEEDEDSlot is already at its maximum capacity
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
422INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference 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 idStringMReservation 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
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource is found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID not found
422MSG_DATE_FORMATDate format is not valid
422INACTIVE_RESOURCEReservation 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
idStringReservation id received from earlier Reserve Slot API call.id
referenceStringSchedule reference, as used in the earlier Reserve Slot call.
startDateSlot start time, as used in the earlier Reserve Slot callslot.start
endDateSlot end time, as used in the earlier Reserve Slot callslot.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,

FieldTypeDescription
details.coding.codeStringSlot 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
422INACTIVE_RESOURCEExtending slot reservation is not allowed more than once.
400INVALID_GDS_USERIDGDS UserID is not valid
422REFERENCE_NOT_FOUNDReferenced resource is not found
422INVALID_PARAMETERSubmitted parameter is not valid
400INVALID_IDENTIFIER_SYSTEMIdentifier system is not valid
400INVALID_IDENTIFIER_VALUEIdentifier value is not valid
422INVALID_RESOURCESubmitted resource is not valid
422MISSING_MANDATORY_ELEMENTMandatory element is missing
422INVALID_EXTENSIONSubmitted extension is not valid
422INVALID_REFERENCEReference 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 IDReference1-1Reservation id received from earlier Reserve Slot API call.Appointment.identifier
CommentStringType0-1Comments 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
ParticipantArray1-*Participants of appointment e.g. practitioner, healthcareService, location etc (only Patient is mandatory)Appointment.participant
PatientReference1-1Reference of Patient Resource within this Appointment (usually “Patient/#1”)Appointment.participant.actor.patient
ReasonReference0-1Optional “Reason” resource (provides more detailed information than just the ReasonCode below, but usually not required for booking purposes)Appointment.reasonReference
ReasonCode CodeableConcept 0-1Optional (but recommended) “Reason” code for the appointment (also known as “Presenting Condition”, “Admission Diagnosis” or “Impairment Code”) taken from ICD9 coding systemAppointment.reasonCode
DescriptionStringType0-1Free-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)
SlotIdentifier1-1Slot resource containing reservation identifier
IdentifierIdentifier0-*One or more identifiers supplied by 3rd parties to help track this appointment.Appointment.Identifier.value
PriorityunsignedInt0-1Priority 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 priorityAppointment.priority
remoteAppointmentBoolean0-1Set 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 IDString1-1Internal Patient ref within THIS Appointment (usually ‘1’)Patient.id
Referral Type Extension 0-1Free 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-1Healthcode ID for patient’s insurance companyAppointment.Patient.Extension.valueString
URL = {ref_URL}/extension/patient/insurer
Registration ID Extension 0-1Patient’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-1Insurer’s Authorisation number for patient (Pre-auth) Appointment.Patient.Extension.valueString
URL = {ref_URL}/extension/patient/authorizationno}
GivenString1-1Patient’s first namePatient.Humanname.given
FamilyString1-1Patient’s last namePatient.Humanname.family
PrefixString0-1Patient’s titlePatient.Humanname.prefix
TelecomContactPoint1-*Patient’s contact telecom detailsPatient.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)
GenderAdministrativeGender1-1Patient’s genderPatient.gender
BirthDateString1-1Patient’s date of birth (YYYY-MM-DD) (*)Patient.birthdate
AddressAddress1-1Patient’s addressPatient.address (FHIR address field “period” is not supported, as the address is always assumed to be current)
nhsNumberString0-1Patient’s NHSIf 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,

FieldTypeDescription
AppointmentResponse.idStringNew unique ID for the newly created appointment
ParticipantStatusStringStatus of appointment. This is always “accepted” for newly booked appointments.
patientUrlStringLink for patient to open when joining video consultation. Not included for face-to-face appointments.
practitionerUrlStringLink for practitioner to open when starting the video consultation. Not included for face-to-face appointments.

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable entity
400MSG_INVALID_ID – “Slot does not allow remote appointments”Appointment was created using “remoteAppointment=true” but the schedule only allows for face-to-face appointments.
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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 TypeCodeable
Concept
0-1Appointment type – “style” of appointment, NOT the actual service type (i.e. walk-in, routine, emergency, etc) – all type codes are lowercase. Appointment.appointmenttype
DescriptionStringType0-1Description of appointment, similar to the subject line of an emailAppointment.descriphttps://www.hl7.org/fhir/R4/appointment-definitions.html#Appointment.descriptiontion
StartDate0-1Start date of appointmentAppointment.start
EndDate0-1End date of the appointmentAppointment.end
CommentStringType0-1Comments 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
ParticipantArray1-*Participants of appointment e.g. practitioner, healthcareService, location etc (only Patient is mandatory)Appointment.participant
PatientReference1-1Reference of Patient Resource within this Appointment (usually “Patient/#1”)Appointment.participant.actor.patient
RequiredBoolean0-1Required status of participant (assumes “required” if not specified)Appointment.participant.required
Participant StatusCodeable
Concept
0-1Status of participant (assumes “accepted” if not specified)Appointment.participant.status
ReasonReference0-1Optional “Reason” resource (provides more detailed information than just the ReasonCode below, but usually not required for booking purposes)Appointment.reasonReference
ReasonCodeCodeable
Concept
0-1Optional (but recommended) “Reason” code for the appointment (also known as “Presenting Condition”, “Admission Diagnosis” or “Impairment Code”) taken from ICD9 coding systemAppointment.reasonCode
Identifier0-*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
idString1-1Internal Patient ref within THIS Appointment (usually ‘1’) Patient.id
Referral TypeExtension0-1Free text string to describe where the referral is from,
e.g. “GP referral”
Appointment.Patient.Extension.valueString
URL = {ref_URL}/extension/patient/referralType
InsurerExtension0-1Healthcode ID for patient’s insurance companyAppointment.Patient.Extension.valueString
URL = {ref_URL}/extension/patient/insurer
Registration IDExtension0-1Patient’s insurance registration ID or patient ID recognised by calling applicationAppointment.Patient.Extension.valueString
URL = {ref_URL}extension/patient/registrationid
Authorization NoExtension0-1Insurer’s Authorisation number for patient (Pre-auth)Appointment.Patient.Extension.valueString
URL = {ref_URL}/extension/patient/authorizationno
GivenString1-1Patient’s first namePatient.Humanname.given
FamilyString1-1Patient’s last namePatient.Humanname.family
PrefixString0-1Patient’s titlePatient.Humanname.prefix
phoneTelecom?-1Patient’s telephone number (*)Patient.Telecom.Value (Where system = ‘phone’)
emailTelecom?-1Patient’s email address. If specified, this MUST be a valid address. (*)Patient.Telecom.Value (Where system = ‘email’)
gender AdministrativeGender 1-1Patient’s GenderPatient.gender
birth dateString1-1Patient’s date of birth (YYYY-MM-DD)Patient.birthdate
addressAddress1-1Patient’s addressPatient.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,

FieldTypeDescription
IdStringAppointment Response ID
ParticipantStatusStringStatus of appointment

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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}/valueset/appointment-cancellation-reason",
                "code": "PC100"
             }
       ]
    }

Where,

Name DataType Card. Description FHIR Field
IDReference1-1Appointment ID of an existing appointmentAppointment.identifier
StatusStringType0-1Valid options include “proposed, pending, booked, arrived, fulfilled, cancelled, noshow”Appointment.status
CommentStringType0-1Comments 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
DescriptionStringType0-1Description of appointment, similar to the subject line of an emailAppointment.description
PriorityunsignedInt0-1Priority 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 priorityAppointment.priority
cancelationReasonCodeableConcept0-1Healthcode “Cancellation Reason Code” for why an appointment was cancelled. Optional, but highly recommended. Should only be used when the Status is “cancelled”. Note the American spelling of “cancelation” in the field nameAppointment.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",
    "id": "20201127172539895LfDJ0022",
    "meta": {
        "lastUpdated": "2024-11-21T10:34:11.027+00:00"
    },

   "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"
            }
         ]
      }
   ],
   "status": "cancelled",
    "cancelationReason": {
        "coding": [
            {
                "system": "https://ice.api.healthcode.co.uk/valueset/appointment-cancellation-reason",
                "code": "PC100",
                "display": "Patient cancelled - Transport issues"
            }
        ]
    },
   "comment":"Updated comment",
   "description":"Updated description",
   "priority":2
}

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
400INVALID_RESOURCEUnprocessable Entity –
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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 OThe specialty code of a practitioner that would be required to perform the service requested in this appointment
Practitioner String OPractitioner ID who is attending the appointment
Location String OLocation ID where the appointment will be held
appointment-status String OStatus of appointment Multiple statuses may be specified, comma-separated.
service-category String OService category code for appointments
service-type StringOService Type code for appointments
Patient String OInternal Patient ID used for appointment
date-from String ODate from which the search needs to be done
date-to String ODate up to which the search needs to be done
identifierStringOMatch any external (3rd party/business) identifier
nhs-numberStringOMatch patient NHS number (includes CHI/IHI) recorded against appointments. This should be a 10-digit number with no punctuation.
Schedule String OOnly return appointments matching the Schedule ID specified.
_sortString Odate-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 ORequest server to return additional resources in the response. Valid options are: schedule, practitioner, location. Multiple options can be used, comma separated.
_since String OOnly return results that have been updated since the date/time specified (Format YYYY-M-DDThh:mm:ss)
_summaryStringOIf “true“, instructs API to only return reduced/summary details. Default is “false
pageStringOPage index to be fetched {1,2,3..}
countStringOMaximum 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,

FieldTypeDescription
Appointment.idStringAppointment ID
/extension/channelStringChannel id and name of system where booking originated
patientInstructionStringThis 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
400MSG_CANT_PARSE_CONTENTFailed to parse Appointment
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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
practitionerStringMPractitioner ID that needs to be applied
locationStringOLocation that will be marked as being unavailable for this practitioner. If omitted, the NotAvailable record will be applied across ALL locations.
descriptionStringMDescription/reason for notAvailable record
StartStringMStart datetime of the notAvailable
EndStringMEnd datetime of the notAvailable
identifierStringOBusiness 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,

FieldTypeDescription
idString Non-availability ID

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse NotAvailable
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID is not found
422MSG_DATE_FORMATDate 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.idStringMNotAvailable 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
400MSG_CANT_PARSE_CONTENTFailed to parse NotAvailable
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID not found
422MSG_DATE_FORMATDate 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 StringOPractitioner for whom the non-availability is defined
location String OLocation where the non-availability is applicable
_since String ODate from which the search needs to be performed
booking_identifier String ODefault booking ID for the resource
external_identifier String OExternal ID used while creating the resource in ICE by the calling application
pageStringOPage index to be fetched {1,2,3..}
countStringOMaximum 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,

FieldTypeDescription
idString NotAvailabe ID

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse NotAvailable
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID not found
422MSG_DATE_FORMATDate 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 StringOExact name of channel to search for
_since String OOnly search records created/updated since date specified (YYYY-MM-DDTHH:mm:SS)
pageStringOPage index to be fetched {1,2,3..}
countStringOMaximum 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,

FieldTypeDescription
valueString Channel ID
nameStringActual name of Channel
aliasStringAlternative name for this Channel

Error handling

HTTP Code Error Code Description
400MSG_CANT_PARSE_CONTENTFailed to parse NotAvailable
400MSG_MISSING_MANDATORY_PARAMMandatory parameter is missing
400MSG_INVALID_FORMATSubmitted parameter is not valid
400INVALID_RESOURCEUnprocessable Entity
422MSG_FAILED_TO_READ_ENTITYFailed to read entity from database
404MSG_ENTITY_NOT_FOUND_IN_DATABASENo matching resource found
422MSG_PARAM_INVALIDParameter content is not valid
422MSG_REFERENCE_ID_NOT_FOUNDReference ID not found
422MSG_DATE_FORMATDate format is not valid