Argo-Scheduling Implementation Guide Release 1.0.0

This page is part of the Argonaut Scheduling Implementation Guide (v1.0.0: Release) based on FHIR R3. This is the current published version in it's permanent home (it will always be available at this URL). For a full list of available versions, see the Directory of published versions

Patient based Scheduling Use Cases

Introduction

The Argonaut Scheduling Implementation Guide defines a series of interactions which cover the basic appointment creation workflow for patient based scheduling which includes: registration of patients and updating coverage information, discovery of available appointments and booking the canceling appointments. It also covers patient access to their appointments. The basic workflow steps and Argonaut Scheduling APIs for three use cases are detailed below.

Use Case 1: Patient Portal Scheduling for existing patients

This use case is focused on a patient scheduling through a healthcare organization’s patient portal. The patient may be trying to book an appointment to see a particular Practitioner or for a service to be performed.

Preconditions:

  • Patient has relationship to health system
  • Patient uses a “patient portal” - an application hosted by his provider.
  • User level login and trust

Scenario 1a: Existing Patient schedules directly with their provider

This simple scenario serves as an effective means to scale up the complexity toward subsequent scenarios

Patient: Hal has been with his PCP for several years. Hal has some severe back pain
         and wants to see his PCP, Dr Y, as soon as possible (today, or tomorrow at the latest).

Scenario 1b: Existing Patient schedules a service directly with their health care service

This scenario is the same as 1a except a Service or Specialty instead of a specific Provider is being scheduled.

Patient: Hal has been with his PCP for several years. Hal has some severe back pain and sees his PCP who
         ordered an imaging study.  Hal will be scheduling the study within the health care service.

Patient Portal Scheduling for new or existing patient.
diagrams/Slide28.png

Patient login

Before a patient can begin, she must login in to the patient portal. This step MAY include updating or confirmation of patient and insurance coverage information.

Patient login.
diagrams/Slide05.png

The patient ID is returned or known. See the Login and Trust Section for details.

  • Updates to patient demographic information MAY be included in the login step for some systems. However the interactions to update this information are outside the scope of this specification
  • Updates to patient insurance coverage information are detailed in Use Case 2 Step 4 below

This step is the key transaction for this scheduling Use case. It asks the questions: when to book? It is dynamic and complex because of multiple dependencies.

Appointment Availability Discovery and Search.
diagrams/Slide30.png

Based on the set of input parameters supplied by the Client, the Server determines which schedulable “assets” are needed for the visit and returns a set of possible Appointment times where all required assets are available. The scope of this guide is limited to the available appointments based on the following “simple” inputs:

  • practitioner
  • available times
  • location
  • specialty
  • set of common visit types.

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

Using Both GET and POST Syntax the operation can be invoked as follows:

GET [base]/Appointment/$find?{parameters}&?{_count}

POST [base]/Appointment/$find?{_count}

Scenario 1a:

Use the operation to fetch a maximum of the soonest 3 open appointments available within the next 2 days for Dr Y at the Napa location.

Request using GET

GET [base]/Appointment/$find?start=2017-07-15T20:00:00Z&end=2017-07-17T20:00:00Z&provider=Practitioner/dr-y&location=Napa&_count=3

Request using POST

POST [base]/Appointment/$find&_count=3

Request body

    {
      "resourceType": "Parameters",
      "parameter": [
        {
          "name": "start",
          "valueDateTime" : "2017-07-15T20:00:00Z"
        },
        {
          "name": "end",
            "valueDateTime" : "2017-07-17T20:00:00Z"
        },
        {
          "name": "provider",
          "valueUri": ["Practitioner/dr-y"]
          }
        },
        {
          "name": "location",
          "valueString": ["Napa"]
        }
    ]
    }

Response

HTTP/1.1 200 OK
[other headers]

