🚧

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.

Oystehr Telemed V2 is built on top of Amazon Chime SDK Meetings (opens in a new tab). Video participants join the meeting using the Amazon Chime Client SDKs (opens in a new tab) for web, iOS, and Android.

Telemed on FHIR

Telemed is integrated directly with the FHIR Service. When you create a video meeting, 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 Meeting request creates the FHIR Encounter, its Encounter.virtualService (opens in a new tab) value is automatically set to store the ID of the Amazon Chime SDK meeting.

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": "chime-video-meetings",
                "display": "Chime SDK Video Meetings"
              },
              {
                "url": "addressString",
                "valueString": "0a24d732-a08f-465c-9947-0849ef102713"
              }
            }
          }
        ],
      },
    ]
  }
}

The valueString in the extension's addressString is the Amazon Chime SDK Meeting ID.

Using Telemed

There are two steps to using Telemed:

Create a Video Meeting

Create Telemed v2 Meeting API Reference (opens in a new tab)

Create a Telemed Meeting 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 meeting</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 oystehrAccessToken = 'your-oystehr-access-token';
const PROJECT_ID = 'your-project-id';
const response = await fetch(`https://project-api.zapehr.com/v1/telemed/v2/meeting`, {
  body: JSON.stringify(encounter),
  headers: {
    Authorization: `Bearer ${oystehrAccessToken}`,
    'content-type': 'application/json',
    'x-zapehr-project-id': PROJECT_ID,
  },
  method: 'POST',
});

Create Telemed Meeting takes just one value in the request body, a FHIR Encounter resource JSON. The endpoint does a few things:

  • Creates or updates the FHIR Encounter
  • Creates a Amazon Chime SDK Meeting
  • Updates the FHIR Encounter to put the Amazon Chime SDK Meeting ID into virtualService.

Join a Video Meeting

Join Meeting API Reference (opens in a new tab)

In order to connect to a Video Meeting as a participant, invoke the Join endpoint as the Developer, User, or M2M Client (actor) who needs to connect. This returns AWS Chime SDK Meeting and Attendee objects necessary for the participant to join the meeting.

Join a Telemed Meeting with Fetch
const encounterId = 'your-encounter-id';
const oystehrAccessToken = 'your-oystehr-access-token';
const PROJECT_ID = 'your-project-id';
const response = await fetch(`https://project-api.zapehr.com/v1/telemed/v2/meeting/${encounterId}/join`, {
  headers: {
    Authorization: `Bearer ${oystehrAccessToken}`,
    'content-type': 'application/json',
    'x-zapehr-project-id': PROJECT_ID,
  },
  method: 'GET',
});

Joining as Multiple Participants with M2M Token

To connect to a Video Meeting as a participant, invoke the Join endpoint. This returns AWS Chime SDK Meeting and Attendee objects necessary for the participant to join the meeting. There are two ways to join a meeting:

  1. As an anonymous participant: Use the anonymous=true query parameter to join anonymously.
  2. As the default participant: If no parameters are provided, the system will attempt to join using the default profile associated with the token.
Response from the Join Meeting endpoint
{
    "Attendee": {
        "AttendeeId": "12647130-0b50-462e-a489-31794640d3bf",
        "Capabilities": {
            "Audio": "SendReceive",
            "Content": "SendReceive",
            "Video": "SendReceive"
        },
        "ExternalUserId": "5813cd60-89af-4462-8dfe-b8eec70b3e5e",
        "JoinToken": "MTI2NDcxMzAtMGI1MC00NjJlLWE0ODktMzE3OTQ2NDBkM2JmOjkyZjk0MTM5LTU4NmQtNGQzNi04NDg5LWYxNDlmMjY3MzMxYQ"
    },
    "Meeting": {
        "ExternalMeetingId": "e7716793-ce85-4111-a7e6-7b8d9713d541",
        "MediaPlacement": {
            "AudioFallbackUrl": "wss://haxrp.m2.ue1.app.chime.aws:443/calls/f010e847-fe49-4d94-baaa-d411636b2713",
            "AudioHostUrl": "6eda0d8e1db6f0bf881b254e80bd7394.k.m2.ue1.app.chime.aws:3478",
            "EventIngestionUrl": "https://data.svc.ue1.ingest.chime.aws/v1/client-events",
            "ScreenDataUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/f010e847-fe49-4d94-baaa-d411636b2713",
            "ScreenSharingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/v2/screen/f010e847-fe49-4d94-baaa-d411636b2713",
            "ScreenViewingUrl": "wss://bitpw.m2.ue1.app.chime.aws:443/ws/connect?passcode=null&viewer_uuid=null&X-BitHub-Call-Id=f010e847-fe49-4d94-baaa-d411636b2713",
            "SignalingUrl": "wss://signal.m2.ue1.app.chime.aws/control/f010e847-fe49-4d94-baaa-d411636b2713",
            "TurnControlUrl": "https://2713.cell.us-east-1.meetings.chime.aws/v2/turn_sessions"
        },
        "MediaRegion": "us-east-1",
        "MeetingArn": "arn:aws:chime:us-east-1:345244738039:meeting/f010e847-fe49-4d94-baaa-d411636b2713",
        "MeetingId": "f010e847-fe49-4d94-baaa-d411636b2713",
        "TenantIds": []
    }
}

Compliance

Oystehr maintains a BAA with AWS (opens in a new tab). When building on Oystehr, your BAA with Oystehr (opens in a new tab) acts as a chain to AWS and our other service providers, so what you build on Oystehr Telemed may be HIPAA compliant.

As stated in the Oystehr's BAA, HIPAA-compliance is a shared responsibility and building on Oystehr does not automatically make what you build HIPAA-compliant. You are responsible for doing your part to safeguard PHI when using Oystehr. Learn more about HIPAA Compliance and Oystehr.

🚧

The Telemed Service does not yet support FHIR R5 (opens in a new tab).