Skip to main content

EMPI Reference Implementation

· 9 min read
Rahul Agarwal
Medplum Core Team

Patient record-keeping systems often have duplicate patient records, which can affect patient care and service delivery. One of the Medplum use cases is the the Enterprise Mater Patient Index (EMPI), database used in healthcare settings to maintain accurate and consistent unique identifiers for patients across various departments and services. A great EMPI implementation will improve patient safety, enhance the quality of care, facilitate data sharing among disparate healthcare systems, AND speed payer contracting.

The Medplum team has had experience with EMPIs across different practices, including telehealth practices, which especially thorny duplication and identity issues as patients may never meet providers in real life.

This video walkthrough summarizes a reference implementation that we have developed based on our experience. It can be used with any identity solutions or matching algorithms.

Our overview of Patient Deduplication Architectures describes the data model and pipelines in detail.


The following points are covered in this implementation:

  • How to trigger the deduplication pipeline by subscribing to changes on the Patient resource, which reduces the maintenance cost of implementation
  • Creating a Task for humans to review high-risk duplicates
  • Creating the Risk Assessment - how likely is this to be a duplicate?
  • Numeric scoring and qualitative scoring for calculating the probability that a record pair is duplicates
  • Workflow for merging two records driven by FHIR Questionnaires
  • Showing how duplicates are deactivated, and creation of a bi-directional link between duplicates
  • How to mark records as "Do not merge"
  • Demonstration of traceability how to audit merges

EMPI Deduplication workflow code



Today I'll go over a simple patient deduplication workflow in Medplum. Patient deduplication is an important problem in healthcare, not just for cleaning up your data, but also for enriching your data when you're pulling patient records from multiple sources. Today's administration will show a human-in-the-loop deduplication pipeline that proceeds in two steps.

First, we will listen for changes to a Patient. Create a set of candidate matches for that patient. Next, we'll have a human review those matches and decide whether to merge or block those matches. So let's get started. You'll see here that we have three patient records, all for people named Alex Smith.

The first two are clearly the same person, but the third one is clearly someone else. Even though they're clearly different ages, they all have the same birthdate. 1970, January 1st as a common placeholder, when the birthdate is not known for our deduplication pipeline, we're going to do a match on first name, last name, date of birth, and zip code, which can be a pretty high fidelity matching pipeline.

In addition to these patient records, we have clinical data associated with each one. So for Mr. Alex Smith, you can see that we have encounters that are linked to that patient. However, we've also gotten medication records in the form of medication requests, also known as prescriptions, but they're assigned to the second Alex Smith record from no, Mr.

So, to trigger our pipeline, we'll first make a change to one of the patient records. She'll then kick off a search for any kind of matching records. Okay, so let's go off and go ahead and kick off this deduplication pipeline. So I'll make a change to Mr. Alex Smith and I'll give him a phone number. So let's just add a phone number here.

We'll say, okay, this will kick off one of our bots. That will look through all patients to find matches. Once it finds a match, it will create a task resource to review the potential duplicate.

So let's, let's look at here. There's not much to the task. The real heart of the real resource that represents the candidate match will be the risk assessment resource, which we'll talk about in a second.

But here we'll see that there's the task. Kind of indicates whether or not this task is active and who should be performing this task. This is great for incorporating the deduplication review into your existing task-based workflow. Let's look at the candidate match in the risk assessment.

So we use a risk assessment resource in a couple different ways. First, We use the method field to indicate what kind of matching rule produced this candidate match here. It was a name, date of birth, and zip code. As I mentioned earlier, the subject is who is considered the source record. That is the the person who triggered the matching process, and we use the basis field for the target record, who we think they match to.

We can also have a, if we look at the JSON, we see that we can have a a numeric score on the probability of match as well as a qualitative assessment. Here we're saying it's 90%, it's almost certain, but we can't be a hundred percent sure. So we'll see. After this first step, we have two candid matches.

One is Mr. Alex Smith, two Alex Smith, and another one is Mr. Alex Smith. To Ms. Alex Smith. The woman patient earlier. Now we're ready for the second part of our pipeline, which is to merge these records. So we'll go to our first one. We'll click on the apps tab, which will show a questionnaire. Questionnaire is a type of FHIR resource associated with this RiskAssessment.

Again, the risk assessment being the risk of a match. And we think that Mr. Alex Smith and Alex Smith are probably a good match, so we'll decide to merge them. So we will not leave the, we will not check this box and then we'll have a couple choices in terms of how we have merge the data. We're gonna merge the names.

We're not gonna do anything with the address because they're the same. And for right now, we won't delete the source patient.

