Appointment Management Using APIs

Appointment Management Using APIs

Overview

PKB offers an Appointment Management capability in our UI, allowing a patient to securely message a team in the PKB organisation to say they wish to Cancel or Amend an appointment. This message then has to be read and acted upon by someone at the organisation.

These secure messages and the associated appointment information can be extracted via API, enabling the organisation to have more control over how requests are handled. For example, organisations can:

  • Route requests to specific individuals or teams

  • Create their own dashboards to handle the requests

  • Build their own reports to monitor the volume of requests per specialty over time

Workflow Description

  1. PKB organisation enables Appointment Management capability.

  2. The organisation sends appointments into PKB patient records (via HL7 or FHIR).

  3. Patients send secure messages to request to amend/cancel appointments.

  4. A clinician at the organisation “Grants Access” to enable the required data to be extracted.

  5. The organisation uses PKB’s APIs to:

    1. extract the secure message requests

    2. extract the appointment details

  6. The organisation displays the extracted information to the appropriate appointment management team.

  7. The appointment management team actions the patient requests within their own appointment system.

  8. The organisation sends the updated appointment information to PKB (via HL7 or FHIR).

API Details

This workflow uses a combination of custom REST APIs and our Aggregated FHIR API.

Grant Access

  1. A clinician who has access to the cancel / rebook messages sent by patients grants access to their PKB record.

    1. Access is granted to the credentials that PKB provides to the organisation for use with the PKB APIs.

  2. The resulting authorization code is exchanged for an access and refresh token pair.  

    1. Tokens will be managed and maintained by the customer to ensure the authorization is only done once.  

    2. A corrective workflow is required to obtain a new authorization code in the event a session breaks / expires.

Here is an example of a patient using this process, with links out to the key parts of our wiki.  The clinician follows the same steps, only the scope is changed to CLINICIAN.

Extract Messages

  1. Using a valid access token, retrieve the user’s messages in PKB, specifying which messages to return by supplying a specific timestamp as a parameter.

  2. Within the response, there are a few key elements to be aware of:

    1. The “subject” has the type of request (change or cancel) and the date, time, and appointment’s subject (from the HL7 feed) of the appointment.  You’ll need this to match to the appointment information from the aggregated endpoint.

    2. The “content” has the note that the patient added when making the request to change or cancel. 

    3. The “patientId” is the PKB id of the patient.  You’ll need this to obtain the patient’s national identifier.

