Unified.to
All articles

How to Read Clinical Notes and Write Notes Back to the EHR with

Your product can read a patient's clinical documents (progress notes, consultation notes, discharge summaries, care summaries and more) from AdvancedMD, athenahealth, CharmHealth, Epic, MEDITECH, NextGen Healthcare, Oracle Health, PointClickCare, SMART on FHIR, TruBridge and Veradigm through one connection and one method call. On TruBridge, it can also write a note back into the chart (as of 24 October 2026).

sdk.healthcare.listHealthcareDocuments returns the same Document object on all eleven. The document's content (a PDF, an HTML note, plain text) is served from a short-lived document_url, so your product never handles the customer's EHR credentials. Every request is executed directly against the customer's EHR, so what you read is what exists there now.

Why clinical notes are the hard part of an EHR integration

AI scribes, care coordination tools, prior-authorization assistants and patient-facing apps all need the narrative record: what the clinician wrote, not just the coded data. The EHR already holds it, as documents attached to the patient and the visit.

The difficulty is that a document is two things in every EHR: a metadata record (who wrote it, for which patient and visit, what kind of note it is) and the content itself, usually stored separately as a binary that only an authenticated request can fetch. Each vendor also classifies notes in its own way. Unified.to's Healthcare API maps the metadata into a single Document object, normalizes the kind of note into one type field, and proxies the content so you build the read once.

What you are building

A clinical documents panel inside your product: the customer connects their EHR, and each patient's notes appear with type, author, visit and a link to open the content. On TruBridge, your product can also file a note it generated.

  1. Authorize the customer's EHR and store one connection ID
  2. List a patient's documents, optionally filtered by kind of note
  3. Open the content through document_url
  4. Write notes back on EHRs that accept them (TruBridge)
  5. Pick up new and changed documents where supported

Connect once and list a patient's documents

Initialize the SDK with your API key. This is the same for every category.

import { UnifiedTo } from '@unified-api/typescript-sdk';
import * as errors from '@unified-api/typescript-sdk/sdk/models/errors';

const sdk = new UnifiedTo({
  security: {
    jwt: process.env.UNIFIED_API_KEY,
  },
});

If your customers require their data to stay in a region, pass serverIdx when initializing: 0 for the North American server, 1 for European, 2 for Australian.

Each end-customer authorizes their own EHR through Unified.to's authorization component, which returns a connection ID. Store one per customer. On SMART on FHIR EHRs such as Epic, Oracle Health and athenahealth, the user signs in at the EHR and the connection is scoped to what they authorized; on a patient launch, that is one patient's record.

Listing a patient's documents takes one call:

const documents = await sdk.healthcare.listHealthcareDocuments({
  connectionId,
  patientId,
  limit: 50,
});

patientId is optional on a patient-launch connection: leave it out and Unified.to uses the patient who authorized the connection.

What each field tells you

type normalizes the kind of note: PROGRESS_NOTE, CONSULTATION_NOTE, HISTORY_AND_PHYSICAL, DISCHARGE_SUMMARY, PROCEDURE_NOTE, REFERRAL_NOTE, SUMMARY, LABORATORY_REPORT, IMAGING_REPORT, CONSENT, or OTHER. It is derived from the LOINC document code the EHR sends, and codes keeps the EHR's original codings so nothing is lost when the type is OTHER.

Filter on it server-side to show one kind of note at a time:

const discharges = await sdk.healthcare.listHealthcareDocuments({
  connectionId,
  patientId,
  type: 'DISCHARGE_SUMMARY',
});

OTHER has no LOINC code to search by, so filtering on it returns 400; filter it in your own code instead.

encounter_id ties the note to the visit, and practitioner_id to its author. Both reference the Encounter and Practitioner objects in the same API, so a note joins to the visit and clinician your product already reads, with no name matching.

