How to Write Remote Patient Monitoring Readings to the EHR with
Your product can write patient readings (blood pressure, weight, glucose, heart rate and other vital signs) into the patient's chart as observations on Canvas Medical, DrChrono, Epic, Google Cloud Healthcare API, Jane and SMART on FHIR, and read vitals and lab values back from more than 20 EHRs, through one connection (as of 24 October 2026).
sdk.healthcare.createHealthcareObservation and listHealthcareObservations work the same way on every one of them. A reading is in the chart when the request returns.
Why readings belong in the chart
Remote patient monitoring, chronic care and digital therapeutics programs collect readings from devices and apps every day. If those readings stay in your product, clinicians have to log in somewhere else to see them, and the chart that billing, care plans and other clinicians rely on is missing the data. Writing the reading to the EHR as an observation puts it where the care team already looks, next to the readings taken in clinic.
Unified.to's Healthcare API writes and reads readings as a single Observation object: a coded measurement with a value, unit and time.
What you are building
- Authorize the customer's EHR and store the connection ID
- Map each device reading to a LOINC-coded observation
- Write it to the patient's chart
- Read the chart's vitals to show trends, including in-clinic readings
Write a reading
import { UnifiedTo } from '@unified-api/typescript-sdk';
const sdk = new UnifiedTo({
security: { jwt: process.env.UNIFIED_API_KEY },
});
const observation = await sdk.healthcare.createHealthcareObservation({
connectionId,
healthcareObservation: {
patient_id: patientId,
status: 'FINAL',
type: 'VITAL_SIGNS',
codes: [{ system: 'http://loinc.org', code: '29463-7', display: 'Body weight' }],
value_number: 82.4,
value_unit: 'kg',
observed_at: reading.takenAt,
},
});
On the FHIR-based EHRs, status, patient_id and a code (codes or name) are required; the capability matrix lists required fields per integration. Use the standard LOINC code for each measurement (body weight 29463-7, heart rate 8867-4, glucose 2339-0, oxygen saturation 59408-5) so the EHR files it with the matching in-clinic vitals. type sets the observation category; VITAL_SIGNS files it as a vital sign. observed_at is when the reading was taken, not when you sent it.
Use value_number and value_unit for measurements, and value_text for coded or free-text results. notes carries context, such as the device used.
Read vitals back
const vitals = await sdk.healthcare.listHealthcareObservations({
connectionId,
patientId,
type: 'VITAL_SIGNS',
});
Each observation has value_number, value_unit, observed_at, a reference_range where the source provides one, and interpretation (NORMAL, LOW, HIGH, CRITICAL_LOW, CRITICAL_HIGH, ABNORMAL). Panels such as blood pressure return their parts as components, each with its own code and value, so systolic and diastolic arrive together:
const bp = vitals.filter((o) => o.codes?.some((c) => c.code === '85354-9'));
const latest = bp.sort((a, b) => String(b.observed_at).localeCompare(String(a.observed_at)))[0];
const systolic = latest?.components?.find((c) => c.codes?.some((x) => x.code === '8480-6'))?.value_number;
const diastolic = latest?.components?.find((c) => c.codes?.some((x) => x.code === '8462-4'))?.value_number;
type also takes LABORATORY, SOCIAL_HISTORY, SURVEY and other categories, so the same call powers a labs trend view.
Handling coverage that varies by EHR
Gate writes on the capability matrix. Most EHRs return observations read-only. Where your customer's EHR doesn't accept writes, keep readings in your product and send a summary through another channel (for example a clinical document where notes can be written).
Check what the EHR expects. Some EHRs accept only certain categories or codes from patient-facing apps, depending on how the health system has configured them. Test each code with the customer before you go live.
Treat 501 as information, not failure. A 501 on create means this EHR doesn't accept observations through the API; the connection is still valid for reads.
Stay current
On Canvas Medical, Epic, Google Cloud Healthcare API, Open Dental, Oracle Health, SMART on FHIR, TruBridge and Veradigm, [virtual webhooks](/blog/what_are_virtual_webhooks_how_they_differ_from_sync_based_webhooks) and updatedGte deliver new and changed observations, including readings taken in clinic (as of 24 October 2026).
→ Start your 30-day free trial → Book a demo
Frequently asked questions
Can I correct a reading I wrote?
Not through the unified Observation object; observations are create-only. Correct it in the EHR, or write a new reading.
Does this handle RPM billing?
No. This puts readings in the chart, which billing depends on. Time tracking and claims for remote monitoring codes stay in your product or the practice's billing system.