curl --location 'https://sandbox.patientsknowbest.com/json/messages/after/2018-01-17' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer lJWcpd5weZhtTHsu-kQ20AfvgduoJsJy' \ --header 'Cookie: JSESSIONID=B3ED9547D61202250449B3A8D1B94176' /
[ { "id": "85b45f24-c7e6-4c7a-b9a3-73f51dfd1932", "messages": [ { "id": "134796117", "conversationId": "85b45f24-c7e6-4c7a-b9a3-73f51dfd1932", "subject": "Request to change appointment: Sunday 14 September 2025 12:00am - Emergency", "content": "i would like to change my appointment to another day please. Can you change it to 16th September 2025 if it is possible? ", "attachmentCount": 0, "attachments": null, "timestamp": 1756815121459, "senderId": "3054563", "onBehalfOfId": null, "htmlContent": false, "recipientIds": [ "14795070", "3054563" ], "patientId": "3054563", "messageStatus": "UNREAD" } ], "participants": [ { "id": "3054563", "firstName": "MCHFT", "lastName": "Pat01", "title": "", "teamName": "", "jobTitle": "" }, { "id": "14795070", "firstName": "Jack", "lastName": "Brown", "title": "", "teamName": "Appointment Management Team", "jobTitle": "Doctor" } ], "latestMessageId": 134796117, "messageCount": 1 }, ...

Identify the Patient

  1. Using a valid access token, and the PKB patientId from the message, get the national identifier for the patient.

  2. Call /json/v1/users/{userId}

curl --location 'https://sandbox.patientsknowbest.com/json/v1/users/3054563' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer lJWcpd5weZhtTHsu-kQ20AfvgduoJsJy' \ --header 'Cookie: JSESSIONID=B3ED9547D61202250449B3A8D1B94176'
{ "id": "3054563", "userType": null, "heightCm": null, "heightFeet": null, "heightInches": null, "heightInchesTotal": null, "weightKg": null, "weightLbs": null, "title": "Mrs", "firstName": "MCHFT", "lastName": "Pat01", "dob": "1980-01-01", "dateDeceased": null, "isDeceased": false, "genderMF": "f", "gender": "F", "email": "mchft_pa01@pkbtest.com", "phone": "07403529478", "address1": "1 Address Street", "address2": "", "city": "City", "state": "Country", "postalCode": "ST5 8ES", "country": "GB-ENG", "jobTitle": null, "organizationName": null, "teamName": null, "nationalIds": [ { "value": "9136220604", "name": "NHS number", "countryCodes": [ "GB-ENG", "GB-WLS" ] } ], "orgLevelIds": null, "teamLevelIds": null, "contacts": [ { "id": "20769", "contactType": "PHONE", "contactValue": "07403529478", "phoneUseType": "MOBILE_PHONE", "primary": true, "confirmed": false }, { "id": "3054564", "contactType": "EMAIL", "contactValue": "mchft_pa01@pkbtest.com", "phoneUseType": null, "primary": true, "confirmed": true } ], "patient": true }

Identify the Appointment

  1. Obtain an access token for the Aggregated FHIR endpoint.  Instructions here.

  2. Search the Aggregated endpoint for the patient’s appointment.  

    1. You must include the patient’s NHS number (or PKB public id) in the search.

    2. We support FHIR search parameters so you can use any other supported search parameter that would be helpful to identify the appointment.

    3. If you use the “status” search parameter with a value of “pending” that will bring back only the appointments that have been requested to be changed/cancelled.

  3. Your appointment id from the HL7 message is stored within the Appointment resource in the “identifier” element, with the system of: “http://fhir.patientsknowbest.com/id/external-identifier”

curl --location 'https://aggregated-fhir.sandbox.patientsknowbest.com/fhir/Appointment?actor%3APatient.identifier=https%3A%2F%2Ffhir.nhs.uk%2FId%2Fnhs-number%7C5137198994&date=2025-10-25' \ --header 'Authorization: Bearer ...'
{ "resourceType": "Bundle", "meta": { "versionId": "0", "lastUpdated": "2025-09-23T16:03:57.879+00:00" }, "type": "searchset", "total": 1, "link": [ { "relation": "first", "url": "/fhir/Appointment?actor:Patient.identifier=https://fhir.nhs.uk/Id/nhs-number%7C5137198994&date=2025-10-25&page=1" }, { "relation": "self", "url": "/fhir/Appointment?actor:Patient.identifier=https://fhir.nhs.uk/Id/nhs-number%7C5137198994&date=2025-10-25" } ], "entry": [ { "link": [ { "relation": "self", "url": "https://sandboxaggregated.fhir-api.sandbox.patientsknowbest.com/Appointment/2f6de2c8-43d6-3d30-9920-1cecc40e972f" } ], "fullUrl": "https://sandboxaggregated.fhir-api.sandbox.patientsknowbest.com/Appointment/2f6de2c8-43d6-3d30-9920-1cecc40e972f", "resource": { "resourceType": "Appointment", "id": "2f6de2c8-43d6-3d30-9920-1cecc40e972f", "meta": { "extension": [ { "url": "http://fhir.patientsknowbest.com/structuredefinition/uploaded-data-id", "valueString": "14476030" }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/recorded-date", "valueDateTime": "2025-01-30T15:16:55.000+00:00" }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/partner-identifier", "valueReference": { "identifier": { "system": "urn:uuid:cd97da65-0aa4-43a6-b695-cfd0c6f3267d", "value": "238bcad5-a4ce-49e0-a944-ebd58ea076da" } } }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/version-persisted", "valueDateTime": "2025-02-14T14:32:08.660+00:00" }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/access-route", "valueCoding": { "system": "http://fhir.patientsknowbest.com/codesystem/access-route", "code": "HL7_API", "display": "Integration (HL7)" } }, { "url": "ex:createdAt", "valueInstant": "2025-02-14T14:30:50.523820Z" } ], "versionId": "8286325", "lastUpdated": "2025-08-13T11:34:51.467777Z", "security": [ { "system": "http://fhir.patientsknowbest.com/codesystem/source-organization", "code": "3bd83e49-bc53-37d6-af7f-0398cf4689bc", "display": "Muse GP" }, { "system": "http://fhir.patientsknowbest.com/codesystem/connecting-org", "code": "3bd83e49-bc53-37d6-af7f-0398cf4689bc", "display": "Muse GP" }, { "system": "http://fhir.patientsknowbest.com/codesystem/privacy-label", "code": "GENERAL_HEALTH" } ] }, "extension": [ { "url": "http://fhir.patientsknowbest.com/structuredefinition/notification-control", "extension": [ { "url": "http://fhir.patientsknowbest.com/structuredefinition/notification-suppressed", "valueBoolean": true }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/notification-controlled-by", "valueString": "OUR_CODE" }, { "url": "http://fhir.patientsknowbest.com/structuredefinition/notification-target-list", "valueString": "[]" } ] }, { "url": "https://fhir.nhs.uk/StructureDefinition/Extension-Portal-Link", "valueUrl": "https://sandbox.patientsknowbest.com/nhs-login/login?phrPath=%2Fdiary%2FviewAppointment.action%3FuniqueId%3D2f6de2c8-43d6-3d30-9920-1cecc40e972f%26style%3Dnhs-england" } ], "identifier": [ { "system": "http://fhir.patientsknowbest.com/id/menudata-legacy-identifier", "value": "134707934" }, { "system": "http://fhir.patientsknowbest.com/id/common-identifier", "value": "e22fe762-f7a1-4d61-9d45-6f03e766195a" }, { "system": "http://fhir.patientsknowbest.com/id/external-identifier", "value": "112431409e" } ], "status": "booked", "specialty": [ { "coding": [ { "code": "SPEC_03", "display": "SPEC_03" } ] } ], "appointmentType": { "coding": [ { "display": "What's the specialty say" } ] }, "start": "2025-10-25T13:30:00.000+00:00", "_end": { "extension": [ { "url": "http://hl7.org/fhir/StructureDefinition/data-absent-reason", "valueCode": "unknown" } ] }, "participant": [ { "actor": { "reference": "Patient/beb67e3a-234e-3df9-a043-48f4931fa565", "display": "Mr Paul Peel" }, "status": "accepted" }, { "actor": { "type": "Location", "display": "The best GP in the UK" }, "status": "accepted" } ] }, "search": { "mode": "match" } } ] }

Appointment Amended at Source

Using the information obtained above (appointment id and message content), the team at the trust amends the appointment.  The resulting change flows into PKB via the existing appointment feed.

Patients Know Best Resource Hub | Deploy | Developer | Trust Centre | Manual | Research | Education | Release Notes

© Patients Know Best, Ltd. Registered in England and Wales Number: 6517382. VAT Number: GB 944 9739 67.