status is CURRENT, SUPERSEDED or ENTERED_IN_ERROR. Hide ENTERED_IN_ERROR documents and prefer the CURRENT version of a note that has been amended.

authored_at is when the note was written; mime_type and filename tell you how to render the content before you fetch it.

Open the content

document_url is a signed link to Unified.to's download route, valid for one hour. Fetch it from your server (no API key needed on that request) and Unified.to retrieves the content from the EHR with the connection's own credentials:

const response = await fetch(document.document_url!);
const body = Buffer.from(await response.arrayBuffer());
// render by document.mime_type: text/plain, text/html, application/pdf …

If the EHR embedded the content in the record, it is returned directly; if the record points at a binary on the EHR, Unified.to streams it. The EHR's token is never sent anywhere except the customer's own FHIR server.

Don't store document_url; list or get the document again when you need a fresh link.

Write a note back to the chart

An AI scribe's job isn't done until the note is in the chart. On TruBridge (as of 24 October 2026), create a document with the note body base64-encoded:

const created = await sdk.healthcare.createHealthcareDocument({
  connectionId,
  healthcareDocument: {
    patient_id: patientId,
    encounter_id: encounterId,
    status: 'CURRENT',
    type: 'PROGRESS_NOTE',
    mime_type: 'text/plain',
    document_data: Buffer.from(noteText).toString('base64'),
    authored_at: new Date().toISOString(),
  },
});

status, patient_id and document_data are required. type sets the LOINC document code (progress note is 11506-3); pass codes instead when the EHR expects a specific code. The note is filed when the request returns, not on a sync cycle.

On the other EHRs, documents are read-only through the unified Document object. Epic's API lists document create, but it isn't enabled for patient-launch connections yet; gate your write-back interface on the capability matrix.

Handling coverage that varies by EHR

Each EHR's own API determines what Unified.to can return.

Check support before you scope. Field support, write support and list parameters are documented per integration on the Supported Integrations page.

Treat 501 as information, not failure. Where an EHR doesn't support documents, the request returns 501 Not Implemented rather than an empty list. An empty list means the patient has no documents; a 501 means this EHR can't tell you either way.

try {
  return renderDocuments(await sdk.healthcare.listHealthcareDocuments({ connectionId, patientId }));
} catch (error) {
  if (error instanceof errors.UnifiedToError && error.statusCode === 501) {
    return renderUnsupported();
  }
  throw error;
}

Render what returns. name, type and authored_at are enough for a working list; author, visit and content are enhancements that appear when the EHR provides them.

Stay current when a note is added or amended

On Oracle Health, SMART on FHIR, TruBridge and Veradigm (as of 24 October 2026), subscribe to changes and let Unified.to's [virtual webhooks](/blog/what_are_virtual_webhooks_how_they_differ_from_sync_based_webhooks) deliver them:

{
  "connection_id": "5de520f96e439b002043d8dc",
  "hook_url": "https://yourapp.com/webhooks/healthcare",
  "object_type": "healthcare_document",
  "event": "created",
  "interval": 5,
  "webhook_type": "virtual"
}

Subscribe separately for created and updated. The interval field sets how often Unified.to checks for changes: as often as every minute on paid plans, 60 minutes on the trial. A check that finds nothing isn't billed. On those same EHRs, updatedGte returns only documents changed since a timestamp. On the others, read on a schedule.

→ Start your 30-day free trial → Book a demo

Frequently asked questions

Does Unified.to store the notes it reads?

No. Every request runs against the customer's EHR in real time, and Unified.to keeps no patient records at rest (connection credentials and operational metadata are encrypted at rest). Unified.to is HIPAA compliant.

Can I update or delete a note?

Not through the unified Document object. EHRs treat filed notes as part of the legal record; amendments are new documents that supersede the old one, which is why status distinguishes CURRENT from SUPERSEDED.

Why does a document have no document_url****?

The EHR returned a document record with no attached content. List it, but don't offer an "open" action.

All articles