The Telemed Service is currently in beta.
Telemed
Telemed allows you to build cross-platform video calls into your applications. For example, you can use Telemed to create a video call where patients join from a mobile application while a provider joins from their desktop.
If you're looking for reference material, see Ottehr open source EHR (opens in a new tab) which uses Telemed to power its video calls.
ZapEHR Telemed is built on top of Twilio Video (opens in a new tab). Video participants join the room using the Twilio Video Client SDKs (opens in a new tab) for web, iOS, and Android.
Important Update: Twilio will End of Life (EOL) (opens in a new tab) the Programmable Video product on December 5, 2024. As a result, we've developed ZapEHR Telemed V2, built on top of the Amazon Chime SDK.
Telemed on FHIR
Telemed is integrated directly with the FHIR Service. When you create a video room, a FHIR Encounter (opens in a new tab) resource is created to document it. Use this encounter to store and retrieve any details that are relevant to your use case. For example you might want to store:
- Encounter.subject (opens in a new tab) — Typically a patient
- Encounter.appointment (opens in a new tab) — Reference an appointment that scheduled this telemedicine visit
- Encounter.reason (opens in a new tab) — A list of medical concerns to be discussed in the telemedicine visit
Encounter virtualService
Telemed Encounter resources are just like any other FHIR Encounter you might create except in one thing. Your Create Room request creates the FHIR Encounter, its Encounter.virtualService (opens in a new tab) value is automatically set to store the ID of the Twilio Room that is created for V1 or the Amazon Chime SDK meeting ID for V2.
If your Project is using FHIR R4, an extension is used to backport the virtualService
model into the Encounter because the R4 Encounter (opens in a new tab) resource does not support it:
{
"encounter": {
"resourceType": "Encounter",
"id": "4ad7a37e-9edc-45fa-a4c4-da1c8cae505b",
"status": "in-progress",
"subject": {
"reference": "Patient/edb5ecd3-7ed9-4f0c-b8d2-2f9251be0165"
},
"participant": [
{
"individual": {
"reference": "Practitioner/f1d01874-0631-4903-8b32-73b3299b3363",
"display": "Dr Adam Careful"
}
}
],
"extension": [
{
"url": "https://extensions.fhir.zapehr.com/encounter-virtual-service-pre-release",
"extension": [
{
"url": "channelType",
"valueCoding": {
{
"system": "https://fhir.zapehr.com/virtual-service-type",
"code": "twilio-video-group-rooms",
"display": "Twilio Video Group Rooms"
},
{
"url": "addressString",
"valueString": "RM2643645eb020ae2d215eee80dbc1928d"
}
}
}
],
},
]
}
}
The valueString
in the extension's addressString
is the Twilio Video Room ID.
Using Telemed
With Twilio Programmable Video reaching its End of Life (EOL) on December 5, 2024, we strongly recommend using Telemed Version 2, please see Telemed v2 documentation.
There are two steps to using Telemed:
Create a Video Room
Create Telemed Room API Reference (opens in a new tab)
const providerProfile = "Practitioner/f1d01874-0631-4903-8b32-73b3299b3363";
const providerName = "Dr Adam Careful";
const patientName = "Ms Jane Doe";
const deviceProfile = "Device/2643645eb020ae2d215eee80dbc1928d";
const startTime = new Date();
const encounter = {
resourceType: 'Encounter',
text: {
status: 'generated',
div: '<div xmlns="http://www.w3.org/1999/xhtml">Encounter for telemed room</div>',
},
contained: [
{
resourceType: 'Location',
id: 'home',
description: "Client's home",
mode: 'kind',
},
],
status: 'arrived',
class: {
system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
code: 'HH',
display: 'home health',
},
participant: [
{
individual: {
reference: providerProfile,
display: providerName,
},
},
],
period: {
start: startTime.toISOString(),
},
location: [
{
location: {
reference: '#home',
display: "Client's home",
},
},
],
meta: {
versionId: '47dfc118-025d-407a-9210-55ffc9dd198a',
lastUpdated: '2023-10-17T14:36:05.672Z',
},
extension: [
{
url: 'https://extensions.fhir.zapehr.com/encounter-other-participants',
extension: [
{
url: 'https://extensions.fhir.zapehr.com/encounter-other-participant',
extension: [
{
url: 'period',
valuePeriod: {
start: startTime.toISOString(),
},
},
{
url: 'reference',
valueReference: {
reference: deviceProfile,
display: patientName,
},
},
],
},
],
},
],
};
const zapehrAccessToken = 'your-zapehr-access-token';
const PROJECT_ID = 'your-project-id';
const response = await fetch(`https://project-api.zapehr.com/v1/telemed/room`, {
body: JSON.stringify({"encounter": encounter}),
headers: {
Authorization: `Bearer ${zapehrAccessToken}`,
'content-type': 'application/json',
'x-zapehr-project-id': PROJECT_ID,
},
method: 'POST',
});
Create Telemed Room takes just one value in the request body, a FHIR Encounter resource JSON. The endpoint does a few things:
- Creates the FHIR Encounter
- Creates a Twilio Video Room and adds the participants to the room
- Updates the FHIR Encounter to put the Twilio Video Room SID into
virtualService
as described here.
Get Token
Get Token API Reference (opens in a new tab)
In order to connect to a Video Room as a participant, invoke the Get Token endpoint as the Developer, User, or M2M Client (actor) who needs to connect. This returns a Twilio Video JWT with the actor's identity.
const encounterId = 'your-encounter-id';
const zapehrAccessToken = 'your-zapehr-access-token';
const PROJECT_ID = 'your-project-id';
const response = await fetch(`https://project-api.zapehr.com/v1/telemed/token?encounterId=${encounterId}`, {
headers: {
Authorization: `Bearer ${zapehrAccessToken}`,
'content-type': 'application/json',
'x-zapehr-project-id': PROJECT_ID,
},
method: 'GET',
});
{
"jti": "SKd7a07a1a4fbaefd0ee2441709991d479-1700688669",
"grants": {
"identity": "9219f94d-10b4-4b90-bd72-ab8b68f59ca3",
"video": {
"room": "RM821208e1120d5eb16aa761054d740ef6"
}
},
"iat": 1700688669,
"exp": 1700692269,
"iss": "SKd7a07a1a4fbaefd0ee2441709991d479",
"sub": "AC651425b9af5c41409aadf099cc156af3"
}
The value in grants.identity
is the participant's User ID. In order to connect to the Video Room with this token, the user's profile
property must be present in the encounter's participants.
Compliance
ZapEHR maintains a BAA with Twilio (opens in a new tab) which is offered through its enterprise-tier plans. When building on ZapEHR, your BAA with ZapEHR (opens in a new tab) acts as a chain to Twilio and our other service providers, so what you build on ZapEHR Telemed may be HIPAA compliant.
As stated in the ZapEHR's BAA, HIPAA-compliance is a shared responsibility and building on ZapEHR does not automatically make what you build HIPAA-compliant. You are responsible for doing your part to safeguard PHI when using ZapEHR. Learn more about HIPAA Compliance and ZapEHR.
The Telemed Service does not yet support FHIR R5 (opens in a new tab).