The reason you might wanna do this is after you've done the deduplication, you might want to clean up the old data. However, right now we want to keep the old data round for posterity, so we'll click okay here. Now, if we go back to our patients, we'll see a couple things. We'll see that within these two records.

The Alex Smith record has now become the master record. We see this because it is listed as active. True, but it's the original Mr. Alex Smith record no longer is active. We'll also see that there's this link field that says it replaces Mr. Alex Smith and the other way around Mr. Alice Smith is replaced by Alex Smith, so there's a bidirectional link there.

Additionally, we'll see that the Encounter resources we had before have now been updated. To point from Mr. Alex Smith to Alex, our target resource. So all the clinical data has now been merged to the target patient. Let's go back to our risk assessments, which are our can matches, and let's look at Alex Smith to Mrs.

Alex Smith. Now for this one, we know that they, a human, decide that they're not. The same patient. So we're gonna say, do not merge these records. Let's talk about this dunks. This will add each record to a list such that on the next time we do a match, we know not to make a candidate out of them. So in this case, we say Alex Smith does not, these are are called our do not Match lists.

So in this case, we have Smith. Should not be matched with Mrs. Alex Smith and reciprocally. We have Mrs. Alex Smith and should not be matched with Mr Alex Smith and we can do these. So every patient will have their own do not match list. And when we trigger the first part of our pipeline, again, we will skip over anything on our do not match list.

It can be an arbitrary number of elements on each do not match list. Let's just take a quick look at the bots that perform both of these operations. So we have two bots here. We have our fine matching patients, which is for the first step of the pipeline to generate the tasks and risk assessments, and the second step of our pipeline, which is the merge matching patients.

So as a final step, I'd like to talk about some of the traceability aspects of this deduplication pipeline. So first I'll show you how you can actually see who performed the merge operation. We click on Alex Smith, who was our merged patient. So first off, when we enter the patient page, we'll see in this timeline view that there was a change made to the resource to make this link to the other Alex Smith resource.

And we can see the details here. If we go to the link property, you can say, see that? We are linked to Mr. Alex Smith and vice versa. If we can go to Alex Smith, we can look at their details. Mr. Alex Smith, and you say that they're linked to Alex Smith. You see that they have a reciprocal connection. A Mr.

Alex Smith is replaced by, but Alex Smith replaces Mr. Alex Smith. Next we can look at the history tab to see all the changes that were made. We can actually see that I was the one. If we look here, who added those links? This is a key point I wanna focus on. Even though we use the bot to do it, we actually get the observability that I was the one who triggered the bot.

The way we set that up is that if we go to the bot resource itself, we click on merge match. Patients and go to the details tab. You can see that he has this one flag called Run as users said, to troop for these kind of sensitive deck pipelines. You are gonna wanna turn that on. What that means is that when this bot runs, it keeps track of who triggered it and will show up in the history as that person performing the operations as opposed to the but itself.

So, This is just to give you a quick overview of how even though we performed this merger operation, you can audit when it was done and who it was done by. These bots are stored in our Medplum demo bots repo, and I encourage you to check out that repository to check out the code.

YC Open Source Founders - Q&A

· 6 min read
Reshma Khilnani
Medplum Core Team

YC invites alumni (like us - Medplum is YC S22) to come speak for the current batch and share our experiences. We were excited when our YC Partners Diana and Nicolas invited Medplum to come and speak to Open Source and devtools companies two weeks ago.

YC Open Source Meetup

Jorge, Michel, and me at YC (Nicolas at the edge)

However, I had a moment of panic when I realized that the other panelists were Michel from Airbyte, and Jorge from MindsDB. For context, MindsDB and Airbyte have huge communities. They are frequently featured on Hacker News - which is the New York Times of open source.

Standing side-by-side with these founders, I worried, could not be a flattering comparison.

RepoGithub StarsStage ready?
mindsdb17,600 ⭐😎
airbyte11,500 ⭐😎
medplum789 ⭐😬

A False Comparison

Here's one thing that we believe: 10 or 20 years from now, we will find the fact that we grouped open source startups together funny and peculiar. It's like looking at startups from the late 90's when "Internet" was a startup category - how quaint!

Looking back at our 2023 selves, we will have that same thought about "open source" startups - a grouping representative of the time, and not the startup itself.

YC Founders were quick to pick up the fact that we are not all the same. Below are the questions they asked in session. These answers are from the Medplum perspective, these certainly don't apply globally and the answers you get from Michel and Jorge would no doubt be pretty different.

What Founders Asked

Why did you choose open source?

