Patient-authorized EHR integration
Record model and categories
Every record comes back in one normalized shape, grouped into ten categories, with its source and codes attached.
Categories
You ask for records by category, and patients approve sharing by category. There are 10:
| Category | What's in it | FHIR resources |
|---|---|---|
demographics |
Name, birth date, sex, contact details | Patient |
medications |
Active and past prescriptions | MedicationRequest, MedicationDispense, MedicationAdministration |
conditions |
Diagnoses and problem list | Condition |
labs |
Lab observations and reports | Observation, DiagnosticReport |
vitals |
Blood pressure, heart rate, weight, and similar | Observation |
allergies |
Allergies and intolerances | AllergyIntolerance |
immunizations |
Vaccination history | Immunization |
encounters |
Visits, appointments, care teams | Encounter, Appointment, CareTeam |
documents |
Visit summaries and clinical documents | DocumentReference |
claims |
Insurance claims and coverage | ExplanationOfBenefit, Coverage |
One record
FinchNode reads each health system's FHIR resources and returns them in one normalized JSON shape. Every record has these fields, plus fields for its category, such as name, status, and startDate for a medication.
| Field | Meaning |
|---|---|
id |
FinchNode's stable ID for the record, rec_ and 24 hex characters. It stays the same across syncs. The same prescription at two health systems is two records. |
resourceType |
The FHIR resource it came from, such as MedicationRequest. |
sourceRecordId |
The resource's ID at the health system. |
source, sourceName |
Which connection it came from. |
codes |
The source's codes, such as RxNorm or LOINC, with system, code, and display. |
sourceUpdatedAt |
When the health system last changed it, or when FinchNode last updated it if the source didn't say. |
syncedAt |
When FinchNode last imported it. |
{
"id": "rec_a81e05c4c049bf549c1e4fc5",
"resourceType": "MedicationRequest",
"sourceRecordId": "MedicationRequest/medication-demo-001",
"source": "northstar-health",
"sourceName": "Northstar Health System (Synthetic)",
"codes": [{ "system": "http://www.nlm.nih.gov/research/umls/rxnorm", "code": "861007", "display": "Metformin 500 MG Oral Tablet" }],
"sourceUpdatedAt": null,
"syncedAt": "2026-08-25T17:00:00Z",
"name": "Metformin 500 mg tablet",
"status": "active",
"startDate": "2026-07-18"
}
That record is synthetic. Field definitions for each record type are in the schemas of openapi.yaml.
The whole record at once
GET /users/{subject}/records returns a snapshot of every shared category, or the ones you name in ?categories=. It has four parts:
| Part | What it holds |
|---|---|
data |
The records, grouped into sections. Most categories have one section; labs also fills diagnosticReports, and encounters fills appointments and careTeam. |
consent |
The receipts that allow this read, with their categories and expiry. |
sources |
The health systems this read covers, with a last-synced time taken from the records returned. meta.sources has the sync history. |
meta |
Freshness and completeness. See Freshness, partial and stale records. |
Use the snapshot to show a summary. To import records into your own database, page through categories instead. See Read and paginate.
Subjects
A subject is u_ followed by 16 hex characters. It's stable for your app and different for every other app, so two apps can't match a patient by subject.