🚧

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 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)

Create a Telemed Room with Fetch
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.

Get a Telemed Token with Fetch
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',
});
Decoded token from the Get Token endpoint
{
  "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).