Virtual Care
v9
DexCare offer an on-demand virtual (ODV) platform for booking and conducting telemedicine visits via video.
The DexCare APIs allow these visits to be booked programmatically so health systems may develop their own booking flows.
This page walks you through the API calls required to book a virtual visit and direct the patient end user into the DexCare virtual visit waiting room.
IMPORTANT NOTE
This documentation reflects the latest version of the API.This preview version of the API is available for customers that control their full patient experience by leveraging the DexCare APIs. The v9 functionality is not yet available for customers using the Dexcare white-labeled patent booking experience
See the previous version of the API here
The calls below assume that the user interface (UI) will provide information to the user about whether the virtual clinic is open. If the clinic is open, the UI will display the current duration of time the user must wait in order to be seen. This duration is known as the Wait Time.
The user will then need to sign-in before progressing to the waiting room.
This flow requires the following additional pieces of patient information (to being signed in):
- the patient’s current location (selected from a pulldown of “practice regions”)
- the patient’s major complaint / reason-for-visit.
The following order of operations will be used to create the virtual visit
- Retrieving Practice Region Availability
- Retrieving Region Wait Times
- Retrieving Patient Identifying Information
- Creating Visits
Alternatively, client applications may skip the step of retrieving patient information and book an appointment by submitting patient information along with the visit request as part of our Guest Booking Flow.
Once a visit has been created it is possible to Retrieve a Visit Summary
New API Features
For the v9 release, DexCare has added a number of important new features for filtering wait times and creating visits.
Visit Types
In v9 of the DexCare API, the concept of “visit type” was introduced to allow alternate patients to be provided with care via different modalities, such as by phone or virtually via video teleconference.
The v9 API allows clients to specify this visitType
as part of the request to create a visit.
Assignment Qualifiers
Another concept introduced as part of the v9 API was the notion of an “assignment qualifier” to allow different types of patients to be directed to providers that suitable for providing those patients care.
This allows, for instance, the system to make a distinction between adult and pediatric patients, in which case only certain providers would be suited for the latter.
The available assignment qualifiers may be retrieved via the Assignment Qualifiers service located at the following endpoint:
https://ecvapi.[servername]/api/9/assignmentqualifiers
View the Open API specification
Language Requirements
The API now allows a flag to be set when the patient is requesting a provider that supports a given language.
This is an open metadata field, though DexCare recommends specifying languages using an ISO 639-3 code.
Urgency
The urgency flag is used to indicate the level of urgency of the patient’s visit.
This is a numeric value to allow for future functionality that will include ranking, but effectively now it is either on (non zero value) or off (0).
The default is 0.
Assessment Tool
The assessment tool field allows clients to indicate what sort of pre-assessment tool was used to evaluate the patient prior to putting them into the queue, such as ADA
Retrieving Practice Region Availability
Virtual Visits are delivered based on a Practice Region.
Practice Regions in the DexCare API correspond to a state provider licensure.
Practice Regions are used to collect the physical location of the patient to assign them to a properly licensed provider.
You will use Practice Regions to query if service is available (i.e. is the clinic open), hours of operation, and wait times.
Initiate a call to get the list of selectable Practice Regions based on the identifier of the Practice.
Endpoint
https://ecvapi.[servername]/api/8/DexCare/practices/{practiceId}
Example Call
curl -H "Host: you.host" -H "accept: */*" -H "content-type: application/json" \
-H "domain: your.domain" -H "correlation-id: [your-correlation-id]" \
-H "x-api-key: [yourapikey]" -H "accept-language: en-US,en;q=0.9" \
"https://your.domain.co/api/8/practices/[your-practice-id]?product=[yourproduct]"
Parameters
practiceId
identifier for a Practice belonging to a client. This value is set up and provided by DexCare and may be hardcoded in your application.
REQUIRED
type: | path |
default: | N/A |
example: | 0cee700e-f4c1-4459-b390-263e4ded436c (Acme) |
values: | string |
product
namespace particular to a given client
OPTIONAL
type: | query |
default: | N/A |
example: | healthconnect |
values: | string |
Responses
200
A practice entity instance is returned.
{
"id": "6996d161-cd16-4556-9577-f942c3f80c80",
"displayName": "Virtual Visits",
"careMode": "virtual",
"payment": {
"insurance": true,
"selfPay": true,
"serviceKey": true
},
"epicBookingEnabled": true,
"practiceRegions": [{
"id": "333bc7df-b368-4cee-9992-9abeef54dbed",
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"displayName": "California",
"regionCode": "CA",
"active": true,
"availability": [{
"start": "2021-11-14T08:00:00.000Z",
"end": "2021-11-15T07:59:00.000Z"
}, {
"start": "2021-11-15T08:00:00.000Z",
"end": "2021-11-16T07:59:00.000Z"
}, {
"start": "2021-11-16T08:00:00.000Z",
"end": "2021-11-17T07:59:00.000Z"
}, {
"start": "2021-11-17T08:00:00.000Z",
"end": "2021-11-18T07:59:00.000Z"
}, {
"start": "2021-11-18T08:00:00.000Z",
"end": "2021-11-19T07:59:00.000Z"
}, {
"start": "2021-11-19T08:00:00.000Z",
"end": "2021-11-20T07:59:00.000Z"
}, {
"start": "2021-11-20T08:00:00.000Z",
"end": "2021-11-21T07:59:00.000Z"
}],
"busy": false,
"busyMessage": "Providers are currently at capacity and closed",
"paymentAccountId": "8d4c9407-e1f3-4d4e-b2a1-ed964522151c",
"visitPrice": 4900,
"orderWeight": 0,
"departments": [{
"id": "4d2a72d5-41d5-462d-985b-9e2ce41c1570",
"epicDepartmentId": "405772000",
"ehrSystemName": "org.providence.dig.epic.provorca",
"defaultDepartmentName": "Interstate"
}],
"market": "default"
}, {
"id": "8a43204f-f0ef-4dcb-ac9d-4e68ddb2ca87",
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"displayName": "Montana",
"regionCode": "MT",
"active": true,
"availability": [{
"start": "2021-11-14T08:00:00.000Z",
"end": "2021-11-15T07:59:00.000Z"
}, {
"start": "2021-11-15T08:00:00.000Z",
"end": "2021-11-16T07:59:00.000Z"
}, {
"start": "2021-11-16T08:00:00.000Z",
"end": "2021-11-17T07:59:00.000Z"
}, {
"start": "2021-11-17T08:00:00.000Z",
"end": "2021-11-18T07:59:00.000Z"
}, {
"start": "2021-11-18T08:00:00.000Z",
"end": "2021-11-19T07:59:00.000Z"
}, {
"start": "2021-11-19T08:00:00.000Z",
"end": "2021-11-20T07:59:00.000Z"
}, {
"start": "2021-11-20T08:00:00.000Z",
"end": "2021-11-21T07:59:00.000Z"
}],
"busy": false,
"busyMessage": "Providers are currently at capacity and closed",
"paymentAccountId": "8d4c9407-e1f3-4d4e-b2a1-ed964522151c",
"visitPrice": 4900,
"orderWeight": 0,
"departments": [{
"id": "4d2a72d5-41d5-462d-985b-9e2ce41c1570",
"epicDepartmentId": "405772000",
"ehrSystemName": "org.providence.dig.epic.provorca",
"defaultDepartmentName": "Interstate"
}],
"market": "default"
}]
}
- praticeRegions
- List of Practice Regions belonging to the Practice that can be shown to the user in a UI element such as select box.
- Within the Practice Regions are a list of
availability
instances that define the start and end times for potential appointments. - You will need to add “Other” to the list returned. If the user selects “Other” you will want to provide a message that they are out of service area.
Retrieving Region Wait Times
After the user selects a supported Practice Region you will need to call the following endpoint to determine the wait time for that region using its regionCode
.
Users of previous versions of the API please note that you will use the regionCode property instead of the id the practiceRegion in subsequent calls
The wait times that are returned distinguished from each other based on properties such as assignment qualifiers and visit types which may also be used as filters.
Endpoint
https://ecvapi.[servername]/api/9/regions/waittimes
View the Open API specification
See the Open API Specification for the visit service for the full documentation on this endpoint.
Example Call
curl -H "Host: [your.host]" -H "accept: */*" -H "content-type: application/json" \
-H "domain: [your.domain]" -H "correlation-id: [your-correlation-id]" -H "accept-language: en-US,en;q=0.9" \
"https://your.host.com/api/9/regions/waittimes?regionCodes[]=WA&practiceId=[yourpracticeid]&product=[yourproduct]"
Parameters
regionCodes
REQUIRED
The identifier for the region for which availability is being queried, typically the two letter state code
type: | query |
default: | N/A |
example: | WA |
values: | string array |
practiceId
identifier for a Practice belonging to a client. This value is set up and provided by DexCare and may be hardcoded in your application.
REQUIRED
type: | query |
default: | N/A |
example: | 0cee700e-f4c1-4459-b390-263e4ded436c (Acme) |
values: | string |
assignmentQualifiers
additional assignment qualifiers to filter provider queue (i.e. pediatric or adult)
OPTIONAL
type: | query |
default: | N/A |
example: | pediatric |
values: | string array |
visitTypeNames
distinguishes between modalities of visit such as virtual visits (done via video) vs those done by phone
OPTIONAL
type: | query |
default: | N/A |
example: | virtual |
values: | string array |
product
namespace particular to a given client
OPTIONAL
type: | query |
default: | N/A |
example: | healthconnect |
values: | string |
Responses
200
Returns an “available” state (true
or false
), and if not available, it will also return the reason why.
If the Region is available (available == true
) then the booking button can be set to an active state with the display of a wait time.
If the Region is not available, it is recommended that the user not be allowed to proceed and be displayed the correct messaging.
[{
"available": true,
"estimateGeneratedAt": "2021-11-18T19:17:52.435Z",
"estimatedWaitTimeSeconds": 560,
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"regionCode": "WA",
"visitTypeName": "phone",
"assignmentQualifiers": ["adult"]
}, {
"available": false,
"estimateGeneratedAt": "2021-11-18T19:17:52.441Z",
"reason": "NO_ONCALL_PROVIDERS",
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"regionCode": "WA",
"visitTypeName": "phone",
"assignmentQualifiers": ["testNewAssignmentQualifier_849b9d3f-3b6e-486f-bfa7-bf226ff8ec30"]
}]
- available
- indicates whether or not the practice is available as a boolean value
- reason
- enumeration that describes why the practice is not available
- values include:
OFF_HOURS
NO_ONCALL_PROVIDERS
REGION_BUSY
UNKNOWN
Retrieving Patient Identifying Information
A Patient guid or other patient identifying information is necessary to create a visit.
Our page on Patient related APIs details how this information may retrieved or added to the system.
If you system is generating data in Epic directly and not through DexCare, you will not use our patient guid.
Instead you will supply the following three fields:
- ehrIdentifier
- ehrIdentifierType
- homeEhr
Creating Visits
The final step in this workflow will create a visit within DexCare’s system as well as an appointment in Epic.
Endpoint
POST /api/9/visits
Parameters
Body Schema
Example Virtual Visit Request Payload
{
"patient":{
"gender":"mail",
"phone":"204-555-3233",
"firstName":"Joe",
"address":{
"line2":"Box #1",
"state":"WA",
"line1":"312 S Washington St",
"city":"Seattle",
"postalCode":"98104"
},
"patientGuid":"12341234-129f-4d0e-afaa-b3009dbe80c7",
"dateOfBirth":"1970-01-01T00:00:00.000Z",
"email":"patent.email@dexcarehealth.com",
"lastName":"Public"
},
"visitDetails":{
"practiceId":"6996d161-cd16-4556-9577-f942c3f80c80",
"stateLicensure":"WA",
"visitTypeName":"virtual",
"visitReason":"zzzIntegrationTests visit reason",
"brand":"providence",
"acceptedTerms":true,
"declaration":"self"
},
"billingInfo":{
"couponCode":"kyle1",
"paymentMethod":"couponcode"
}
}
Example Phone Visit Request Payload
The following payload sent to the v9 version of the end point would result in a phone visit being created,
This example also illustrates using an ehrIdentifier, ehrIdentifierType, and homeEhr instead of a patient guid.
{
"billingInfo": {
"paymentMethod": "insurance",
"declaration": "self",
"insuranceType": "manual",
"insuranceProviderId": "kpvirtual",
"insuranceMemberId": "internal"
},
"patient": {
"firstName": "Sinjoro",
"lastName": "Ajnulo",
"gender": "male",
"dateOfBirth": "1970-01-13",
"phone": "202-555-1212",
"email": "sinjoro.anjulo@example.com",
"address": {
"line1": "123 Main Street",
"city": "Seattle",
"state": "WA",
"postalCode": "98101"
},
"ehrIdentifier": "M123456",
"ehrIdentifierType": "MRN",
"homeEhr": "MAM",
"homeMarket": "MAS"
},
"visitDetails": {
"acceptedTerms": true,
"assignmentQualifiers": [
"adult"
],
"declaration": "self",
"stateLicensure": "WA",
"visitReason": "Example request for a phone visit",
"visitTypeName": "phone"
}
}
Example Patient Proxy Payload
This example shows how a pediatric visit would be created where the user creating the visit (the actor
) is not the same as the patient.
{
"actor": {
"firstName": "Actor",
"lastName": "Proxy",
"gender": "female",
"dateOfBirth": "1970-01-13",
"phone": "202-555-1212",
"email": "actor.proxy@example.com",
"address": {
"line1": "123 Main Street",
"city": "Seattle",
"state": "WA",
"postalCode": "98101"
},
"ehrIdentifier": "M123456",
"ehrIdentifierType": "MRN",
"homeEhr": "MAM"
},
"billingInfo": {
"paymentMethod": "insurance",
"declaration": "other",
"insuranceType": "manual",
"insuranceProviderId": "kpvirtual",
"insuranceMemberId": "internal",
"firstName": "Insurance",
"lastName": "Member",
"gender": "female",
"dateOfBirth": "1971-03-15"
},
"patient": {
"firstName": "Sinjoro",
"lastName": "Ajnulo",
"gender": "male",
"dateOfBirth": "2010-02-14",
"phone": "202-555-1212",
"email": "sinjoro.anjulo@example.com",
"address": {
"line1": "123 Main Street",
"city": "Seattle",
"state": "WA",
"postalCode": "98101"
},
"ehrIdentifier": "M123456",
"ehrIdentifierType": "MRN",
"homeEhr": "MAM",
"homeMarket": "MAS"
},
"visitDetails": {
"acceptedTerms": true,
"assignmentQualifiers": [
"pediatric"
],
"declaration": "other",
"stateLicensure": "WA",
"visitReason": "Example visit of a proxy submitting visit for a child",
"interpreterLanguage" : "es-MX",
"urgency" : 1
}
}
Important Payload Properties
For full details, see the OpenAPI Specification for the v9 visits API.
- patient
- in cases where the patient is requesting a visit for themselves, this information will match the patient information retrieved from GET
/v1/patient
. When the user requesting visit is acting on behalf of the patient, this information will match the patient information defined in a call to/v1/patient/other
- actor
- information provided when booking on behalf of another person information, such as a guardian to a patient for child visits. Required when
visitDetails.declaration
isother
and should not be in the request payload whenvisitDetails.declaration
isself
- billingInfo
- required properties vary based on the
paymentMethod
selected. N.B. not all payment methods are supported for each service and some payment methods require setup from your DexCare contact
billingInfo
for a credit card through Stripe:
...
"billingInfo": {
"paymentMethod": "creditcard",
"stripeToken": "TokenFromStripe"
}
...
billingInfo
for a coupon code or service key:
...
"billingInfo": {
"paymentMethod": "couponcode",
"couponCode": "aSecretServiceKey",
}
...
billingInfo
when a patient is using their own insurance:
...
"billingInfo": {
"paymentMethod": "insurance",
"declaration": "self",
"firstName": "patient first name",
"lastName": "patient last name",
"gender": "enum: 'male' | 'female' | 'other' ",
"dateOfBirth": "YYYY-MM-DD",
"insuranceType": "manual",
"insuranceProviderId": "patient insurance provider id",
"insuranceMemberId": "patient insurance membership id",
}
...
billingInfo
when a patient is using someone else’s insurance:
...
"billingInfo": {
"paymentMethod": "insurance",
"declaration": "other",
"firstName": "first name of the primary insurance holder",
"lastName": " last name of the primary insurance holder",
"gender": "enum: 'male' | 'female' | 'other' ",
"dateOfBirth": "YYYY-MM-DD",
"insuranceType": "manual",
"insuranceProviderId": "insurance holder insurance provider id",
"insuranceMemberId": "insurance holder membership id",
}
...
- visitDetails.assessmentToolUsed
- if patient has done preassessment, which tool was used
- visitDetails.assignmentQualifiers
- This field will be used to specify any assignment qualifiers (e.g. pediatric or adult)
- visitDetails.departmentId
- identifier for the department in which visit will be conducted. Use the id of a department returned when you selected a practice region
- visitDetails.declaration
- indicates if the visit is for the current user (
self
) or someone else (other
) - visitDetails.ehrSystemName
- allows support for health systems with more than one EHR/EMR instance. Use the ehrSystemName of a department returned when you selected a practice region
- visitDetails.interpreterLanguage
- optional language requested if interpreter services are available — use ISO 639-3 Individual Language codes
- visitDetails.practiceRegionId
- Practice Region in which the patient is currently located — alows for virtual MA to triage patients that might be outside of treatment area
- visitDetails.urgency
- urgency rating; 0 for default urgency
- visitDetails.visitReason
- patient’s major complaint / symptom. This is used by the virtual MA for triaging patients.
- visitDetails.visitTypeName
- This field will be used to specify the modality of the visit (e.g. virtual or phone)
Responses
200
The returned payload is a Visit containing the visitId necessary to navigate to the “waiting room”
i.e. a Waiting Room URL: DexCare/visit/{visitID}?brand={brandID}
AUTH TOKEN REQUIRED
{
"visitId": "241f29d1-3402-4a00-b74b-064d28d22596",
"patientGuid": "233441f4-129f-4d0e-afaa-b3009dbe80c7",
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"visitRedirectUrl": "https://th.frosh.dex.care/visit/241f29d1-3402-4a00-b74b-064d28d22596?brand=providence",
"tokBoxVisit": {
"waitingRoomSession": {
"sessionId": "2_MX40NjQ5NzM1Mn5-MTYzNzI2MzA3MzU2Mn5pcktjWSsreTF5bFBIQ25lOHUvb1B2L1B-fg"
},
"videoConferenceSession": {
"sessionId": "1_MX40NjQ5NzM1Mn5-MTYzNzI2MzA3MzgzMn5VbDFaRjc2R2J0UGRaWENUQzZRTTdyN2R-fg"
}
}
}
- visitId
- needed by the browser to navigate into the waiting room
400
Bad request; See response for info
404
Practice not found
500
Internal error
Guest Booking Flow
The guest booking flow consolidates the process of booking patients described above by allowing client applications to submit patient information as part of the the booking request instead of looking it up separately.
For this API, looking up Practice Regions is also not a required step.
Endpoint
POST /v1/booking/queued-guest-visit
Example Call
The full OAS details the parameters in full.
Below is a sample request used to submit to the guest booking endpoint.
{
"patient": {
"firstName": "first",
"lastName": "last",
"email": "first.last@foo.bar.baz",
"phone": "206-789-0123",
"gender": "male",
"dateOfBirth": "1958-06-07",
"address": {
"line1": "2324 Eastlake Ave",
"city": "Seattle",
"state": "WA",
"postalCode": "98102"
}
},
"billingInfo": {
"paymentMethod": "insurance",
"declaration": "self",
"insuranceType": "manual",
"insuranceProviderId": "string",
"insuranceMemberId": "string"
},
"visitDetails": {
"visitTypeName": "virtual",
"acceptedTerms": true,
"declaration": "self",
"stateLicensure": "WA",
"visitReason": "reasons",
"brand": "providence"
}
}
Responses
200
The returned payload contains the Url required to redirect users to the waiting room.
{
"visitId": "<uuid>",
"visitRedirectUrl": "<string>"
}
Retrieving Visit Summaries
Once a visit has been created, it is possible to retrieve its data using the summary endpoint.
The results from this call will allow you to display the current status and type of the visit.
Endpoint
/api/9/visits/{visitId}/summary
Example Call
curl -H "Host: [your.host]" -H "domain: [your.domain]" -H "content-type: application/json" \
-H "accept: */*" -H "accept-language: en-US,en;q=0.9" -H "correlation-id: [your-correlation-id]" \
-H "x-api-key: [your-api-key]"" -H "authorization: Bearer [your-auth-token]" \
"https://your.host.com/api/9/visits/[your.visit.id]/summary"
Parameters
visitId
identifier for a visit
REQUIRED
type: | path |
default: | N/A |
example: | 241f29d1-3402-4a00-b74b-064d28d22596 |
values: | string |
Responses
200
{
"visitId": "241f29d1-3402-4a00-b74b-064d28d22596",
"userId": "446566b8-d043-411d-90ae-a3a6b39a8ab9",
"patientGuid": "233441f4-129f-4d0e-afaa-b3009dbe80c7",
"status": "requested",
"type": "virtual",
"modality": "virtual",
"assignmentQualifiers": [],
"isHighPriority": false,
"stateLicensure": "WA",
"practiceId": "6996d161-cd16-4556-9577-f942c3f80c80",
"providerId": null,
"homeMarket": "default",
"assessmentToolUsed": null,
"integrations": {
"tytoCare": {
"enabled": true,
"account": {
"accountId": "233441f4-129f-4d0e-afaa-b3009dbe80c7",
"isActive": true,
"devicePairingStatus": "NOT_PAIRED",
"isDeviceOnline": false
}
}
},
"tokBoxVisit": {
"apiKey": "46497352",
"waitingRoomSession": {
"sessionId": "2_MX40NjQ5NzM1Mn5-MTYzNzI2MzA3MzU2Mn5pcktjWSsreTF5bFBIQ25lOHUvb1B2L1B-fg"
},
"videoConferenceSession": {
"sessionId": "1_MX40NjQ5NzM1Mn5-MTYzNzI2MzA3MzgzMn5VbDFaRjc2R2J0UGRaWENUQzZRTTdyN2R-fg"
}
}
}