Healthcare app developers have what we call "the terrible choice", (a) buy an off the shelf health records system and fight with it or (b) invest a ton of time and resources into your medical record system to build your workflow, compliance, certification and integrations.

Minimal/simple medical app implementations are rare, and when they exist - spiral in complexity when the app makes contact with the healthcare establishment (insurance billing, medications ordering, lab integrations etc).

What healthcare devs really need is a composable solution, that enables adding on functionality as needed with great abstractions. Composability is a superpower and is the key attribute of open source.

Open source has some great secondary benefits too. Healthcare devs are very jaded after repeatedly being marketed products that don't really work and/or are largely undocumented black boxes. The ability to test and audit open source in depth has appeal, and helps to build trust.

We actually "learned the open source lesson" a long time ago. The Medplum founding team founded a medical imaging SaaS startup called MedXT (YC W13). MedXT customers were constantly asking for "source code in escrow" or "source access" whenever they would sign a SaaS agreement. We should have put some careful thought as to why they were asking for it. With 20/20 hindsight, we now know that continuity of business and compliance are critical for customers, and open source is a great tool in that regard.

What were some of the most effective tactics for growing your dev mindshare early on?

We have a fundamentally different approach to growing dev mindshare than many other open source startups. We don't do launch week, memes, or advanced Tweeting. (Maybe we should, but that's not top of mind today.)

For us, getting customers to build and run in production was the first step in getting dev mindshare. Electronic Health Records have no "hobbyist" use case, if you are going to use it, it better work in production.

In that way, getting to production really early, before we had 20 stars on our repo, on was our way to establish mindshare. That production usage is something that our customers value, and that in combination with an open source, certified, well documented, compliant offering is novel for the healthcare dev.

Second to running in production, certifications are our second most effective technique to gain developer mindshare. Medplum has common certifications, like SOC 2 and HIPAA as well as some very industry specific ones like ONC and CLIA/CAP. In general devs find certification tasks tedious and un-fun, so a reference implementation appeals.

Citus Data (YC S11) and Posthog (YC W20) have a similar "in production" ethos to Medplum,

YC Open Source Meetup

Umur (VGP YC, Citus Data S11), Tim (Posthog), James (Posthog), me holding the mic

What are your important metrics?

We track the number of projects and apps created, as well as the number that reach certain maturity milestones in their implementation on our hosted service. These are nothing fancy or sophisticated.

We work hard on our customer success and implementations. We track questions and support requests across all channels Github, Discord, Slack and email. We track how many had documentation/content already published, how many were actual bugs and turnaround times. Troubleshooting, helping others build is our customer obsession, and if their implementation is successful, we'll be successful too.

How did you get your first paid customer?

Our first paid customer used our hosted offering.

Medplum is somewhat unique in that we started with our hosted multi-tenant offering. This is the opposite of many open source companies, who start with a self-hosted single tenant offering.

Our initial customers liked what they saw in the repo, and liked that they could self-host, but decided they would rather have a managed solution. We believe that having a managed solution day 1 was crucial for us, as the time to value and feedback loop are much faster.

Do you do professional services? If so, how much?

We do a small amount of professional services in the form of workshops and pilots for prospective enterprise customers. Engineering leaders often have budget for professional services, and this type of engagement helps devs align stakeholders internally as they make the case to their leadership that they should use Medplum.

How did you decide on your license?

We support customers through many complex compliance audits and certification processes. Our license, Apache 2.0 is a reflection of that, it's well understood to stakeholders. There are code scanners everywhere in an audit.

How was fundraising as an open source company?

I mentioned in the beginning how nerve wracking it is to be compared to the Github star machines like MindsDB and Airbyte. We had to do extra preparation and communicate crisply to investors to tell our story, not a version of someone else's.

For Medplum, open source is our way to build trust. I'll compare and contrast that with some other approaches where open source is a form of marketing, and is primarily for growth.

When it comes to fundraising, the narrative is critical: we are open source to build trust with customers and prospective customers. And companies have trusted us with their data, and use us as their primary health datastore in production. The value customers get from having a trusted partner to manage their data is the basis of our business.

Break a leg on your demo day YC S23!

ONC Certified for (b)(10)

· 2 min read
Reshma Khilnani
Medplum Core Team

The Medplum team is pleased to announce that we have certified the (b)(10) ONC Criteria - Electronic Health Information Export.

To see details related to our certification please check out our ONC Certification page.

What does this mean?

It means that a full export of a patient's data can be pulled from Medplum in a machine readable format, in a timely manner. At the time of this writing, the CHPL lists 70 EHRs have certified the (b)(10), out of 708 total. The requirements are summarized as follows:

✅ All data for a specific patient can be exported

✅ Machine readable format

✅ Timely export

✅ Self-service, can be done without contacting support

For those new to EHRs,** it can come as a surprise that it isn't a requirement that a patient's data be exportable in machine readable format**. This criteria is relatively recent, and a result of the 21st Century CURES Act. We believe it is a great benefit to our industry and for patients.

Medplum's implementation is open source and we believe we are the only open source implementation of this criteria so far. For data management certification criteria, the key benefit of open source is composability. Instead of ripping and replacing a huge monolithic system that needs to conform to one or more complex compliance frameworks, you can progressively enhance an implementation to fit the requirements of your specific scenario.

Demystifying FHIR Systems

· 5 min read
Rahul Agarwal
Medplum Core Team

One of the main sources of confusion when starting an implementation is with FHIR system strings.

This field is ubiquitous across FHIR elements, but many developers who are new to healthcare don't understand its purpose or how to set it properly. They are used in even the most basic implementations, and even the sample data we provide for prototyping has many system identifiers.

So today, we're going to delve into system strings to understand what they're for and how to use them!

System strings are commonly found on two distinct element types:


A common occurrence in healthcare is that the same entity (patient, practitioner, device, etc.) is present in many different systems, each assigning their own unique ID. With FHIR, we can neatly keep track of all these unique IDs using the identifier field.

To avert any name collisions, each Identifier has an associated system string, which acts as a namespace for the identifier. This namespace is typically an absolute URL to ensure its global uniqueness.

Let's look at an example. Say we have two patients, Alice and Bob, who have both visited Hospital 1 and Hospital 2. They have the following medical record numbers:

Hospital 112345
Hospital 298760
Hospital 198760
Hospital 212345

Simply searching for the patient with record number "12345" would cause confusion.

GET [base]/Patient?identifier=12345

The system string is our guiding light here. It allows us to clarify which identifier comes from each hosptial.