Response body

    {
      "resourceType": "Bundle",
      "id": "hal-dr-y-appts",
      "type": "searchset",
      "total": 3,
      "entry": [{
        "fullUrl": "http://server/path/Appointment/proposed-appt-1",
        "resource": {
          "resourceType": "Appointment",
          "id": "proposed-appt-1",
          .. snip ...
        },
        "fullUrl": "http://server/path/Appointment/proposed-appt-2",
        "resource": {
          "resourceType": "Appointment",
          "id": "proposed-appt-2",
          .. snip ...
        },
        "fullUrl": "http://server/path/Appointment/proposed-appt-3",
        "resource": {
          "resourceType": "Appointment",
          "id": "proposed-appt-3",
          .. snip ...
        },
        "fullUrl": "http://server/path/OperationOutcome/oo-for-dr-y-appts",
        "resource": {
          "resourceType": "OperationOutcome",
          "id": "oo-for-dr-y-appts",
          .. snip ...
        }
      ]
    }


Optional Hold Appointment Operation

This operation puts to appointment in a hold status to temporarily prevent the appointment from being booked by another client. This optional step may be needed to allow the end-user to complete additional steps such as end user data entry before the booking can be completed.

Hold Appointment.
diagrams/Slide31.png

The Client sends a hold request operation using the id of selected proposed appointment as the input parameter. The Server determines if and how long the appointment can be held and returns the Appointment resource with with an updated status if successful. The Releasing Holds section below describes how to release the hold before it expires. See the Appointment State Diagram for further details on statuses.

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

POST [base]/Appointment/[id]/$hold

Request

POST [base]/Appointment/proposed-appt1a-1/$hold

Request body

    {
      "resourceType": "Parameters",
      "parameter": [
        {
          "name": "appt-id",
          "valueUrl" : "Appointment/proposed-appt1a-1"
        }
      ]
    }

Response

HTTP/1.1 200 OK
Expires: Wed, 21 March 2018 07:28:00 GMT
[other headers]

Response body

    {
      "resourceType": "Bundle",
      "id": "hal-dr-y-held",
      "type": "searchset",
      "total": 2,
      "entry": [{
        "fullUrl": "http://server/path/Appointment/booked-appt1a",
        "resource": {
          "resourceType": "Appointment",
          "id": "held-appt1a",
          ...snip...
            "status" : "pending",
            "serviceType" : [
          ...snip...
        "fullUrl": "http://server/path/OperationOutcome/oo-held-appt1a",
        "resource": {
          "resourceType": "OperationOutcome",
          "id": "oo-held-appt1a-appt1a",
          .. snip ...
        }
      ]
    }


Book Appointment

The actual booking of the appointment is completed in this step and the scheduling step is completed.

Book Appointment.
diagrams/Slide32.png

The Client sends a book operation using the id of selected proposed appointment, the patient(s) id and optionally any comments as the input parameters. The Server determines if the appointment can be booked and returns the Appointment resource with with an updated status. See the Appointment State Diagram for further details on statuses.

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

POST [base]/Appointment/[id]/$book

Request

POST [base]/Appointment/proposed-appt2a-1/$book

Request body

    {
      "resourceType": "Parameters",
      "parameter": [
        {
          "name": "appt-id",
          "valueUrl" : "Appointment/proposed-appt2a-1"
        },
        {
          "name": "patient-id",
            "valueUrl" : "Patient/1234"
        }
    ]
    }

Response

HTTP/1.1 200 OK
[other headers]

Response body

        {
          "resourceType": "Bundle",
          "id": "derm-booked",
          "type": "searchset",
          "total": 1,
          "entry": [{
            "fullUrl": "http://server/path/Appointment/booked-derm-appt",
            "resource": {
              "resourceType": "Appointment",
              "id": "booked-derm-appt",
              ...snip...
                "status" : "booked",
                "serviceType" : [
              ...snip...
            ]
            "entry": [{
            "fullUrl": "http://server/path/OperationOutcome/oo-booked-derm-appt",
            "resource": {
              "resourceType": "OperationOutcome",
              "id": "oo-booked-derm-appt",
              .. snip ...
            }
          ]
        }


Use Case 2: Open Scheduling for new patient or existing patient

This use case is focused on scheduling through a third-party application where the patient is either a new or existing patient. In either case, the patient doesn’t need to be registered or logged in with the EHR to search for an open Appointment - which is defined as “Open scheduling” for this guide. The patient may be trying to book an appointment to see a particular Practitioner or for a service to be performed. The primary difference between Use Case 2 and Use Case 1 above are the registration steps. The primary difference between Use Case 2 and Use Case 3 below is fetching data in real time in contrast to prefetching scheduling data

Preconditions:

  • New or existing patient
  • Patient uses a third-party application to schedule an appointment
  • Open scheduling model
  • User level Login and trust
  • Fetching available appointments in real time

Scenario 2a. New Patient Schedules an Appointment with a Provider without being in health system

Patient: Bruce just moved to the area, has a rash.  He wants to set up an appointment with Dr X as soon as
         possible (within a week or so)

Scenario 2b. Patient Discovers and Schedules a Service without being in a health system

Patient: Bruce just moved to the area, has a rash.  He wants to set up an appointment with a local
        dermatologist as soon as possible (within a week or so).

In Scenario 2a and 2b we have introduced the complexities of a new patient and a consumer facing 3rd party application to schedule the appointment. Scenario 2b is the same as 2a except a Service or Specialty instead of a specific Provider is being scheduled.


Open Scheduling for new or existing patient.
diagrams/Slide29.png

Patient Registration Option A

For this scenario a new patient will need to be registered or an existing patient fetched prior to booking. This MAY occur at this step or prior to booking. This step is discussed in detail in step 4 below.

Appointment Availability Discovery and Search

This step is the key transaction for this Scheduling Use Case. It asks the questions: when to book? It is dynamic and complex because of multiple dependencies.

Appointment Availability Discovery and Search.
diagrams/Slide03.png

This step is the same as described in Scenario-1.

Optional Hold Appointment Operation

This operation puts to appointment in a hold status to temporarily prevent the appointment from being booked by another client. This step is not optional if the patient was not registered in step 1 above. It is needed in order to register the patient prior to booking the appointment.

Optional Hold Appointment Operation.
diagrams/Slide04.png

The details of this step are the same as described in Scenario-1. The Releasing Holds section below describes how to release the hold before it expires.

Patient Registration Option B

A new patient will need to be registered or an existing patient fetched prior to actually booking the appointment. This MAY occur at this step prior to booking the appointment or at the beginning of the workflow in step 1. This step MAY include updating or confirmation of patient and insurance coverage information as well.

Patient Registration.
diagrams/Slide12.png

Registering or Fetching a Patient:

Usage
Existing Patients

To fetch an existing patient resource id, the Client SHALL follow the guidance in the US Core Patient Profile which use the standard FHIR RESTful search API

For example fetching a patient by an identifier such as an MRN using:

GET [base]/Patient?identifier=[system]|[code]

For example fetching a patient by name, gender and birthdate using:

GET [base]/Patient?family=[name]&?given=[name]&gender=[gender]

New Patients

To register a new patient, The Client SHALL use the standard FHIR RESTful create API as follows:

POST [base]/Patient

In response to this transaction, the server SHOULD create a new patient resource only if the patient resource does not already exist in the system. If the patient is already registered within the system, the existing patient resource SHOULD be returned. Note that the Client SHALL not use the ‘If-None-Exist’ header as described in FHIR conditional create API).

Request

POST [base]/Patient

Request body

{
  "resourceType" : "Patient",
  "meta" : {
    "profile" : [
      "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
    ]
  },
...snip...
  "active" : true,
  "name" : [
    {
      "family" : "Shaw",
      "given" : [
        "Amy",
        "V."
      ]
    }
  "gender" : "female",
  "birthDate" : "2007-02-20",
...snip...
}

Response

HTTP/1.1 201 Created
Location: [base]/Patient/server-id-123/_history/1
[other headers]


Updating or Creating Patient Coverage Information:

Updates to patient coverage information MAY be associated with the login and registration steps for some systems or as a distinct step following booking.

API

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

To update the existing insurance information or create it if it is new, The Client uses the standard FHIR RESTful update and create API as shown:

  • update: PUT [base]/Coverage/[id]
  • create: PUT or POST [base]/Coverage

​Note that the server MAY reject certain updates to the coverage information (for example, type of coverage) and SHOULD return an OperationOutcome explaining the reason.

Request to create Coverage resource for patients

POST [base]/Coverage

Request body

{
  "resourceType" : "Coverage",
  "identifier" : [
    {
      "system" : "https://www.anthem.com/ca",
      "value" : "DZW9200000000"
    }
  ],
  "status" : "active",
  ...snip...
  "period" : {
    "start" : "2016-01-01"
  },
  "payor" : [
    {
      "display" : "Anthem Blue Cross of California"
    }
  ],
  "grouping" : {
    "plan" : "1FZQ",
    "planDisplay" : "Anthem Bronze 60 D HSA PPO"
  }
}

Response

HTTP/1.1 201 Created
Location: [base]/Coverage/argo-sch-1/_history/1
[other headers]

Request to update Coverage to extend coverage period

PUT [base]/Coverage/argo-sch-1

Request body

{
  "resourceType" : "Coverage",
  "id" : "argo-sch-1",
  "identifier" : [
    {
      "system" : "https://www.anthem.com/ca",
      "value" : "DZW9200000000"
    }
  ],
  "status" : "active",
  ...snip...
  "period" : {
    "start" : "2018-01-01"
  },
  "payor" : [
    {
      "display" : "Anthem Blue Cross of California"
    }
  ],
  "grouping" : {
    "plan" : "1FZQ",
    "planDisplay" : "Anthem Bronze 60 D HSA PPO"
  }
}

Response

HTTP/1.1 200 OK
Location: [base]/Coverage/argo-sch-1/_history/2
[other headers]


Book Appointment

After the patient is registered, the actual booking interaction can occur.

Book Appointment.
diagrams/Slide06.png

This step is the same as described in Scenario-1.

Patient Coverage Update Option C

For some systems, updating or confirmation of insurance coverage information MAY occur at this step after booking. The Coverage interaction is discussed in detail in step 4 above.

Use Case 3 Prefetching Open Slots

As in Use Case 2 above, this use case is focused on scheduling through a third-party application where the patient is either a new or existing patient. The patient may be trying to book an appointment to see a particular Practitioner or for a service to be performed. In contrast to determining available appointments in real-time, in this use case: 1) the scheduling data is fetched prior to the end user request as FHIR Slots, 2) the appointment availability is based upon third party application business rules, and 3) a valid appointment resources created and exchanged with the scheduling server (EHR). This is defined as “prefetching” for this guide.

Preconditions:

  • New or existing patient
  • Patient uses a third-party application to schedule an appointment
  • Open scheduling model
  • User level Login and trust
  • Third Party App able to acquire:
    • Scheduling business rules for target organization
    • At a minimum FHIR resource ids for Location and Practitioner
    • Accepts subscription notifications
  • FHIR Scheduling Server:
    • Supports FHIR event based subscriptions
    • Allows writing of Appointments by 3rd party applications

Scenario 3a. New Patient Schedules an Appointment with a Provider without being in health system

Patient: Bruce just moved to the area, has a rash.  He wants to set up an appointment with Dr X as soon as
         possible (within a week or so)

Scenario 3b. Patient Discovers and Schedules a Service without being in a health system

Patient: Bruce just moved to the area, has a rash.  He wants to set up an appointment with a local
        dermatologist as soon as possible (within a week or so).

In Scenario 3a and 3b we have introduced the complexities of a new patient and a consumer facing 3rd party application to schedule the appointment. Scenario 3b is the same as 3a except a Service or Specialty instead of a specific Provider is being scheduled.


Prefetching Open Slots.
diagrams/Slide37.png

Open Scheduling for new or existing patients.
diagrams/Slide42.png

Share Business Rules

The EHR/Hospital shares the business rules and logic for creating an appointment for a particular service with the third-party application. For example, which assets are needed and determination of whether the shared slot are a fixed size (e.g., 5 or 15 minutes) or variable sized slots. This is typically an “out of band” transaction and a FHIR based transaction is out of scope for this IG.

Share Business Rules.
diagrams/Slide08.png

Subscribe for Schedule Change Notifications

The third-party application subscribes to the FHIR Scheduler to receive notifications of schedule changes for the a provider, facility, device, etc depending on the system. The notification of the schedule change informs the client which slots to prefetch to update their slot data. For example, Provider X has 6 new appointments booked triggering the FHIR Scheduler to send 6 notifications to the subscriber. The notification triggers are based upon the Slot events and SHALL include:

  1. Slots that are open to prefetching have a change of status
  2. Slots that are open to prefetching have a change of visit type
  3. Slots that were previously open to prefetching are no longer open to prefetching

and MAY include additional triggers. Note that the notification payload is the Schedule resource associated with the Slot that triggered the event. A “hearbeat” notification should also be sent with a site specific frequency and should not contain a payload.

Subscribe for Schedule Change Notifications.
diagrams/Slide43.png

API

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

To subscribe for notfications of schedule changes, The Client SHALL use the standard FHIR Subscription API as follows:

POST [base]/Subscription

To unsubscribe:

Delete [base]/Subscription/[id]

Subscribe

POST [base]/Subscription

Request body

    {
      "resourceType": "Subscription",
      "id": "example",
      "status": "active",
      "reason": "Notify subscriber of schedule changes to trigger the subscriber prefetch updated slots",
      "_criteria": {
        "extension": [
          {
            "url": "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/extension-subscription-triggerevent",
            "valueString": "schedule where any slot that reference it has changed"
          },
          {
            "url": "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/extension-subscription-eventfocus",
            "valueCode": "Schedule"
          }
        ]
      },
      "channel": {
        "extension": [
          {
            "url": "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/extension-subscription-payloadprofile",
            "valueUri": "//fhir.org/guides/argonaut-scheduling/StructureDefinition/argo-sched-notif"
          }
        ],
        "type": "rest-hook",
        "endpoint": "https://feed-handler.com/notification",
        "payload": "application/fhir+json"
      }
    }

Response

HTTP/1.1 200 OK
[other headers]


Initial Load

The third-party application fetches the “initial load” of open slots to get all the data needed supporting the creation of new appointments. The query is made for the maximum date ranges for the available slots for each provider or service and is typically repeated daily to reset or to resynchronize its information with a scheduling server.

Initial Load.
diagrams/Slide14.png

API

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

Using Both GET and POST Syntax the operation can be invoked as follows to fetch all open slots for the maximum period of time for relevant Practitioners, Locations and Services:

GET [base]/Slot/$prefetch?{parameters}

POST [base]/Slot/$prefetch

Prefetch open slots from July 15,2017 to August 17,2017

Request using GET Syntax

GET [base]/Slot/$prefetch?start=2017-07-15T20:00:00Z&end=2017-07-17T20:00:00Z

Request using POST Syntax

POST [base]/Slot/$prefetch

Post request body

    {
      "resourceType": "Parameters",
      "parameter": [
        {
          "name": "start",
          "valueDateTime" : "2017-07-15T20:00:00Z"
        },
        {
          "name": "end",
            "valueDateTime" : "2017-07-17T20:00:00Z"
        }
    ]
    }

Response

HTTP/1.1 200 OK
[other headers]

Response body

    {
      "resourceType": "Bundle",
      "id": "prefetch-1",
      "type": "searchset",
      "total": 1000,
      "entry": [{
        "fullUrl": "http://server/path/Slot/1",
        "resource": {
          "resourceType": "Slot",
          "id": "1",
          .. snip ...
          "status":"free"
          .. snip ...
        },
        "fullUrl": "http://server/path/Slot/2",
        "resource": {
          "resourceType": "Slot",
          "id": "2",
          .. snip ...
          "status":"free"
          .. snip ...
        },
        "fullUrl": "http://server/path/Slot/3",
        "resource": {
          "resourceType": "Slot",
          "id": "3",
          .. snip ...
          "status":"free"
          .. snip ...
        },
        "fullUrl": "http://server/path/OperationOutcome/oo-for-prefetch",
        "resource": {
          "resourceType": "OperationOutcome",
          "id": "oo-for-prefetch",
          .. snip ...
        }
      ]
    }


Notification of schedule changes

After subscribing with the FHIR Scheduler and fetching the initial load, the third-party application receives notifications from the FHIR Scheduler of schedule changes as well as “heartbeat” notifications as described above. For a notification triggered by a schedule change, the notification payload is a Schedule resource containing the actor (e.g, provider, device or location) and date range (usually a day). In a “heartbeat” notification the payload is absent. There are several architectures to implement the subscription notifications such as using a “feed handler” depicted in figure below.

Notification of schedule changes.
diagrams/Slide44.png

API

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

The standard FHIR Subscription API describe the REST Hook channel as follows:

POST [app notification endpoint]

Notification of schedule change:

POST https://feed-handler.com/notification

Notification body

{
  "resourceType" : "Schedule",
  "id" : "example1",
  "actor" : [
    {
      "reference" : Practitioner/dr-y,
      "display" : "Crusher, Beverly"
    }
  ],
  "planningHorizon" : {
    "start" : "2018-02-13",
    "end" : "2018-02-13"
  }
}
“Heartbeat” Notification:
POST https://feed-handler.com/notification

**** No notification body****


“Smart Polling” for Updated Slots

When the Client is notified of schedule changes, it can fetch the slots based on the actor and time period in the notification’s payload and update its prefetched slot data. Notifications beyond the Client’s time horizon are ignored.

'Smart Polling' for Updated Slots.
diagrams/Slide45.png

API

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

This transaction is the same as for the Initial Load. Using Both GET and POST Syntax the operation can be invoked as follows to fetch all open slots for the notification period of time for relevant actor:

GET [base]/Slot/$prefetch?{parameters}

POST [base]/Slot/$prefetch

Request usingPOST syntax

POST [base]/Slot/$prefetch

Request body

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "practitioner",
      "valueDateTime" : "Practitioner/123"
    },
    {
      "name": "start",
      "valueDateTime" : "2017-07-15T00:00:00Z"
    },
    {
      "name": "end",
        "valueDateTime" : "2017-07-15T24:00:00Z"
    }
]}

Response

HTTP/1.1 200 OK
[other headers]

Response body

{
  "resourceType": "Bundle",
  "id": "prefetch-1",
  "type": "searchset",
  "total": 8,
  "entry": [{
    "fullUrl": "http://server/path/Slot/20170715240000-123",
    "resource": {
      "resourceType": "Slot",
      "id": "20170715240000-123",
      .. snip ...
      "status":"free"
      .. snip ...
    }
  ]}


Patient Registration Option A

This step is identical to Scenario 2 Step 1. above.

Appointment Availability Discovery and Search

Based on the shared business rules and user input, the client application server is able to create available appointments from the prefetched slot information and return them to the end user. How this is done is application specific and out of scope for this guide.

Appointment Availability Discovery and Search.
diagrams/Slide10.png

The FHIR RESTful based interactions are the same as described in Scenario-1 Step 2. with the key difference that the role of the FHIR Scheduler (EHR) is replaced by the Client Application Server. Other non-FHIR based solutions are possible as well.

Optional Hold Appointment Operation

After the end user selects a preferred appointment time. There may be additional steps such as end user data entry prior to actually booking the appointment. The Client Application may request FHIR Scheduler (EHR) to hold this appointment to prevent it from being taken by another user.

Optional Hold Appointment Operation.
diagrams/Slide04.png

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

This step is similar to Scenario 2 Step 5 above. However, in this case the Client generates an Argonaut Appointment Profile resource and exchanges it with the FHIR Scheduler. The Releasing Holds section below describes how to release the hold before it expires. Using the POST Syntax the operation can be invoked as follows:

POST [base]/Appointment/$hold

The payload may be either use the Appointment resource directly or the Parameters format as shown in the examples below:

Request

POST [base]/Appointment/$hold

Appointment resource as request body

{
  "resourceType" : "Appointment",
...snip...
  "status" : "proposed",
  "serviceType" : [
...snip...
  "start" : "2017-07-17T01:00:00Z",
  "end" : "2017-07-17T01:15:00Z",
  "participant" : [
    {
      "actor" : {
        "reference" : "Practitioner/dr-y",
        "display" : "Dr Y"
...snip...
}

Parameter format as request body

      {
        "resourceType": "Parameters",
        "parameter": [
          {
            "name": "appt-resource",
            "resource":{
                        "resourceType" : "Appointment",
                        "id" : "proposed-appt2",
                      ...snip...
                        "status" : "proposed",
                        "serviceType" : [
                      ...snip...
                        "start" : "2017-07-17T01:00:00Z",
                        "end" : "2017-07-17T01:15:00Z",
                        "participant" : [
                          {
                            "actor" : {
                              "reference" : "Practitioner/dr-y",
                              "display" : "Dr Y"
                      ...snip...
            }

          }
        ]
      }

Response

HTTP/1.1 201 Created
Location: [base]/Appointment/argo-appt-1/_history/1
Expires: Wed, 21 March 2018 07:28:00 GMT
[other headers]

Response body

    {
      "resourceType": "Bundle",
      "id": "argo-appt-1",
      "type": "searchset",
      "total": 2,
      "entry": [{
        "fullUrl": "http://server/path/Appointment/scheduled-appt2a",
        "resource": {
          "resourceType": "Appointment",
          "id": "held-appt2a",
          ...snip ...
          "status" : "pending",
          "serviceType" : [
        ...snip...
        "fullUrl": "http://server/path/OperationOutcome/oo-held-appt1a",
        "resource": {
          "resourceType": "OperationOutcome",
          "id": "oo-held-appt1a-appt1a",
          .. snip ...
        }
      ]
    }


Patient Registration Option B

This step is identical to Scenario 2 Step 4 above.

Book Appointment

The Client is ready to actually book the appointment and the request to book the selected Appointment is made to the FHIR Scheduler (EHR).

Book Appointment Operation.
diagrams/Slide06.png

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

If the Hold Appointment Operation step was done, this step the same as Scenario 2 Step 5 above. The Client references the FHIR Scheduler supplied id from the hold response when booking the appointment. If the Hold Appointment Operation step was skipped, then the Client creates an Argonaut Appointment Profile resource and exchanges it with the FHIR Scheduler. The operation is invoked as follows:

POST [base]/Appointment/$book

The payload may be either use the Appointment resource directly or the Parameters format as shown in the examples below:

Request

POST [base]/Appointment/$book

Appointment resource as request body

{
  "resourceType" : "Appointment",
...snip...
  "status" : "pending",
  "serviceType" : [
...snip...
  "start" : "2017-07-17T01:00:00Z",
  "end" : "2017-07-17T01:15:00Z",
  "participant" : [
    {
      "actor" : {
        "reference" : "Practitioner/dr-y",
        "display" : "Dr Y"
...snip...
}

Parameter format as request body

      {
        "resourceType": "Parameters",
        "parameter": [
          {
            "name": "appt-resource",
            "resource":{
                        "resourceType" : "Appointment",
                        "id" : "proposed-appt2",
                      ...snip...
                        "status" : "pending",
                        "serviceType" : [
                      ...snip...
                        "start" : "2017-07-17T01:00:00Z",
                        "end" : "2017-07-17T01:15:00Z",
                        "participant" : [
                          {
                            "actor" : {
                              "reference" : "Practitioner/dr-y",
                              "display" : "Dr Y"
                      ...snip...
            }

          }
        ]
      }

Response

HTTP/1.1 201 Created
Location: [base]/Appointment/argo-appt-1/_history/1
[other headers]

Response body


    {
      "resourceType": "Bundle",
      "id": "argo-appt-1",
      "type": "searchset",
      "total": 2,
      "entry": [{
        "fullUrl": "http://server/path/Appointment/scheduled-appt2a",
        "resource": {
          "resourceType": "Appointment",
          "id": "held-appt2a",
          ...snip...
            "status" : "booked",
            "serviceType" : [
          ...snip...
        "fullUrl": "http://server/path/OperationOutcome/oo-held-appt1a",
        "resource": {
          "resourceType": "OperationOutcome",
          "id": "oo-held-appt1a-appt1a",
          .. snip ...
        }
      ]
    }


Patient Coverage Update Option C

For some systems, updating or confirmation of insurance coverage information MAY occur at this step after booking. The Coverage interaction is discussed in detail in Scenario 2 Step 4 above.

Canceling/Rescheduling Appointments

The end user may elect to cancel or reschedule an existing appointment. Rescheduling is a two step process of canceling and rebooking a new appointment.

Patient Canceling/Rescheduling Appointments.
diagrams/Slide33.png

Canceling and Rescheduling has the potential to introduces complex failure states. The best practices guidance discusses how failures should be handled. See the Appointment State Diagram for further details on statuses and state transitions.

Usage

To cancel an appointment the Client uses the standard FHIR PATCH transaction as shown:

PATCH [Base]/Appointment/[id]

  • optional input parameter:

    1. cancel reason code or string
  • Note the Server SHALL declare support for JSON, XML, or FHIRPath Patch in the CapabilityStatement

Target Appointment:

{
  "resourceType" : "Appointment",
  "id" : "argo-appt1",
  "meta" : {
    "profile" : [
      "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/argo-appt"
    ]
  },
  "text" : {
  ...snip...
  },
  "status" : "booked",
  "serviceType" : [
  ...snip...

Cancel using JSON PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 [
 { "op": "replace", "path": "/status", "value": "cancelled" },
 ]

Cancel using XML PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 <?xml version="1.0" encoding="UTF-8"?>
 <diff xmlns="http://hl7.org/fhir">
   <replace sel="Appointment/status/@value">cancelled</replace>
 </diff>

Cancel using FHIRPath PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 **payload**
 <?xml version="1.0" encoding="UTF-8"?>
 <Parameters xmlns="http://hl7.org/fhir">
   <parameter>
     <name value="operation"/>
     <part>
       <name value="type"/>
       <valueCode value="replace"/>
     </part>
     <part>
       <name value="path"/>
       <valueString value="status"/>
     </part>
     <part>
       <name value="value"/>
       <valueCode value="cancelled"/>
     </part>
   </parameter>
 </Parameters>

Response

HTTP/1.1 200 OK
Location: [base]/Appointment/argo-appt1/_history/3
[other headers]

Resulting cancelled Appointment:

{
  "resourceType" : "Appointment",
  "id" : "argo-appt1",
  "meta" : {
    "profile" : [
      "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/argo-appt"
    ]
  },
  "text" : {
  ...snip...
  },
  "status" : "cancelled",
  "serviceType" : [
  ...snip...



Releasing Holds

If not booking a held appointment, the Client should release the hold on it before it expires. The length of an appointment hold is determined by the scheduling service’s business rules, after which the status of the Appointment may change. See the Appointment State Diagram for further details on statuses and state transitions.

Canceling Appointment Hold.
diagrams/Slide38.png

Releasing holds has the potential to introduces complex failure states. The best practices guidance discusses how failures should be handled.

Usage

This transaction uses the standard FHIR PATCH transaction as described in the Canceling/Rescheduling Appointments above.

Target Appointment:

{
  "resourceType" : "Appointment",
  "id" : "argo-appt1",
  "meta" : {
    "profile" : [
      "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/argo-appt"
    ]
  },
  "text" : {
  ...snip...
  },
  "status" : "pending",
  "serviceType" : [
  ...snip...

Release hold using JSON PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 [
 { "op": "replace", "path": "/status", "value": "cancelled" },
 ]

Release hold using XML PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 <?xml version="1.0" encoding="UTF-8"?>
 <diff xmlns="http://hl7.org/fhir">
   <replace sel="Appointment/status/@value">cancelled</replace>
 </diff>

Release hold using FHIRPath PATCH

PATCH [Base]/Appointment/argo-appt1

Patch body

 **payload**
 <?xml version="1.0" encoding="UTF-8"?>
 <Parameters xmlns="http://hl7.org/fhir">
   <parameter>
     <name value="operation"/>
     <part>
       <name value="type"/>
       <valueCode value="replace"/>
     </part>
     <part>
       <name value="path"/>
       <valueString value="status"/>
     </part>
     <part>
       <name value="value"/>
       <valueCode value="cancelled"/>
     </part>
   </parameter>
 </Parameters>

Response

HTTP/1.1 200 OK
Location: [base]/Appointment/argo-appt1/_history/3
[other headers]

Resulting Appointment after releasing hold:

{
  "resourceType" : "Appointment",
  "id" : "argo-appt1",
  "meta" : {
    "profile" : [
      "http://fhir.org/guides/argonaut-scheduling/StructureDefinition/argo-appt"
    ]
  },
  "text" : {
  ...snip...
  },
  "status" : "cancelled",
  "serviceType" : [
  ...snip...



Retrieving appointments

The patient searches for their appointments.

Patient Retrieves Their Appointments.
diagrams/Slide34.png

Patient access to their scheduled appointments uses the standard FHIR search API.

APIs

The following Argonaut Scheduling artifacts are used in this transaction:

Usage

To fetch scheduled appointments for a patient the Client SHALL use the standard RESTful search API as shown along with these standard search parameters:

  • patient (required) filter by the patient
  • status (optional) filter by status such as ‘booked’
  • date (optional) filter by a date or a date range ( including the date modifiers ‘ge’,’le’,’gt’,’lt’)
  • practitioner (optional) filter by a practitioner(s)

GET [base]/Appointment?patient=[id]{&status=[status]}{&date=[date]{&date=[date]}}{&practitioner=[id]}

Search for all appointments for a patient with Resource ID 1234: GET [base]/Appointment?patient=1234

Search for all booked appointments for this patient: GET [base]/Appointment?patient=1234&status=booked

Fetch all completed appointments for this patient since January: GET [base]/Appointment?patient=1234&status=fulfilled&date=ge2017-01-01

Fetch all completed appointments with Dr Y for this patient since January : GET [base]/Appointment?patient=1234&status=fulfilled&date=ge2017-01-01&practitioner=Dr+Y