"resourceType": "Patient",
"name": [{"given": ["Alice"]}],
"identifier": [
// MRN - Hospital 1
"system": "",
"value": "12345"
// MRN - Hospital 2
"system": "",
"value": "98760"
"resourceType": "Patient",
"name": [{"given": ["Bob"]}],
"identifier": [
// MRN - Hospital 1
"system": "",
"value": "98760"
// MRN - Hospital 2
"system": "",
"value": "12345"

Now if we add the system string to our search, we can do a targeted query for Bob.

GET [base]/Patient?identifier=|12345

See our search guide for more information about searching with system strings.


Healthcare thrives on codes. Labs, medications, billing - they all have alphanumeric code systems. These standardized codes help healthcare actors communicate, reduce ambiguity, and streamline interoperability. You may have heard of some of these codes, like CPT for "procedure codes" or ICD-10 "diagnosis codes".

In an ideal world, there would be one universal code system for any application. But real-life healthcare is more complicated.

Let's take medications as an example. There are at least four common coding systems used to identify medications (for a deeper dive, check out our guide on medication codes).

This is where CodeableConcepts come in handy. They anticipate that the same concept (e.g. drug) might have different representations (aka codes) in different systems.

The example below shows how Tylenol would be represented in RxNorm and NDC. Here, the system string lets us know which code system we're using.

text: 'Tylenol 325 MG Oral Tablet';
coding: [
// RxNorm
system: '',
code: '209387',
// NDC
system: '',
code: '50580045850',

However, not all CodeableConcepts map to a standard system. For example, assume that you are using the Communcation.category field to organize messages based on product lines. Since product lines are specific to your company, there won't be a standard code system available. In these cases, you will develop in-house, or local , codes.

Best Practices for System Strings

So now that we understand Identifier and CodeableConcepts better, we can talk about how to write good system strings.


For Identifiers, the strategy is simple: each system string should correspond 1:1 with the source system. For instance, a patient ID from a particular hospital should have a system string like


When it comes to CodeableConcepts, it gets a bit more complex. Whenever possible, you should use standardized code systems to avoid reinventing the wheel and promote good data hygeine. The FHIR community has defined standard system strings for these code systems.

Some commonly used code systems:

DomainCode Systemsystem string
Procedure Names. Provider roles.SNOMED
Clinical ObservationsLOINC

For local codes, **the system string should reflect the degree of consensus **you want to enforce across your organization.

A system string like could indicate a company-wide standard for product lines, while could refer to a standard specific only used within the messaging function.


System strings are your go-to tool for successful healthcare data management. By keeping them clean and consistent, you'll save yourself a lot of confusion and time.

See Also

Vanya for Browsing Data on Medplum's FHIR Server

· 2 min read
Cody Ebberson
Medplum Core Team

Darren Devitt, a respected FHIR expert, has recently released an alpha version of a new tool called Vanya. Similar to how Postman functions for API requests, Vanya is designed specifically for browsing data on FHIR servers.

I've taken some time to test Vanya with Medplum's FHIR server, and I want to share the setup process, some tricks I've found useful, and a brief overview of my experience.

Setting Up Vanya with Medplum's FHIR Server

If you've decided to give Vanya a try, here's what you need to know to get it running with Medplum's FHIR server:


You'll need to input the FHIR base URL, not just the server base URL. Remember to include the "fhir/R4" path. For example, when using the Medplum Staging server, I used the full URL "".


Vanya requires authentication as an HTTP header. For my testing, I used a "Basic" auth header created using the client ID and client secret.

You can use a tool such as DebugBear to generate a Basic auth header from a client ID and client secret.

Or, if you prefer, you can use the OAuth2 client_credentials flow with the client ID and client secret to get an access token. See our guide on Client Credentials for step-by-step instructions.

Once you have a Basic auth token or a Bearer token, add it to the Vanya HTTP headers:

Enter Vanya auth header

Using Vanya

Once you've set up these parameters, you can start using Vanya to browse through different types of FHIR data on the Medplum server.

Vanya client screenshot

Wrapping Up

Vanya is still in its alpha stage, and there's a lot to look forward to as it continues to develop. However, even now, it offers a useful tool for browsing FHIR data. I'll be keeping an eye on the tool's progress, and I'll share any important updates here.

Give Vanya a try and let us know about your experience. If you have any questions or need help with the setup, please join our Discord!

Medplum's Proposal for NASA's Health Tech RFP

· 2 min read
Cody Ebberson
Medplum Core Team

NASA's TRISH team (Translational Research Institute for Space Health) recently issued an RFP for a healthcare tech platform designed for monitoring spaceflight participant health metrics during space missions. TRISH is a virtual consortium focused on applied research to ensure astronaut health during space exploration.

As avid space enthusiasts, and NASA Space Camp alumni, we were eager to apply.

Cody at Space Camp

Medplum submitted a proposal. We were invited to present to the TRISH team in June!

Medplum for TRISH

We're now anxiously awaiting the results.

Adapting to Space Challenges

A notable challenge in the RFP was the solution's ability to operate in a low power environment. To address this:

Medplum on Raspberry Pi

We successfully set up the entire Medplum tech stack on a Raspberry Pi 4 (8gb edition). Due to Medplum's open source nature and its reliance only on widely-used open source dependencies, this transition was quite smooth. For those curious, here's the Raspberry Pi 4 model we used.

Raspberry Pi OS Selection

A necessary adjustment was using the 64-bit edition of the Raspberry Pi OS because 32-bit Postgres isn’t widely supported or available as a Debian package. Following that, the Medplum installation mirrored the process on any other Linux server, as detailed in our Ubuntu installation guide.

Satya with Raspberry Pi

Monitoring Power Consumption

With everything up and running, it became pertinent to gauge the power consumption. Using the SURAIELEC Watt Meter, we observed that when Medplum operates idly, the power consumption hovers around 1-1.5 watts.

Raspberry Pi CPU usage

Raspberry Pi power consumption

UI Development

Once power constraints were addressed, we used the Medplum React components to assemble a mock dashboard showcasing health metrics of Artemis mission astronauts, monitoring vital signs and other crucial health parameters. We also included the spacecraft's intrinsic metrics, such as cabin temperature, pressure, oxygen levels, CO2 concentrations, and radiation readings.

Medplum Space EHR


This exercise provided a practical demonstration of Medplum’s adaptability and versatility, underscored by the strength of open source tools. We believe the exercise emphasizes Medplum's flexibility and readiness for diverse challenges.

24/7 Pediatrician Access - Summer Health Case Study

· 3 min read
Reshma Khilnani
Medplum Core Team

(2 minute demo)


Summer Health is an innovator in direct-to-patient pediatrics, with a focus on messaging and mobile access for parents via SMS. Their fast growing practice is available nationwide and is known for excellent patient engagement.

Medplum Solutions Used

  • Custom EHR - The Summer Health custom EHR allows providers to respond to patient messages, enables task management and automation, and has AI-assisted encounter documentation.
  • Patient Portal - The patient experience includes the ability to reach pediatricians via messaging, and to view information across web and mobile devices.
  • FHIR API - with all data being natively stored as FHIR, enabling synchronization through a FHIR API to Google BigQuery allows robust analytics and visibility into operations.

Challenges Faced

The unique nature of the Summer Health offering necessitated custom software development, specifically:

  • Messaging-based workflows are convenient for users, but require aggregation, careful data extraction and synthesis to be actionable for providers.
  • Pediatrics requires complex access control patterns because patients are children and multiple caregivers are creating and accessing data on their behalf.
  • Timeliness and tasking are crucial and providers and staff respond in a timely manner to patient inquiries.
  • Mobile access with single sign on for clinicians who primarily administer care through mobile devices. This was a key pain point with other solutions.

Why Medplum?

Medplum stood out for the following reasons:

  • Complete control over the user experience, reducing burden for the providers.
  • Identity management and access control allows caregivers to access records.
  • Unlimited and flexible integrations, and ability to build them as needed without restriction, including streamlined incorporation of cutting edge technologies like LLMs.

The team completed their initial build in 16 weeks.

Features Used

The following Medplum features were used to build this product.

  • Integrations - notably Medplum's integration framework and tools made it easy to integrate BigQuery and LLMs.
  • Google Authentication and External authentication - Summer Health uses multiple identity providers for practitioners and patients respectively.
  • Access policies - Patients are children, so parametrized access policies support parent and caregiver access.
  • Subscriptions - integrations to data warehousing and other applications are powered by event driven notifications
  • FHIR Datastore, specifically family relationships and GraphQL allow for medical records that incorporate sibling and family member context
  • Charting and Task Management - encounter documentation and tasks are featured in the application and major drivers of the workflow.
  • Bulk FHIR API to support reporting and interoperability with other systems.

Value Based Care and Elderly Populations - Ensage Case Study

· 4 min read
Reshma Khilnani
Medplum Core Team

(2 minute demo)


EnSage, is an innovator in healthcare management, improves outcomes for elderly populations in value-based care (VBC) organizations. Their service automates the acquisition of patient data from multiple sources and performs data-driven risk-scoring on each patient. The risk scores then aid the care team in scheduling check ups for the highest risk patients first. It also facilitates sharing these risk profiles with their Primary Care Providers, enabling high fidelity care coordination across institutions.

Medplum Solutions Used

In this project, EnSage utilized two Medplum solutions.

  1. Custom EHR: A health record application specifically tailored for EnSage practitioners. This provides healthcare professionals with vital data at their fingertips.
  2. Provider Portal and FHIR API: An application for referring physicians to access and contribute to the integrated care management, but ensures they only have access (via API or app) to patients under their care.

Challenges Faced

EnSage overcame significant technical challenges in this project, including the need to aggregate data from a wide array of sources such as claims data, CMS datasets, and more. Additionally, they required a bespoke workflow that incorporated case management across multiple organizations that necessitated sophisticated access controls.

They completed their initial build in 16 weeks.

Why Medplum?

Medplum stood out due to its out-of-the-box auth service that supports cross-organization access. Its ability to build high-fidelity custom integrations quickly also proved invaluable in overcoming the challenges of collecting and synchronizing data from multiple sources.

The FHIR data model also proved valuable, as a well documented data model supported by EHRs aligned stakeholders quickly.

These factors allowed EnSage to focus on what was most important: their risk scoring algorithms and the clinician experience.

Features Used

EnSage leveraged a suite of Medplum features to create a comprehensive and efficient solution:

  1. Authorization: by leveraging Medplum sophisticated access control system, the EnSage team was able to expose the Medplum FHIR API directly to client applications and external partners, without the need to encapsulate it behind a gateway / proxy.
  2. Authentication: Multiple authentication providers were utilized, with the EnSage team using Google Authentication, while referring physician identities were managed in an Auth0 tenant.
  3. FHIR Datastore: All data is stored in FHIR format and is accessible via the FHIR API. This provides a standardized approach to storing and accessing health information.
  4. Subscriptions: In this implementation, in response to questionnaires, subscriptions are triggered, setting off automated workflows like notifications, data synchronization and more.
  5. Scheduling: Integration between Acuity and FHIR Schedule provided a robust solution for managing appointments and optimizing healthcare service delivery.
  6. Charting: A system for documenting encounters, including details like CPT and diagnosis codes, was created. This facilitated a comprehensive and precise record-keeping process.
  7. Billing and Revenue Cycle: An automated integration with Candid Health enabled Medicare (CMS) billing for providers on the platform.
  8. Open source: The development team used Typescript for the entire stack. The Medplum open source code, issue tracking and community features helped streamline development and speed learning.

Below is an architecture diagram showing how the different components fit together.

Ensage system diagram Click to enlarge

In conclusion, Medplum was instrumental in providing the tools and support needed to address the complex challenges faced by EnSage. The result is an efficient, patient-centered system that ensures proactive care for elderly populations in value-based care settings.

At Home Diagnostics - Ro Case Study

· One min read
Reshma Khilnani
Medplum Core Team


Ro, is an innovator in direct-to-patient healthcare services, provides patient centric healthcare services nationwide.

Medplum Solutions Used

  1. Lab Network - sending lab orders and receiving diagnostic reports across lab sites
  2. Provider Portal and FHIR API - allow data access with controls, to practitioners and applications

Challenges Faced

Ro, and their diagnostics arm enable a sophisticated nationwide diagnostics service, that includes touch points across clinical teams, shipping and logistics, laboratory sites and customer success.

The workflow requires tight coordination and real-time synchronization between many systems and applications.

Power of g10 - Codex Case Study

· 10 min read
Reshma Khilnani
Medplum Core Team

Codex Health enables health systems manage their patient populations with effective remote patient monitoring (RPM) programs for diabetes, cardiovascular diseases and more.

Their offering has a patient facing experience, a provider experience and EHR integrations with Epic, Cerner and others.

They read and write data from EHRs, and collect data from medical devices like CGM, scales and blood pressure monitors.

Challenging the Status Quo

Historically, services like Codex would have had to connect to EHRs using some combination of system integrators or HL7 V2 over VPN connections which is painful, brittle and costly.

With the roll out of the Standardized API for Patient and Population Services (g)(10) by major EHR platforms like Epic and Cerner they are able to connect to multiple health systems via REST based FHIR APIs, without third party aggregators or VPN Connections.

The "old" way of connecting

(Above) The "old" way of connecting an application to an EHR

The new way of connecting

(Above) The new (g)(10) based way of connecting an application to an EHR

This standardized interface allows Codex to provide RPM programs with no setup cost.

The (g)(10) API is very powerful, as it has build in support for access controls using SMART-on-FHIR oAuth Scopes, enabling:

  • Provider Access - allowing Codex physicians and staff to access demographic data, diagnostic reports and notes for patients under their care.
  • Patient Access - patients can auth in the Codex application and read and write their own data to their record, without need for IT approval.

This scalable approach allows the Codex team to focus on their service, and not on integrations.

Using Medplum

Codex uses Medplum as part of their software development cycle, because Medplum is an open source implementation of the (g)(10), and so from a developer perspective is the same as Epic, Cerner or others, but with robust tooling and configurable permissions. This streamlines the Codex's teams software development lifecycle and their testing across platforms and products.

This standardized interface driven approach allows them to deliver their two solutions:

  • Foresight - an analytics and case management web application for clinicians, that helps them view and manage their patients care
  • Allie - a patient facing application that runs on iOS and Android that allows patients to view their care plans and take action.

Interview with Codex Engineering

Below is a brief interview with the Codex engineering leadership Zane Silver and Yury Staravoitau, about their EHR integrations the transcript is edited for clarity.

Video - 7 mins 51 seconds

Background (Zane): Let me just give you quick refresher of what we're doing here at Codex.

So we're building a remote patient monitoring platform a software solution as well as professional service on top of that. So we sell directly to healthcare providers or DMEs durable medical equipment manufacturers. And they can use our platform to monitor patients remotely if any diseases we connect over Bluetooth.

We have native (iOS, Android) applications, connects over Bluetooth to various blood glucose meters scales, blood pressure monitors. We also do cloud connections for like Dexcom and Freestyle Libre and other CGM devices. A clinician, either at a hospital system or a doctor or technician, might use our platform to be able to monitor or they can out outsource that to us.

We have a licensed disease educators for heart failure, diabetes that we can monitor the patients for them as well. Our internal educators use the same product that we also sell as a platform to the healthcare providers. We integrate directly with EHR systems for those hospital systems, either being able to read or write results back.

So sometimes blood glucose meter results are required in the EHR system, so we do that. We use Medplum as a testing ground and staging ground to make sure that we can properly read and write as well as be able to pull new types of resources records from the healthcare provider themselves.

At this point, a dozen to, well, half a dozen different types of EHR systems: Meditech, Hilo, Epic, Cerner, and others.

We use a multi-tenant system. And so each multi-tenant itself will have its own set of EHRs that's integrated and they're totally isolated across tenants. We are testing connectivity and correctness and being able to pull in those records there.

EHR systems quickly either throttle or crash. So we, we pull in batches and we kind of basically do periodic syncs and then try to do writes in real time.

Question (Reshma): How does it work end to end?

Yury: A patient, selects Medplum as healthcare provider login using the account. And authentication that we put that in the background request EHR system to, to grab some data for this user and update our database, get the refresh token, and on a daily basis, we request some updates using this user by ID for example.

Zane: We integrate with EHR systems, right? Yeah. So we wanna be able to test against EHR systems. And because Medplum is an EHR system with also write access, we can test whether or not we can write records and be able to see that as well as manually write records outside of our application.

Make sure we were able to read those as well. You can't do that unless you're actually doing it on a real EHR system. And we can, but not all of our customers have partnerships where they actually allow us to be able to test on their production systems.

We're remote patient monitoring, so we get (FHIR) Observations (from the customer EHR).

The big part it's missing in terms of the spec is just callbacks and being able to get asynchronous updates.

So moving from an event based versus a pull based system. The pull based system is like much more scalable operationally for us. So we don't have any kind of third party dependencies.

I think for the most part they (providers) prefer it because there's fewer integration points. They turn on the endpoint and give us, our credentials and they're just ready to go. We don't have to, you know, do any back doors connecting directly to their databases or anything like that.

So observations came as from our applications that can be connected to via some devices or, for example, we have dramatic error device that I testing for my blood, blood glucose. Or it can be from EHR system.

I'm happy to talk or, you know, feel free to put us, you know, connect us to anyone you feel like I might be interested in and we're happy to also help out and share any of our learnings and thoughts too.

Question: Can you do a day in the life for me about when you're talking to the provider and you're engaging their IT to get this kind of access, what the process looks like?

Yeah, it's more of a, I would say like a long engaged relationship in terms of actually getting like the direct access to write and read from systems to system.

Obviously, with ONC and data blocking, we can connect with the provider on our own. We don't coordinate with them to do that in terms of just getting patient consent to read their (FHIR) resources. So that's easy if we do that on our own. And then it just takes a little bit of time and talk to the right stakeholders.

The healthcare provider side, find out who the IT team is, get the right people in there and make sure we go through their security reviews. At that point, basically there's, each of the major healthcare providers have their own app portal. So we create an app portal on there. We usually end up giving the healthcare provider what our app ID is, whether it's, you know, app Orchard on Epic.

Cerner has their own developer portal too. Give that to them and then basically they download the app into their system. I don't have any visibility into what that looks like. There says admins do that. And it's usually like a, it takes about 24 hours for that to happen for them to pull it in and then we get their endpoint and it just seems to work for us on that side.

Reshma: So you download their app, but like they're not using the traditional SMART-on-FHIR kind of app machinery. It's more that. You're now eligible to get the credentials that you need to connect server to server?

Zane: That is true. Yeah. We, we can use it in terms of if SMART-on-FHIR to be able to do our launch and they do have to have, you know, download the app there.

But the (Codex) app type is different. So instead of it's a clinician facing app, which is system facing app. So they, the app store kind of on their part, they (provider) have the dropdown that they choose how they want to install it, and it gets installed in their system.

Seems, seems great and it's a lot more scalable in terms of how you can write your application once.

And you don't have to have a custom footprint or like dedicated boxes or instances for each provider.

Our integration costs are very low, so we don't really even, we don't charge in a new integration or onboarding fees or anything like that for a new customer.

Question (Reshma): Are you continuing to roll it out or working on more of the depth scenarios within systems?

I think it's more of just getting more breadth with more provider systems on there. You know, even just this morning we tested Hilo and Meditech, which are two different EHR systems and just getting verified all those seems to work out of the box quite well, which is nice.

Question (Reshma): So anyone with a (g)(10) right? A (g)(10) FHIR implementation?

Zane: Yep.

Reshma: Awesome. It's a great story. It's a great, great story and all the FHIR enthusiasts would be excited.

How It Works

Medplum Client Typescript SDK can be used to connect to the EHR in multiple modes, such as Patient access, oAuth and Basic Auth.

For example use the MedplumClient to connect to another FHIR server from a Bot or other application that has the Medplum client as follows (client credentials).

// External EHR Url and credentials
const externalEhrBaseUrl = '';
const externalClientId = '<client_id>';
const externalClientSecret = '<client_secret>';

// Construct client ant authenticate
const externalEhrClient = new MedplumClient({
baseUrl: externalEhrBaseUrl,
await externalEhrClient.startLogin(externalClientId, externalClientSecret);

// Work with the client as needed, for example search
await externalEhrClient.searchResources('Patient?identifier:contains=999-47-5984');