# FinchNode > With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The platform supports read-only health applications in the United States, with provider search, hosted source authorization, application-specific consent, normalized records, sync state, and lifecycle webhooks. ## Free production-grade EHR API access. [Production-grade access is free with an account.](https://finchnode.com/signup) With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. The public demo API serves fixed fictional records for free without an account. Create a FinchNode account for free production-grade access to real, patient-authorized records within the included plan allowances. The demo itself cannot access real patient data. Free production access and the public synthetic demo | What you get | Free production plan | Public demo API | | --- | --- | --- | | Price | $0/month within included allowances | $0 | | Patient data | Real records with patient authorization and consent | Fixed fictional patient records only | | EHR access | Supported live sources; availability varies by organization | No live EHR connections | | Included usage | 100 connected patient-months; 100,000 production API calls/month; 1 production app | Rate-limited sample API | | Getting started | Account, production credentials, and source availability | No account or API key | Production access requires a FinchNode account, production credentials, a supported live source, and patient authorization and consent. Availability depends on the EHR, organization, application approvals, scopes, and records returned. [Free production EHR API](https://finchnode.com/ehr-integration-api) · [Plans and usage allowances](https://finchnode.com/#pricing) FinchNode does not claim universal EHR coverage, write-back, provider-side bulk access, scheduling, or general HL7 interface-engine functionality. Production availability depends on the source, organization, application approval, granted scopes, patient authorization, and data returned. ## Canonical product pages - [FinchNode home](https://finchnode.com/) - [Free production EHR integration API](https://finchnode.com/ehr-integration-api) - [Production pricing and allowances](https://finchnode.com/#pricing) - [Supported integration directory](https://finchnode.com/integrations) - [Developer Academy](https://finchnode.com/developers) - [Public synthetic demo API — no account needed](https://finchnode.com/developers/demo-api): Production-grade access is free with a FinchNode account at https://finchnode.com/signup. - [Synthetic FinchNode Visualizer](https://finchnode.com/tools/finchnode-visualizer) - [FinchNode Engineering author profile](https://finchnode.com/authors/finchnode-engineering) ## Developer and machine-readable resources - [Accountless demo OpenAPI 3.1](https://finchnode.com/demo-openapi.json) - [Authenticated API OpenAPI 3.1](https://finchnode.com/openapi.yaml) - [Live public demo API](https://api.finchnode.com/demo/v1) - [Public synthetic MCP server](https://api.finchnode.com/demo/mcp) - [Full machine-readable FinchNode reference](https://finchnode.com/llms-full.txt) - [Developer guide RSS feed](https://finchnode.com/feed.xml) - [XML sitemap](https://finchnode.com/sitemap.xml) ## Technical guides - [What we learned building patient-authorized FHIR connections across EHRs.](https://finchnode.com/blog/fhir-connections-across-ehrs-field-notes.md): Firsthand FinchNode engineering notes on endpoint discovery, SMART authorization, scopes, patient context, and source-specific FHIR behavior. - [SMART on FHIR OAuth with PKCE in React and Node.js.](https://finchnode.com/blog/smart-on-fhir-oauth-pkce-react-node.md): Implement a SMART on FHIR standalone authorization-code flow with PKCE, state validation, discovery, and server-side token exchange. - [Fetch patient data with a FHIR API: Patient, labs, conditions, and medications.](https://finchnode.com/blog/fhir-api-tutorial-patient-data.md): Fetch Patient, Observation, Condition, and MedicationRequest resources safely with FHIR R4 searches and server-provided pagination. - [Epic and MyChart FHIR integration for patient-facing applications.](https://finchnode.com/blog/epic-my-chart-fhir-integration-guide.md): Understand Epic patient-facing standalone OAuth, organization endpoints, PKCE, testing boundaries, and FHIR data access. - [Oracle Health FHIR integration: discovery, authorization, and tenant routing.](https://finchnode.com/blog/oracle-health-fhir-integration-guide.md): Build Oracle Health SMART integrations with tenant routing, discovery, patient context, scopes, and honest production validation. - [How to normalize FHIR data across EHRs without losing the source.](https://finchnode.com/blog/normalize-fhir-data-across-ehrs.md): Design a source-aware normalization layer for FHIR resources without erasing provenance, codes, missing data, or lifecycle state. - [FHIR Patient $everything: pagination, missing data, and production caveats.](https://finchnode.com/blog/fhir-patient-everything-guide.md): Use the FHIR Patient $everything operation safely with date filters, type filters, Bundle pagination, size limits, and fallback searches. - [FHIR API error handling: retries, rate limits, and partial results.](https://finchnode.com/blog/fhir-api-errors-retries-rate-limits.md): Handle FHIR OperationOutcome errors, timeouts, rate limits, retries, partial sync, and idempotency without hiding data loss. - [Patient authorization versus application consent in healthcare APIs.](https://finchnode.com/blog/patient-authorization-vs-app-consent.md): Separate EHR authorization from application-specific sharing consent, category limits, revocation, expiry, and deletion. - [Build a longitudinal patient record with TypeScript.](https://finchnode.com/blog/longitudinal-patient-record-typescript.md): Aggregate source-aware FHIR records into a chronological patient timeline with stable identity, provenance, deduplication, and change cursors. - [FHIR vs HL7 v2 vs C-CDA: a developer’s guide.](https://finchnode.com/blog/fhir-vs-hl7-v2-vs-ccda.md): Compare FHIR APIs, HL7 v2 event messages, and C-CDA clinical documents by transport, granularity, workflow, and implementation fit. - [The 7 best FHIR interoperability platforms for health apps in 2026.](https://finchnode.com/blog/best-fhir-interoperability-platforms.md): Compare seven FHIR interoperability platforms by use case, data access model, workflow, and developer fit—including FinchNode, Redox, and Zus. - [How one API connects your app to multiple EHRs.](https://finchnode.com/blog/one-api-connect-to-multiple-ehrs.md): Learn how one API connects multiple EHR systems and how FinchNode’s free production plan provides real, patient-authorized records alongside a synthetic demo. - [The easier way to get patient data from EHRs.](https://finchnode.com/blog/easier-access-to-patient-data.md): Compare direct FHIR integrations, patient-authorized APIs, and clinical data networks to find the easiest compliant path to patient EHR data. ## Integration pages - [Epic](https://finchnode.com/integrations/epic): Add patient-authorized Epic and MyChart record access to your health app through FinchNode’s hosted Connect flow and normalized API. - [Oracle Health (Cerner)](https://finchnode.com/integrations/oracle-health): Connect patient-authorized Oracle Health and Cerner records to your app through one hosted flow and normalized FinchNode API. - [athenahealth](https://finchnode.com/integrations/athenahealth): Add patient-authorized athenahealth record access to your health app with FinchNode’s hosted connection flow and unified API. - [eClinicalWorks / healow](https://finchnode.com/integrations/eclinicalworks-healow): Connect patient-authorized eClinicalWorks and healow records to your app through FinchNode’s hosted flow and normalized API. - [MEDITECH Expanse](https://finchnode.com/integrations/meditech): Add patient-authorized MEDITECH Expanse record access to your health app through FinchNode’s hosted flow and unified API. - [Veradigm / Allscripts](https://finchnode.com/integrations/veradigm-allscripts): Connect patient-authorized Veradigm and Allscripts records through FinchNode’s hosted flow and normalized EHR API. - [Medicare Blue Button 2.0](https://finchnode.com/integrations/medicare-blue-button): Add patient-authorized Medicare claims and coverage data to your digital health app through FinchNode and CMS Blue Button 2.0. --- # Complete FinchNode developer guide text # What we learned building patient-authorized FHIR connections across EHRs. A transparent implementation report covering the patterns that repeated, the behaviors that did not, and the evidence boundary behind FinchNode’s current integration work. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/fhir-connections-across-ehrs-field-notes - Evidence boundary: Based on FinchNode implementation work, public vendor documentation, synthetic testing, directory validation, and the production-readiness evidence available on August 25, 2026. ## Bottom line FHIR creates a common resource model, but a production patient-access connection still varies by organization discovery, OAuth registration, SMART metadata, scopes, patient context, token lifecycle, and resource availability. A reliable aggregation layer must preserve those differences as explicit state rather than hiding them behind a universal-coverage claim. ## Key takeaways - Vendor support and production-ready connectivity are different claims; FinchNode tracks them separately. - The recurring engineering work is discovery, authorization, patient context, normalization, provenance, and lifecycle handling—not merely issuing a FHIR GET request. - One API can give an application a stable contract while still reporting source-specific limits and incomplete data honestly. ## Evidence boundary: what this report does and does not claim These notes describe FinchNode’s implementation experience, not a certification of every endpoint operated by an EHR vendor. We count an integration as fully validated only after the relevant registration, authorization, callback, token exchange, patient context, representative FHIR reads, and lifecycle behavior have been observed in the applicable environment. As of this review, Epic is the only FinchNode integration treated internally as production-ready. Several other adapters have meaningful code, directory, approval, or sandbox evidence but still lack a completed live production patient lifecycle. Publishing that distinction is important because a supported vendor logo is not evidence that every organization or record will work. > No patient records, credentials, access tokens, or protected health information were used to prepare this public report. ## The implementation patterns we observed The exact state changes as onboarding advances, so this table records the evidence available on the review date rather than making a permanent coverage promise. Selected FinchNode integration evidence reviewed on August 25, 2026 | Source family | Observed engineering pattern | Evidence boundary | | --- | --- | --- | | Epic / MyChart | Standalone patient OAuth, PKCE-capable authorization, organization endpoint routing | Sandbox and production application path validated; organization data still varies | | Oracle Health | Directory-driven tenant routing plus tenant SMART/OIDC discovery | Developer testing and directory routing validated; live production patient lifecycle incomplete | | athenahealth | Separate preview and production registrations with signed OIDC validation | Branded production login reached; live patient lifecycle incomplete | | Veradigm / Allscripts | Organization-specific FHIR routing with authorization metadata on distinct hosts | Production access approved and discovery validated; live patient lifecycle incomplete | | MEDITECH | Strict callback registration, PKCE, and environment-specific FHIR bases | Partial Greenfield authorization and token evidence; complete application lifecycle incomplete | | Medicare Blue Button | Beneficiary authorization for claims and coverage rather than an EHR clinical record | Sandbox registration and initial API evidence; production review incomplete | ## What repeated across integrations - A source-selection step must resolve the organization the patient recognizes to the endpoint the application needs. - Authorization metadata, redirect URIs, client type, scopes, and PKCE behavior must match the registered application exactly. - The authorized patient context must be bound to the source connection before clinical resources are read. - FHIR searches can return empty, partial, paginated, duplicated, or differently profiled results without the connection itself being broken. - Refresh, expiry, revocation, disconnect, and reauthorization require explicit lifecycle states and audit evidence. - Every normalized record needs source identity and freshness metadata so applications can explain where it came from. ## What did not become uniform FHIR R4 does not make every organization expose the same profiles, search parameters, history, notes, or terminology. Even inside one vendor family, tenant configuration and product versions can change the result. Patient matching and portal enrollment can also prevent a technically correct authorization request from producing a usable record. FinchNode therefore treats completeness, source status, and provenance as part of the API response. The platform should never manufacture a complete longitudinal record when a source returned less information. ## The architecture that survived those differences 1. **1. Resolve the source** Search a maintained organization directory and retain the selected endpoint identity. 2. **2. Discover and authorize** Read supported SMART metadata, create a state-bound authorization request, and validate the callback. 3. **3. Bind patient context** Associate the granted source patient identifier with an application-scoped FinchNode subject. 4. **4. Retrieve with limits** Follow server-provided pagination, record OperationOutcome details, and avoid assuming unsupported searches. 5. **5. Normalize without erasing provenance** Create stable application categories while preserving source identifiers, resource type, and timestamps. 6. **6. Enforce sharing and lifecycle state** Apply the application-specific consent boundary to reads, webhooks, revocation, and deletion. ### Primary sources - [SMART App Launch 2.2](https://hl7.org/fhir/smart-app-launch/) - [FHIR R4 RESTful API](https://hl7.org/fhir/R4/http.html) - [US Core Implementation Guide](https://hl7.org/fhir/us/core/STU9/) ## Frequently asked questions ### Does FinchNode claim to connect to every EHR? No. FinchNode provides one application contract across supported patient-access sources. Availability still depends on the organization endpoint, application approval, patient authorization, scopes, and returned data. ### Why can two FHIR servers return different patient records? FHIR standardizes resources and API patterns, but servers can support different profiles, searches, data histories, terminology, and tenant configurations. The underlying patient record can also differ by organization. ### What makes an EHR integration production-ready? FinchNode requires evidence across registration, endpoint routing, authorization, callback and token exchange, patient context, representative data reads, refresh or expiry, revocation, disconnect, and monitoring. ### Is this a benchmark of EHR vendors? No. It is an implementation field report with explicit evidence limits. It should not be read as a vendor performance score or universal compatibility certification. --- # SMART on FHIR OAuth with PKCE in React and Node.js. A security-first walkthrough of discovery, authorization, callback validation, and token exchange for a standalone patient-facing application. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/smart-on-fhir-oauth-pkce-react-node - Evidence boundary: Protocol behavior is grounded in SMART App Launch 2.2. The code is educational and uses placeholder endpoints rather than a live EHR. ## Bottom line A SMART standalone launch is an OAuth 2.0 authorization-code flow with FHIR-specific discovery, audience, scopes, and patient context. Generate PKCE and state on the server, send only the authorization URL to React, and exchange the returned code from a trusted backend. ## Key takeaways - Use `.well-known/smart-configuration` instead of hard-coding authorization endpoints when the server publishes it. - Bind state and the PKCE verifier to a short-lived server-side transaction. - Treat the browser as a navigation surface; keep token exchange and persistent tokens on the backend. ## The standalone launch sequence 1. **1. Discover** Read the server’s SMART configuration and select its authorize and token endpoints. 2. **2. Prepare** Generate unpredictable state and a PKCE verifier; store them with a short expiry. 3. **3. Redirect** Request an authorization code with the registered redirect URI, FHIR audience, minimum scopes, and S256 challenge. 4. **4. Validate** On callback, reject missing, expired, reused, or mismatched state before exchanging the code. 5. **5. Exchange** Send the code, verifier, client identifier, and exact redirect URI to the token endpoint. 6. **6. Bind** Validate the response and associate the returned patient context with the authorized source connection. ## Generate state and PKCE on the Node.js server The verifier must remain secret until the token exchange. Store only the transaction identifier in the browser session or secure, same-site cookie. ```javascript import { createHash, randomBytes } from 'node:crypto'; const base64url = (value) => value.toString('base64url'); const state = base64url(randomBytes(32)); const verifier = base64url(randomBytes(64)); const challenge = base64url(createHash('sha256').update(verifier).digest()); await transactions.save({ state, verifier, expiresAt: Date.now() + 5 * 60_000 }); const authorize = new URL(smart.authorize_endpoint); authorize.searchParams.set('response_type', 'code'); authorize.searchParams.set('client_id', process.env.FHIR_CLIENT_ID); authorize.searchParams.set('redirect_uri', 'https://app.example.com/auth/callback'); authorize.searchParams.set('aud', fhirBaseUrl); authorize.searchParams.set('scope', 'openid fhirUser launch/patient patient/*.rs'); authorize.searchParams.set('state', state); authorize.searchParams.set('code_challenge', challenge); authorize.searchParams.set('code_challenge_method', 'S256'); return { authorizationUrl: authorize.toString() }; ``` ## Validate the callback before exchanging the code Use the exact redirect URI registered with the server. Consume state once so a valid callback cannot be replayed. Do not log authorization codes or token responses. ```javascript const transaction = await transactions.consume(request.query.state); if (!transaction || transaction.expiresAt < Date.now()) throw new Error('invalid_state'); const body = new URLSearchParams({ grant_type: 'authorization_code', code: request.query.code, client_id: process.env.FHIR_CLIENT_ID, redirect_uri: 'https://app.example.com/auth/callback', code_verifier: transaction.verifier, }); const tokenResponse = await fetch(smart.token_endpoint, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body, }); if (!tokenResponse.ok) throw new Error('token_exchange_failed'); const token = await tokenResponse.json(); ``` ### Primary sources - [SMART launch and authorization](https://hl7.org/fhir/smart-app-launch/STU2.2/app-launch.html) - [SMART scopes and launch context](https://hl7.org/fhir/smart-app-launch/STU2/scopes-and-launch-context.html) ## Production checklist - Require HTTPS and exact pre-registered redirect URIs. - Validate issuer, audience, signature, expiry, and nonce before trusting an ID token. - Encrypt refresh tokens at rest and keep them out of browser storage. - Request the least data and shortest duration the product needs. - Handle denied consent, missing patient context, token expiry, revocation, and reauthorization as normal states. - Apply timeouts, response-size limits, and an outbound-host allowlist to discovery and token requests. ## Frequently asked questions ### Is PKCE required for SMART on FHIR? SMART App Launch 2.2 requires apps to support PKCE. Servers validate the code verifier during token exchange. Use the S256 challenge method. ### Should React exchange the authorization code? A browser-only public client can implement PKCE, but applications with a backend should generally keep token exchange and persistent tokens on the trusted server so tokens are not exposed to browser storage or application JavaScript. ### What is the SMART aud parameter? It identifies the FHIR resource server the application intends to access. Use the server’s advertised FHIR base URL and follow the implementation guide and vendor registration requirements. ### Where does patient context come from? For a standalone patient launch, the authorization server can return a patient identifier in the token response when the granted launch context includes a patient. --- # Fetch patient data with a FHIR API: Patient, labs, conditions, and medications. A practical TypeScript pattern for reading common patient resources without assuming that every FHIR server behaves identically. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/fhir-api-tutorial-patient-data - Evidence boundary: Examples follow FHIR R4 REST and Bundle semantics and use fictional URLs and patient identifiers. ## Bottom line Read the Patient resource first, then issue patient-scoped searches for the clinical resources your app is authorized to access. Follow the server’s Bundle `next` links verbatim, retain provenance, and distinguish an empty search from a failed search. ## Key takeaways - A successful FHIR search returns a `searchset` Bundle, including when it contains zero matching resources. - Follow the server-provided `next` URL rather than constructing page numbers yourself. - Do not assume MedicationRequest alone represents every medication list returned by every source. ## Start with an explicit request plan Common patient data categories and representative FHIR R4 resources | Product category | FHIR resources to evaluate | Important fields | | --- | --- | --- | | Demographics | Patient | name, birthDate, gender, address, telecom | | Labs and vitals | Observation, DiagnosticReport | status, category, code, value, effective date, reference range | | Conditions | Condition | clinicalStatus, verificationStatus, code, onset | | Medications | MedicationRequest, MedicationStatement | status, intent, medication, authoredOn | ## Follow FHIR Bundle pagination safely ```typescript type FhirResource = { resourceType: string; id?: string }; type Bundle = { resourceType: 'Bundle'; type: 'searchset'; entry?: Array<{ resource?: FhirResource }>; link?: Array<{ relation: string; url: string }>; }; export async function readAll(url: string, token: string, maxPages = 20) { const resources: FhirResource[] = []; let next: string | undefined = url; for (let page = 0; next && page < maxPages; page += 1) { const response = await fetch(next, { headers: { accept: 'application/fhir+json', authorization: `Bearer ${token}` }, }); if (!response.ok) throw await fhirError(response); const bundle = (await response.json()) as Bundle; if (bundle.resourceType !== 'Bundle') throw new Error('unexpected_fhir_response'); resources.push(...(bundle.entry ?? []).flatMap((item) => item.resource ? [item.resource] : [])); next = bundle.link?.find((link) => link.relation === 'next')?.url; } return resources; } ``` ## Representative patient-scoped searches > Search support is advertised by a server’s CapabilityStatement and implementation guide. Treat these URLs as patterns, not a promise that every source accepts every parameter. ```http GET {fhirBase}/Patient/{patientId} GET {fhirBase}/Observation?patient={patientId}&category=laboratory&_count=100 GET {fhirBase}/Condition?patient={patientId}&_count=100 GET {fhirBase}/MedicationRequest?patient={patientId}&_count=100 Accept: application/fhir+json Authorization: Bearer {accessToken} ``` ## Normalize after preserving the source - Store the FHIR base, resource type, logical ID, business identifiers, and `meta.lastUpdated`. - Keep coding systems alongside display text; do not collapse different code systems into an unlabeled string. - Represent missing values as unavailable instead of inventing defaults. - Deduplicate only with source-aware identifiers and domain-specific rules. - Keep the raw source resource or an integrity-protected reference when your policy permits it. ### Primary sources - [FHIR R4 RESTful API](https://hl7.org/fhir/R4/http.html) - [FHIR R4 resource identity](https://hl7.org/fhir/R4/resource.html) ## Frequently asked questions ### What does an empty FHIR search return? A successful search normally returns a Bundle of type `searchset` with zero entries. That is different from a failed search, which should return an error status and typically an OperationOutcome. ### How do I paginate through FHIR results? Follow the Bundle link whose relation is `next`. Do not infer or rewrite the continuation URL because servers can use opaque paging state. ### Which FHIR resource contains lab results? Individual laboratory results are commonly represented as Observation resources, often with related DiagnosticReport resources. The exact profiles and search support depend on the server. ### Can I fetch every patient record with one request? Some servers support Patient `$everything`, but its content, parameters, size, and paging behavior vary. Resource-specific searches are often easier to operate and troubleshoot. --- # Epic and MyChart FHIR integration for patient-facing applications. The production work around an Epic connection extends beyond the authorize URL: application registration, organization routing, exact callbacks, patient context, scopes, and source-specific validation all matter. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/epic-my-chart-fhir-integration-guide - Evidence boundary: Combines FinchNode implementation experience with Epic’s public OAuth and testing documentation. It does not claim that every Epic organization exposes identical data. ## Bottom line Use a standalone patient-facing OAuth flow when the patient begins in your application. Register the exact redirect URI, route to the selected organization’s FHIR environment, use PKCE, validate state, and test with the application’s non-production registration before pursuing production use. ## Key takeaways - “Epic integration” is an organization-routing problem as well as an OAuth problem. - Epic recommends PKCE, and current SMART guidance requires applications to support it. - Open sandbox success does not prove an individual customer environment or complete production workflow. ## Choose the correct launch pattern For a patient-facing product that starts outside MyChart, use the standalone launch pattern. The application initiates authorization, Epic authenticates the patient, and the token response supplies the authorized context. An EHR or MyChart launch is a different workflow because Epic initiates the launch and supplies a launch value. ## Build the authorization request from registered values ```http GET {authorizeEndpoint}?response_type=code &client_id={nonProductionClientId} &redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fepic%2Fcallback &aud={encodedOrganizationFhirBase} &scope=openid%20fhirUser%20launch%2Fpatient%20patient%2F*.rs &state={oneTimeState} &code_challenge={s256Challenge} &code_challenge_method=S256 ``` ## What the sandbox cannot prove - That the selected healthcare organization is live for your registered production application. - That the organization returns every configured resource or historical record. - That portal enrollment, proxy access, or patient matching will succeed for every user. - That refresh, logout, revocation, and reauthorization behave identically in every environment. - That an EHR-launched workflow works when only standalone authorization was tested. ## What FinchNode puts behind one connection contract FinchNode separates provider selection from application code, maintains source routing, performs the hosted authorization handoff, tracks connection state, and exposes approved normalized categories through its server API. It still reports source, availability, and sync status so the abstraction does not imply universal data. ### Primary sources - [Epic OAuth 2.0 documentation](https://fhir.epic.com/Documentation?docId=oauth2) - [SMART App Launch](https://hl7.org/fhir/smart-app-launch/) ## Frequently asked questions ### Can a patient-facing app connect to Epic through MyChart? Yes, when the application is registered for the appropriate patient-facing workflow and the selected organization supports the required endpoint and scopes. The patient authenticates with the source, not with FinchNode. ### Does one Epic sandbox cover every hospital? No. A sandbox validates important protocol behavior but does not reproduce every organization’s endpoint configuration, version, data, or patient workflow. ### Should an Epic app use PKCE? Yes. Epic recommends PKCE, and SMART App Launch 2.2 requires applications to support it. Use S256 rather than a plain challenge. ### Does FinchNode receive MyChart passwords? No. The simulated FinchNode Visualizer demonstrates the handoff, but real patient credentials belong only on the healthcare organization’s authorization experience. --- # Oracle Health FHIR integration: discovery, authorization, and tenant routing. A developer guide to the parts of an Oracle Health connection that live outside the resource request itself. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/oracle-health-fhir-integration-guide - Evidence boundary: Based on Oracle Health’s public authorization documentation and FinchNode directory and discovery implementation work. Live production patient validation remains a separate evidence threshold. ## Bottom line Oracle Health implements SMART-style OAuth and FHIR, but an application still needs to resolve the correct organization environment, use registered callbacks, request appropriate context, and validate the discovered issuer and endpoints before reading data. ## Key takeaways - Treat the FHIR base and authorization metadata as tenant-specific input. - Keep Millennium, Soarian, sandbox, and production evidence distinct. - Validate patient context and granted scopes instead of assuming the requested set was approved. ## Resolve the organization before authorization A patient recognizes a hospital or clinic, while an application needs a FHIR base and authorization server. The connection flow should retain the selected organization, resolve its published endpoint, and perform SMART or OIDC discovery against an allowed host before constructing the authorization request. ## Validate discovered metadata ```typescript const fhirBase = new URL(selectedOrganization.fhirBaseUrl); if (fhirBase.protocol !== 'https:') throw new Error('https_required'); assertAllowedHealthcareHost(fhirBase.hostname); const metadataUrl = new URL('.well-known/smart-configuration', `${fhirBase}/`); const smart = await fetchJson(metadataUrl, { timeoutMs: 8_000 }); for (const value of [smart.authorization_endpoint, smart.token_endpoint]) { const endpoint = new URL(value); if (endpoint.protocol !== 'https:') throw new Error('invalid_smart_metadata'); assertAllowedHealthcareHost(endpoint.hostname); } ``` ## Bind authorization to returned context - Use the exact registered redirect URI and client type for the environment. - Validate one-time state and PKCE before accepting the token response. - Record the granted scope string because it can be narrower than the request. - Require the expected patient context before issuing patient-scoped reads. - Validate OIDC issuer, signature, audience, expiry, and nonce when identity scopes are used. ## Separate implementation evidence from production coverage FinchNode has validated Oracle Health developer testing and directory-driven routing. The public claim remains intentionally narrower than universal production support because a full live production patient lifecycle has a higher evidence requirement than successful discovery or sandbox authorization. ### Primary sources - [Oracle Health authorization framework](https://docs.oracle.com/en/industries/health/millennium-platform-apis/fhir-authorization-framework/) - [Oracle Health SMART application testing](https://docs.oracle.com/en/industries/health/health-ai-application-suite/aibta/index.html) ## Frequently asked questions ### Is Oracle Health the same as Cerner for FHIR integrations? Oracle Health includes the platform historically known as Cerner, but products and organization environments can differ. Use the endpoint and implementation guidance for the selected organization and workflow. ### Does Oracle Health support SMART on FHIR? Oracle Health documents OAuth 2.0 authorization with the SMART on FHIR profile, including registered redirect URIs and launch context. ### Why is tenant discovery important? The patient chooses an organization, and that organization determines the correct FHIR base and authorization metadata. Hard-coding one endpoint does not cover a multi-organization product. ### Does a published endpoint prove production access? No. It proves that an endpoint was published. Application approval, organization configuration, authorization, scopes, patient context, data reads, and lifecycle behavior must still be validated. --- # How to normalize FHIR data across EHRs without losing the source. Normalization should reduce application branching while retaining the evidence needed to explain, reconcile, and refresh every clinical fact. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/normalize-fhir-data-across-ehrs - Evidence boundary: Uses FHIR R4 identity and Provenance semantics plus FinchNode’s source-aware record contract. ## Bottom line Normalize into stable product categories, but preserve the source resource type, logical and business identifiers, coding systems, timestamps, and availability state. A normalized value without provenance is easier to display but harder to trust. ## Key takeaways - Use a canonical application model and retain a reversible link to the source representation. - Deduplication is a domain decision; equal display strings are not sufficient evidence that two records are the same. - Missing, unsupported, delayed, and revoked are different states and should not collapse into an empty array. ## Put every normalized item inside a provenance envelope ```typescript type NormalizedRecord = { id: string; category: string; data: T; source: { connectionId: string; organizationId: string; fhirBaseUrl: string; resourceType: string; resourceId?: string; identifiers: Array<{ system?: string; value: string }>; lastUpdated?: string; }; availability: 'available' | 'partial' | 'unsupported' | 'syncing' | 'revoked'; }; ``` ## Normalize codes without flattening meaning - Retain every source coding system, code, display, and original text. - Add normalized terminology as an additional mapping rather than replacing the source coding. - Record the mapping version and confidence or review state. - Do not equate units until quantities have compatible dimensions and an explicit conversion. - Keep reference ranges source-specific because age, sex, method, and laboratory can change them. ## Use layered, explainable deduplication A conservative order for assessing possible duplicate records | Signal | Strength | Caution | | --- | --- | --- | | Same source and stable business identifier | Strong | Confirm identifier system and source namespace | | Same source logical ID and version lineage | Strong within one server | Logical IDs can change when copied between servers | | Same code, value, date, and performer | Moderate | Repeated clinical events can be legitimately identical | | Same display text | Weak | Text can hide different code systems or clinical meanings | ## Represent completeness as data A source can authorize successfully while returning no resources for a category. That may mean the patient has no matching records, the server does not support the search, the scope was not granted, the source is delayed, or the connection is still syncing. Preserve the reason and observation time instead of returning an unexplained empty result. ### Primary sources - [FHIR R4 resource identity](https://hl7.org/fhir/R4/resource.html) - [FHIR R4 Provenance](https://hl7.org/fhir/R4/provenance.html) - [US Core guidance](https://hl7.org/fhir/us/core/STU9/) ## Frequently asked questions ### Why normalize FHIR if it is already a standard? FHIR standardizes resource structures and API patterns, but implementations can use different profiles, codes, resource choices, optional fields, and search behavior. Applications still need a stable product contract. ### Should normalized data keep the original FHIR resource? Keep an integrity-protected source representation or reference when policy and storage constraints permit it. At minimum, retain enough provenance and identifiers to explain and reconcile the normalized item. ### Can records be deduplicated by code and date? Those fields are useful signals but not proof. Repeated clinical events can share the same code and date, so deduplication should be source-aware and explainable. ### What is the difference between missing and unsupported data? Missing means a supported query returned no known value. Unsupported means the source or granted scope cannot provide that category. Syncing, failed, and revoked are additional distinct states. --- # FHIR Patient $everything: pagination, missing data, and production caveats. The operation can simplify record retrieval, but it does not promise every resource, identical server behavior, or a small response. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/fhir-patient-everything-guide - Evidence boundary: Grounded in the FHIR R4 Patient `$everything` operation and standard Bundle paging behavior. ## Bottom line Patient `$everything` requests the information a server can return for an authorized patient. The response is a `searchset` Bundle and can be filtered, paged, limited, or unsupported. Production clients need size limits, continuation handling, and resource-specific fallbacks. ## Key takeaways - The operation returns what the server has and the user is authorized to access—not a universal complete record. - Use `_type`, `start`, `end`, `_since`, and `_count` only when the server supports the desired behavior. - Follow Bundle links and cap pages, bytes, and elapsed time. ## A bounded request is easier to operate ```http GET {fhirBase}/Patient/{patientId}/$everything ?start=2025-01-01 &end=2026-08-25 &_type=Condition,Observation,MedicationRequest,AllergyIntolerance &_count=200 Accept: application/fhir+json Authorization: Bearer {accessToken} ``` ## Treat the Bundle as an unordered retrieval result The FHIR R4 operation defines a `searchset` Bundle. It can include the Patient, related clinical resources, and supporting referenced resources. It does not define an inherent display order, so build a timeline from clinical dates rather than Bundle entry position. ## Production guardrails - Reject `next` links that leave the trusted FHIR host policy. - Apply maximum pages, response bytes, resources, and elapsed time. - Persist a resumable cursor or server continuation only when the source contract permits it. - Record OperationOutcome entries and warnings instead of discarding them. - Fall back to resource-specific searches when the operation is unsupported or too broad. - Deduplicate supporting resources without assuming Bundle order or uniqueness. ### Primary sources - [FHIR R4 Patient $everything](https://hl7.org/fhir/R4/operation-patient-everything.html) - [FHIR R4 paging and HTTP behavior](https://hl7.org/fhir/R4/http.html) ## Frequently asked questions ### Does Patient $everything return the complete medical record? It returns the related information the server has and the authorization context permits. That is not a guarantee of every historical record, source, document, or data category. ### Can a $everything response be paginated? Yes. Servers can require or support paging. Follow the Bundle `next` link and use bounded retrieval safeguards. ### Can I filter Patient $everything? FHIR R4 defines parameters including start, end, `_since`, `_type`, and `_count`, but clients should confirm the target server’s implementation behavior. ### What should I do if $everything is unsupported? Use the server’s CapabilityStatement and implementation guide to construct supported resource-specific patient searches. --- # FHIR API error handling: retries, rate limits, and partial results. A production integration needs a failure model that separates authentication, authorization, unsupported behavior, source outages, and incomplete synchronization. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/fhir-api-errors-retries-rate-limits - Evidence boundary: Uses FHIR R4 HTTP and OperationOutcome semantics with conservative distributed-systems retry practices. ## Bottom line Retry only transient and safely repeatable work, honor server guidance, parse OperationOutcome when present, and expose partial sync state. An integration is more trustworthy when it reports incomplete data than when it silently returns an empty record. ## Key takeaways - A 200 empty search, a 403 scope denial, a 404 unsupported resource, and a timeout require different product states. - Use exponential backoff with jitter and a retry budget; never create an unbounded retry loop. - Persist per-source and per-category progress so one failed query does not erase successful data. ## Start with an actionable error taxonomy Representative FHIR integration outcomes | Outcome | Likely interpretation | Default action | | --- | --- | --- | | 200 with zero entries | Successful search with no matches | Record empty result and freshness | | 400 + OperationOutcome | Invalid or unsupported request | Do not retry unchanged; inspect issue details | | 401 | Missing or expired authorization | Refresh once or require reauthorization | | 403 | Granted access does not permit request | Mark category unavailable; do not loop | | 404 | Resource or endpoint unsupported/not found | Check capability and route | | 429 | Rate limited | Honor Retry-After and retry budget | | 5xx / timeout | Transient source or network failure | Bounded retry with jitter | ## Use a bounded retry helper ```typescript export async function withRetry(operation: () => Promise, attempts = 4) { let lastError: unknown; for (let attempt = 0; attempt < attempts; attempt += 1) { try { return await operation(); } catch (error) { lastError = error; if (!isTransient(error) || attempt === attempts - 1) throw error; const base = Math.min(500 * 2 ** attempt, 8_000); const jitter = Math.floor(Math.random() * 250); await new Promise((resolve) => setTimeout(resolve, base + jitter)); } } throw lastError; } ``` ## Make partial synchronization visible - Track status for each connection and record category. - Return the latest successful data with its timestamp when policy permits stale reads. - Include a machine-readable reason for unavailable or delayed categories. - Emit lifecycle events when a connection requires user action. - Never replace previously successful data with an unexplained empty snapshot after a failed refresh. ### Primary sources - [FHIR R4 HTTP behavior and errors](https://hl7.org/fhir/R4/http.html) - [FHIR R4 OperationOutcome](https://hl7.org/fhir/R4/operationoutcome.html) ## Frequently asked questions ### Should a FHIR client retry every 500 response? Only with a bounded policy and only when the operation is safe to repeat. Consider server guidance, idempotency, elapsed time, and an overall retry budget. ### What is a FHIR OperationOutcome? It is the standard FHIR resource for reporting issues, errors, warnings, and diagnostics. Parse it when present, but still handle non-FHIR error bodies safely. ### Is an empty Bundle an error? No. A searchset Bundle with zero matching entries is normally a successful empty result. Preserve the distinction between empty, unsupported, unauthorized, and failed. ### How should an app show partial patient data? Show which sources and categories succeeded, their freshness, and which remain unavailable or syncing. Do not present a partial record as complete. --- # Patient authorization versus application consent in healthcare APIs. Source authorization answers whether data can be retrieved. Application consent answers whether a specific product may receive and use selected categories for a stated purpose. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/patient-authorization-vs-app-consent - Evidence boundary: Describes FinchNode’s product architecture. It is technical guidance, not legal advice or a substitute for counsel. ## Bottom line Keep source OAuth grants and application-sharing consent as separate records. Bind each to its purpose, data categories, application, timestamps, and lifecycle state, then fail closed when either boundary no longer permits access. ## Key takeaways - An OAuth grant from an EHR is not automatically consent to share every retrieved category with every downstream app. - Consent receipts should be versioned and machine-enforceable, not merely a checkbox event. - Revocation must change API behavior and downstream lifecycle state, not only the user interface. ## Model two independent boundaries Source authorization and application consent answer different questions | Boundary | Question | Representative state | | --- | --- | --- | | Source authorization | May the connection retrieve data from this source? | scopes, patient context, token expiry, revocation | | Application consent | May this application receive these categories for this purpose? | app ID, purpose, categories, policy version, expiry | ## Store an enforceable consent receipt ```json { "receiptId": "consent_demo_01", "subject": "usr_demo_01", "applicationId": "app_example", "purpose": "personalized-care-navigation", "categories": ["demographics", "medications", "labs"], "policyVersion": "2026-08-25", "status": "active", "grantedAt": "2026-08-25T17:00:00Z", "expiresAt": "2026-11-23T17:00:00Z" } ``` ## Enforce consent at every read boundary - Resolve the API key to one application and environment. - Verify that the subject currently shares with that application. - Intersect requested categories with the application allowlist and active consent. - Reject expired, revoked, or deleted consent before loading data. - Record a durable audit event without logging clinical payloads. - Propagate revocation, expiry, and deletion through signed lifecycle events. ## Technical controls do not decide the legal basis A consent service can enforce configured rules, but it cannot determine whether a company’s notice, purpose, retention, onward disclosure, or regulatory posture is legally sufficient. Product, privacy, security, and legal owners must define those requirements explicitly. ## Frequently asked questions ### Is an EHR OAuth approval the same as consent to share with an app? Not necessarily. OAuth authorizes access at the source. A platform can separately record which downstream application may receive which categories for which purpose. ### What should a consent receipt contain? At minimum: subject, application, purpose, approved categories, policy version, grant time, status, expiry if applicable, and lifecycle timestamps. ### What happens after revocation? Future API reads should fail closed, active sync should stop as required, and the system should issue durable lifecycle events and apply the configured deletion or retention policy. ### Is this legal advice? No. This is a technical architecture pattern. Organizations should obtain appropriate legal and privacy guidance for their use case. --- # Build a longitudinal patient record with TypeScript. A timeline is not a giant sorted array. It is a source-aware projection over records with different clinical dates, update times, identities, and completeness. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/longitudinal-patient-record-typescript - Evidence boundary: Uses synthetic examples and source-aware record practices; it does not provide clinical decision support. ## Bottom line Ingest records per source and category, retain stable source identities, map them to typed timeline events, and rebuild projections deterministically. Clinical time, source update time, and ingestion time should remain separate fields. ## Key takeaways - Use a stable source-aware key so refreshes update existing events instead of duplicating them. - Sort by clinical time for display while retaining update and ingestion timestamps for operations. - Treat uncertain dates and missing provenance as visible data-quality states. ## Define one timeline event without flattening the record ```typescript type TimelineEvent = { key: string; kind: 'lab' | 'condition' | 'medication' | 'encounter' | 'immunization'; clinicalTime?: string; recordedTime?: string; ingestedAt: string; title: string; summary?: string; source: { organization: string; resourceType: string; resourceId?: string }; confidence: 'exact' | 'derived' | 'unknown'; }; ``` ## Build stable, source-aware keys Prefer a stable business identifier within its namespace. Otherwise use the source connection, resource type, and logical ID. A content hash can help detect changes, but it should not be the sole real-world identity because clinically distinct events can contain identical data. ## Make refreshes incremental and reversible 1. **1. Read the next change window** Use a source cursor, supported history, or bounded updated-since query. 2. **2. Upsert source records** Preserve version, last-updated, and the raw-to-normalized mapping. 3. **3. Rebuild affected events** Regenerate projections deterministically for changed source records. 4. **4. Mark removals explicitly** Use tombstones or lifecycle state rather than silently deleting history. 5. **5. Commit the cursor** Advance progress only after the data and projection transaction succeeds. ## Design the timeline for uncertainty - Group events with date-only precision separately from exact timestamps when ordering could mislead. - Show source organization and freshness in the detail view. - Do not infer clinical causality from adjacent events. - Allow users to inspect the underlying coded concept and original text. - Indicate when one source or category is unavailable or still syncing. ### Primary sources - [FHIR R4 resource identity](https://hl7.org/fhir/R4/resource.html) - [FHIR R4 Provenance](https://hl7.org/fhir/R4/provenance.html) ## Frequently asked questions ### What is a longitudinal patient record? It is a record assembled over time and often across sources. A reliable implementation preserves source, clinical dates, update times, and completeness instead of presenting every event as equally certain. ### How should FHIR records be ordered? Use the clinically relevant date for display, not Bundle order or ingestion time. Keep date precision and uncertainty visible. ### How do I prevent duplicate timeline events? Use stable source-aware identity, business identifiers where reliable, version lineage, and conservative domain rules. Do not deduplicate only by display text. ### Can this timeline provide medical advice? No. It is a data organization pattern. Clinical interpretation and decision support require separate validation, governance, and regulatory analysis. --- # FHIR vs HL7 v2 vs C-CDA: a developer’s guide. These standards overlap, but they solve different integration problems. The right choice begins with the workflow and access relationship—not whichever acronym is newest. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-25 - Last reviewed: 2026-08-25 - Canonical URL: https://finchnode.com/blog/fhir-vs-hl7-v2-vs-ccda - Evidence boundary: Uses published HL7 specifications and implementation guides. Product availability still depends on the participating systems and contracts. ## Bottom line FHIR is resource-oriented and commonly accessed through modern APIs; HL7 v2 is an event-message standard deeply embedded in provider operations; C-CDA packages a clinical document with narrative and structured entries. Many real integrations use more than one. ## Key takeaways - FHIR is usually the best starting point for patient-authorized app access when supported. - HL7 v2 remains important for event-driven provider workflows such as admissions, orders, and results. - C-CDA is useful when the exchanged unit is a clinical document or summary rather than a resource query. ## Compare the integration unit, not only the syntax A workflow-oriented comparison of three healthcare interoperability standards | Standard | Primary exchange unit | Common fit | Operational reality | | --- | --- | --- | --- | | FHIR | Resource and Bundle through REST or other exchanges | Patient access, app integration, modern data services | Profiles, scopes, searches, and server behavior still vary | | HL7 v2 | Delimited event message | ADT, orders, results, and provider interfaces | Requires interface agreements, routing, acknowledgements, and local mapping | | C-CDA | Clinical document with narrative and structured entries | Summaries, transitions of care, document exchange | Parsing and section-level normalization are substantial tasks | ## Choose by workflow - Use patient-facing FHIR when an individual authorizes an app to read supported resources. - Use contracted FHIR or HL7 v2 when a provider needs operational events or write-back inside clinical workflows. - Use C-CDA when document fidelity and a human-readable clinical narrative are part of the exchange. - Expect translation when an application needs one normalized model across resource, message, and document sources. ## Why the standards coexist A hospital may expose patient-access data through FHIR, send admission events through HL7 v2, and exchange a transition-of-care summary as C-CDA. Replacing every mature interface is rarely the immediate goal. A platform should identify the source model, preserve provenance, and use the standard that fits the permitted workflow. ### Primary sources - [FHIR R4 specification](https://hl7.org/fhir/R4/) - [C-CDA on FHIR mapping guide](https://hl7.org/fhir/us/ccda/) - [HL7 standards overview](https://www.hl7.org/implement/standards/) ## Frequently asked questions ### Is FHIR replacing HL7 v2? FHIR is preferred for many modern API use cases, but HL7 v2 remains deeply used for provider event workflows. The standards often coexist. ### What is the difference between FHIR and C-CDA? FHIR commonly exchanges granular resources and Bundles, while C-CDA exchanges a clinical document containing narrative and structured sections. ### Which standard is best for patient-authorized access? FHIR with SMART authorization is usually the appropriate modern starting point when the source supports the needed patient-facing resources and scopes. ### Can one normalized API combine all three? A platform can normalize selected concepts from multiple standards, but it must retain source provenance and cannot guarantee identical coverage or semantics. --- # The 7 best FHIR interoperability platforms for health apps in 2026. A practical comparison of leading healthcare data platforms—and a clear framework for choosing the right one for patient access, treatment workflows, payer data, or enterprise EHR integration. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-24 - Last reviewed: 2026-09-08 - Canonical URL: https://finchnode.com/blog/best-fhir-interoperability-platforms - Evidence boundary: Based on public product and developer documentation reviewed on the article update date. - Disclosure: FinchNode publishes this comparison and is one of the products evaluated. Rankings are use-case based, limitations are stated, and competing product descriptions link to their primary documentation. ## Bottom line There is no honest universal “best” interoperability platform. FinchNode is our top choice for patient-facing products that need users to authorize read-only EHR data. Other platforms are stronger for payer infrastructure, treatment-based network exchange, or bidirectional provider workflows. ## Key takeaways - Choose the access model before choosing the vendor: patient-authorized access, treatment-based exchange, payer interoperability, and provider integration are different jobs. - A single FHIR API does not guarantee the same data, workflow, or production coverage at every organization. - Evaluate consent, provenance, normalization, sync behavior, sandbox quality, and production onboarding—not just the list of EHR logos. ## Short answer: which FHIR platform is best? For a patient-facing digital health product, FinchNode is the best fit when the user should connect and authorize their own records. It combines provider search, hosted source authorization, purpose-bound consent, normalized read-only data, and ongoing sync behind one application contract. For other use cases, the answer changes. Redox is oriented toward broad enterprise integration patterns, 1upHealth toward payer and population interoperability, Zus toward shared data for treatment relationships, and network platforms such as Health Gorilla, Particle Health, and Metriport toward longitudinal record retrieval for qualified healthcare organizations. > Our ranking is use-case based. “Best” means the strongest fit for a defined workflow—not the platform with the broadest marketing claim. ## FHIR interoperability platforms compared Start with the row that matches how your product is legally and operationally allowed to access data. That distinction will narrow the shortlist faster than a feature checklist. A use-case comparison of seven FHIR interoperability platforms | Platform | Best fit | Primary access pattern | What stands out | | --- | --- | --- | --- | | FinchNode | Patient-facing health apps | Patient-authorized, read-only access | Free production plan with real authorized records and one normalized API | | Redox | Provider and enterprise integrations | Contracted EHR connectivity | FHIR plus legacy standards and bidirectional workflow support | | 1upHealth | Payers and population data | Payer, clinical, and claims interoperability | FHIR-first data platform and population ingestion | | Zus Health | Care delivery builders | Treatment relationship and shared data | Shared record platform with REST and GraphQL access | | Metriport | Treatment-based record retrieval | Network queries for qualified providers | Consolidated FHIR plus documents from multiple source classes | | Health Gorilla | Clinical networks and diagnostics | Network retrieval and clinical workflows | FHIR R4, event notifications, ordering, and longitudinal records | | Particle Health | Longitudinal clinical data and analytics | Network query for verified organizations | FHIR, C-CDA, and analytics-oriented formats | ## How we evaluated the platforms We reviewed each platform’s public product and developer documentation as of August 24, 2026. We weighted workflow fit more heavily than raw feature count because the wrong access model can make an otherwise capable platform unusable for a product. - Access model: who initiates access, what relationship is required, and whether consent or a treatment purpose is the basis. - Connectivity: support for FHIR, documents, legacy interfaces, networks, and direct EHR connections. - Developer experience: sandbox, documentation, consistent APIs, webhooks, and production onboarding. - Data usability: normalization, source provenance, deduplication, change tracking, and predictable errors. - Workflow scope: read versus write, patient-facing versus provider-facing, and individual versus population access. ## 1. FinchNode — free production access to patient-authorized records With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. FinchNode is designed for products whose users want to bring their own health records into an app. Your backend creates one Connect session; the user finds a provider, authorizes on the source’s page, reviews the data categories, and separately chooses what to share with your application. That makes FinchNode a strong fit for consumer health, care navigation, second-opinion, clinical trial, benefits, and AI health products that need read-only patient data but do not want to build a different patient-access journey for every supported EHR family. - Best for: patient-facing products and patient-mediated data access. - Standout: provider search, hosted authorization, purpose-bound consent receipts, normalized records, and lifecycle webhooks in one flow. - Important limit: FinchNode is not a general HL7 interface engine, EHR write-back product, or provider-side population data network. [Explore FinchNode’s EHR integration API](https://finchnode.com/ehr-integration-api) ## 2. Redox — best for broad enterprise EHR integration Redox is a strong shortlist choice when an application must fit into provider workflows and exchange data across both modern and legacy standards. Its documentation covers FHIR exchange as well as translation from formats such as HL7 v2 for scenarios where an EHR does not support the required FHIR operation. That breadth is useful for health systems and vendors that need more than patient-directed record retrieval. It can also mean a more involved implementation and commercial process than a focused patient-access product requires. - Best for: contracted enterprise integrations, cloud delivery, and bidirectional clinical workflows. - Standout: support for both FHIR and legacy healthcare integration patterns. - Ask about: the implementation path and commercial model for each target EHR and workflow. [Review Redox’s official FHIR documentation](https://developer.redoxengine.com/basics/redox-fhir-api/exchanging-fhir-data/) ## 3. 1upHealth — best for payer and population interoperability 1upHealth positions its platform around standards-based clinical and claims data, with a particularly strong payer focus. Its Population Connect documentation describes scheduled ingestion from EHRs and conversion from HL7 v2 and C-CDA into FHIR. Teams working on payer compliance, member data, analytics, or population-scale clinical acquisition should evaluate it. A consumer app that only needs a lightweight patient-authorized connection flow may be solving a narrower problem than the broader 1up platform targets. - Best for: health plans, payer interoperability, and population data pipelines. - Standout: FHIR-first clinical and claims infrastructure. - Ask about: which product supports your exact individual, population, or payer workflow. [Review 1upHealth’s official platform documentation](https://docs.1up.health/docs) ## 4. Zus Health — best for a shared clinical data foundation Zus is a shared health data platform built for healthcare organizations and builders with appropriate patient relationships. Its developer materials describe FHIR R4 APIs, GraphQL access, normalized network data, embedded components, and EHR integrations. Zus is compelling when the product participates in care delivery and wants a shared longitudinal record foundation. Because its sharing and authorization model is tied to healthcare relationships, teams should confirm that their use case and operating model qualify. - Best for: care delivery companies building on a shared clinical record. - Standout: REST, GraphQL, embedded components, and network-sourced data on one platform. - Ask about: permitted purpose, patient relationship requirements, and data-sharing behavior. [Review Zus Health’s official developer overview](https://zushealth.com/developers/) ## 5. Metriport — best for treatment-based record retrieval Metriport offers a FHIR-native Medical API that can consolidate records from health information exchange networks and other source classes. Its public materials emphasize normalized FHIR R4, clinical documents, webhooks, and a developer-oriented API. Its production FAQ states that Medical API access requires requests on behalf of a covered entity with an NPI for a valid treatment purpose. That makes it a strong option for clinical workflows, while distinguishing it from patient-mediated access for general consumer products. - Best for: qualified treatment workflows that need broad record retrieval. - Standout: consolidated FHIR plus C-CDA and PDF documents from multiple sources. - Ask about: production eligibility, treatment-purpose requirements, and record matching. [Review Metriport’s official Medical API overview](https://www.metriport.com/platform/api) ## 6. Health Gorilla — best for network and diagnostic workflows Health Gorilla’s current API documentation describes a FHIR-first platform for longitudinal record retrieval, event notifications, diagnostic ordering, and national interoperability network workflows. This breadth can be valuable for organizations coordinating care or combining data access with labs and clinical events. It is more than a simple EHR aggregation API, so buyers should map the required workflow carefully and understand which services, networks, and permissions are part of the proposed implementation. - Best for: care coordination, clinical networks, notifications, and diagnostic workflows. - Standout: FHIR R4 APIs alongside record retrieval, events, and orders. - Ask about: network qualification, onboarding, permitted purpose, and which modules are included. [Review Health Gorilla’s official API overview](https://developer.healthgorilla.com/reference/health-gorilla-apis) ## 7. Particle Health — best for longitudinal data and analytics Particle Health provides patient data APIs for verified organizations to query clinical records across its network. Its developer documentation describes FHIR R4, C-CDA, and flat data formats, with webhooks for query completion and analytics-oriented retrieval options. It is a strong candidate when a qualified organization needs a longitudinal clinical record or wants analysis-ready outputs. As with every network product, coverage does not mean every record is returned for every patient, and production access depends on the organization and use case. - Best for: network-based clinical retrieval and data products that need multiple output formats. - Standout: FHIR, C-CDA, and flat representations from one query workflow. - Ask about: use-case approval, format provisioning, query coverage, and incremental updates. [Review Particle Health’s official patient data API guide](https://docs.particlehealth.com/docs/patient-data-apis) ## How to choose without buying the wrong platform Write down the sentence “We are allowed to access this data because…” before scheduling demos. If the answer is patient authorization, evaluate the connection and consent experience. If it is treatment, payment, or operations, evaluate network participation, identity matching, and permitted-purpose controls. If a provider has contracted for an interface, evaluate deployment, mapping, monitoring, and write-back. Then test with realistic edge cases: a patient with records at three systems, a revoked authorization, a delayed source, duplicate lab results, an organization that returns fewer resources, and a record that changes after the initial sync. The best platform is the one that makes those cases explicit and operable. Questions to ask every interoperability vendor | Question | Why it matters | | --- | --- | | What authorizes each request? | Determines whether the product fits your legal and operational use case. | | Which organizations are live in production? | Vendor-family support is not the same as endpoint-by-endpoint availability. | | What is normalized, and what remains source-specific? | Reveals how much branching and reconciliation your team still owns. | | How are consent, revocation, and deletion enforced? | Shows whether access boundaries survive beyond the initial OAuth screen. | | How do updates, failures, and duplicates appear? | Determines the operational burden after the demo works. | ## Frequently asked questions ### Is there a free EHR API for real patient data in production? Yes. With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. Production access requires a FinchNode account, production credentials, a supported live source, and patient authorization and consent. Availability depends on the EHR, organization, application approvals, scopes, and records returned. ### Is FinchNode only a synthetic demo or sandbox? No. With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The public demo API serves fixed fictional records for free without an account. Create a FinchNode account for free production-grade access to real, patient-authorized records within the included plan allowances. The demo itself cannot access real patient data. ### What is the best FHIR interoperability platform? The best platform depends on the workflow. FinchNode is built for patient-authorized, read-only EHR access. Provider integrations, payer data, treatment-based network exchange, and write-back may be better served by broader enterprise or network platforms. ### Can a FHIR platform connect to every EHR? No platform can honestly guarantee every EHR, organization, workflow, and data type. A platform can provide one integration contract across its supported sources, but live availability still depends on endpoints, approvals, scopes, data, and permitted use. ### Is FHIR enough for EHR interoperability? FHIR standardizes many data structures and API patterns, but production interoperability also requires authorization, identity matching, provider discovery, consent, terminology handling, normalization, monitoring, and support for source-specific behavior. ### How should a startup compare EHR API vendors? Begin with the access model and use case, then compare production source coverage, normalized data, sandbox quality, consent and revocation, sync behavior, webhooks, pricing, onboarding, and support. Test edge cases rather than only the happy path. --- # How one API connects your app to multiple EHRs. “One connection to all EHRs” is possible at the application layer—but only when the platform handles the source-specific work behind a consistent API. Here is what gets unified, what does not, and how to build it responsibly. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-24 - Last reviewed: 2026-09-08 - Canonical URL: https://finchnode.com/blog/one-api-connect-to-multiple-ehrs - Evidence boundary: Based on public product and developer documentation reviewed on the article update date. ## Bottom line An EHR aggregation platform lets your product integrate once while it manages supported source authorization, data retrieval, normalization, consent, and sync. It does not make every source identical or guarantee every organization and record. ## Key takeaways - Your app should own one stable connection contract while the interoperability platform owns supported source adapters. - Provider search, hosted authorization, normalized categories, consent state, and webhooks are as important as the FHIR request itself. - “Connect to all EHRs” should mean one integration across supported sources—not a promise of universal coverage. ## What “one connection to multiple EHRs” actually means A health app can connect to multiple EHRs through one platform integration when its own backend talks to a single API and sends users through a single connection entry point. The platform then routes each user to the appropriate hospital, clinic, payer, or EHR authorization endpoint. The simplification happens in your product boundary. Behind that boundary, the platform still maintains registrations, endpoints, OAuth details, FHIR capabilities, data mappings, retry behavior, and operational monitoring for each supported source. Good infrastructure hides unnecessary variance without hiding meaningful limitations. > One integration is real. Universal coverage is not. The accurate promise is one application contract across supported record sources. ## Direct EHR integrations versus one interoperability layer A direct strategy can work when you only need one EHR and have the time to own its application registration, launch flow, scopes, endpoint directory, token lifecycle, data quirks, and production support. The cost grows when the second, fifth, and fifteenth systems enter the roadmap. An interoperability layer moves repeated work into shared infrastructure. Your team integrates the product experience once, then enables supported sources through configuration and production approval rather than rebuilding the flow in customer-facing code. Direct integration compared with a unified EHR API | Concern | Direct integrations | Unified platform | | --- | --- | --- | | Provider search | Build and maintain source directories | Use one searchable source catalog | | Authorization | Implement each launch and token flow | Create one hosted connection session | | Data models | Branch on vendor-specific behavior | Read normalized categories with provenance | | Consent | Design receipts and enforcement | Use shared consent state and lifecycle events | | Operations | Monitor every adapter separately | Monitor one API and platform-reported source state | | Expansion | Add another integration project | Enable another supported source | ## The six steps behind a single EHR connection flow The exact endpoints vary by platform, but a well-designed patient-access architecture follows the same sequence. 1. **1. Create a connection session** Your backend declares the requested record categories, purpose, user return URL, and application context. API credentials remain server-side. 2. **2. Let the user find the record source** A hosted search experience maps the hospital, clinic, practice, portal, or payer the user recognizes to a supported technical endpoint. 3. **3. Authorize at the source** The user signs in on the EHR or hospital page. Their source password should not pass through your application or the interoperability platform. 4. **4. Retrieve and normalize available data** The platform reads the resources the source and scopes allow, preserves provenance, and maps supported data into a stable application contract. 5. **5. Record the sharing decision** Patient authorization at the source and consent to share with your specific app should be represented clearly, with purpose, categories, version, and lifecycle state. 6. **6. Sync changes and report lifecycle events** Webhooks or change cursors tell your backend when records change, access expires, consent is revoked, or deletion completes. ## What the platform should unify The most valuable abstraction is larger than a single FHIR endpoint. It should remove source-specific workflow code from your application while retaining enough metadata to troubleshoot and explain the record. - A stable server-side API and consistent error model. - One provider and organization search experience. - A hosted authorization handoff with clear return states. - Normalized record categories such as medications, conditions, labs, vitals, allergies, immunizations, and demographics. - Source attribution and original identifiers for every returned record. - Consent status, approved categories, revocation, expiry, and deletion events. - Sync status, retry behavior, change cursors, tombstones, and signed webhooks. - Separate synthetic sandbox and production environments. ## What one API cannot make identical FHIR improves consistency, but it does not erase local implementation choices or missing data. The same patient may receive a rich result from one source and a smaller result from another. Some organizations expose different resources, search parameters, history, notes, or update behavior. A trustworthy platform treats those differences as data and operational states—not as reasons to silently invent a complete record. Your product should show when a source is still syncing, when a category was unavailable, and where each fact came from. - Which healthcare organizations have live production endpoints. - Which FHIR resources and search parameters an organization supports. - What data exists in the patient’s chart and how far back it goes. - Whether a workflow allows read, write, bulk, scheduling, or only individual access. - The patient’s ability to authenticate and authorize at the selected source. ## How FinchNode approaches the one-connection model FinchNode focuses on the patient-directed, read-only use case. Your product creates a Connect session and sends the user into one hosted journey for provider search, source authorization, synchronization, and a purpose-bound sharing decision. Your backend then reads approved categories through a normalized API. This focus matters. FinchNode does not position the same connection as a replacement for provider-side bulk export, HL7 feeds, scheduling, write-back, or every enterprise interface. Those are valid interoperability needs, but they require different authorization, contracts, and infrastructure. [Explore FinchNode’s unified EHR integration API](https://finchnode.com/ehr-integration-api) ## Can I use a multi-EHR API for free in production? With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. Production access requires a FinchNode account, production credentials, a supported live source, and patient authorization and consent. Availability depends on the EHR, organization, application approvals, scopes, and records returned. A useful proof of concept should not begin with a sales call or real patient data. FinchNode’s $0 plan includes an unlimited synthetic sandbox, while the public demo API can be called without an account, API key, billing method, or vendor sandbox. The public demo returns one fixed fictional patient record as normalized categories and FHIR R4 resources. It proves the request and response shape for a prototype; it does not prove production connectivity to a particular EHR organization. Production access still depends on the supported source, organization, approvals, scopes, and patient authorization. [Explore free production EHR API access and the synthetic demo](https://finchnode.com/ehr-integration-api) ## A practical checklist for a “connect once” platform Before committing, run a proof of concept that starts before OAuth and ends after revocation. A short demo of one successful FHIR response is not enough to predict production work. Unified EHR API evaluation checklist | Test | A strong result | | --- | --- | | Connect three different source families | Your app code and user journey remain materially the same. | | Request a category one source lacks | The API reports availability without fabricating completeness. | | Revoke consent | Subsequent reads fail closed and a signed event reaches your backend. | | Receive an updated lab | The change can be detected without rebuilding the full record. | | Trace a normalized fact | Source, original ID, and retrieval context remain available. | | Move from sandbox to production | Credentials, data, and approvals are clearly isolated. | ## Frequently asked questions ### Is there a free EHR API for real patient data in production? Yes. With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. Production access requires a FinchNode account, production credentials, a supported live source, and patient authorization and consent. Availability depends on the EHR, organization, application approvals, scopes, and records returned. ### Is FinchNode only a synthetic demo or sandbox? No. With a FinchNode account, developers get free production-grade access to real, patient-authorized health records through one unified EHR API. The public demo API serves fixed fictional records for free without an account. Create a FinchNode account for free production-grade access to real, patient-authorized records within the included plan allowances. The demo itself cannot access real patient data. ### Can one API connect an app to all EHRs? One API can connect an app to many supported EHRs and organizations through a consistent contract. No responsible platform should promise every EHR, endpoint, workflow, and record. Production availability varies by source, organization, approval, scope, and data. ### Do I still need SMART on FHIR if I use an EHR aggregation API? The platform may handle source-specific SMART on FHIR flows on your behalf, but SMART and FHIR still power many underlying connections. Your app integrates with the platform’s session, consent, and data APIs instead of implementing every source flow directly. ### Will patient data look identical across EHRs? No. A platform can normalize supported categories and identifiers, but the available resources, coding, history, notes, and update behavior still depend on the source organization and patient record. ### What is the easiest way to add multiple EHR integrations? For a patient-facing, read-only use case, use a platform that combines provider search, hosted source authorization, patient consent, normalized data, sync, and webhooks. For provider write-back or population workflows, choose an enterprise or network integration model designed for those needs. --- # The easier way to get patient data from EHRs. The fastest path is not a shortcut around authorization. It is choosing the right access model, using one integration layer, and making consent, provenance, and updates part of the architecture from day one. [Production-grade access is free with an account.](https://finchnode.com/signup) The $0/month plan includes 100 connected patient-months, 100,000 production API calls per month, one production application, and an unlimited synthetic sandbox. - Author: [FinchNode Engineering](https://finchnode.com/authors/finchnode-engineering) - Published: 2026-08-24 - Last reviewed: 2026-08-24 - Canonical URL: https://finchnode.com/blog/easier-access-to-patient-data - Evidence boundary: Based on public product and developer documentation reviewed on the article update date. ## Bottom line For a patient-facing app, the easiest compliant approach is usually a patient-authorized EHR API with hosted provider search and source authorization. Treatment, payer, provider, research, and population workflows require different access models. ## Key takeaways - Define why the application is allowed to access data before choosing an API. - Patient-facing apps can reduce integration work with a hosted, patient-authorized connection flow. - Easy integration still requires clear consent, source attribution, incomplete-data handling, revocation, and security controls. ## The short answer If individual users need to bring their own medical records into a health app, the easiest path is usually a patient-authorized EHR aggregation API. The app creates one connection session, the user selects a hospital or practice, signs in at the source, approves access, and returns to the app. The backend receives normalized, consent-filtered data through one API. If the product is acting on behalf of a treating provider, health plan, or health system, patient-mediated access may be the wrong route. Network exchange, payer APIs, bulk data, HL7 interfaces, or contracted EHR integrations may be more appropriate. “Easy” begins with the correct authority and workflow. > The simplest technical integration is only useful when it matches the product’s permitted purpose and relationship to the patient. ## Why accessing EHR data is still hard even with FHIR FHIR provides a common language for healthcare data, but it is only one layer of the problem. Applications still need to discover endpoints, register clients, guide authorization, request the right scopes, handle organization-specific behavior, reconcile records, and operate the connection over time. The operational details are where many “simple API” projects expand. A user may know the name of a clinic but not its EHR. One organization may return detailed lab observations while another returns a document. Tokens expire. Patients revoke access. Duplicate records arrive from multiple sources. Production approval takes longer than sandbox development. - Endpoint and provider discovery. - Application registration and production approval. - SMART on FHIR and OAuth launch differences. - FHIR profiles, codes, extensions, and source-specific gaps. - Patient matching, duplicates, and record provenance. - Consent receipts, revocation, expiry, and deletion. - Sync status, retries, monitoring, and support. ## Four common ways to access patient data These routes can all produce clinical data, but they are not interchangeable. Choose based on who the product serves and what authorizes access. Common EHR data access models | Access route | Best for | User involvement | Typical tradeoff | | --- | --- | --- | --- | | Patient-authorized EHR API | Consumer and patient-facing apps | User finds and authorizes each source | Read-only and dependent on patient-access endpoints | | Treatment-based network query | Providers and care delivery organizations | Often no portal login during each query | Requires a qualifying relationship and permitted purpose | | Direct or enterprise EHR integration | Embedded provider workflows and write-back | Varies by workflow | More contracting, implementation, mapping, and maintenance | | Payer or population API | Health plans and population programs | Usually roster or member based | Different regulation, identity, and data-delivery model | ## For patient-facing apps: use one hosted authorization flow A patient-facing product should avoid asking users to send portal passwords, download files, or identify technical EHR vendors. Instead, give them a recognizable provider search, route them to the source’s own authorization page, and return them to a clear sharing decision. The backend should receive a stable subject identifier, consent status, approved categories, source details, and a way to retrieve changes. This keeps credentials out of the app, reduces vendor-specific UI, and gives the product a consistent way to explain what is connected. 1. **1. Ask for the minimum data** Name the categories required for the feature instead of requesting a vague “full chart.” 2. **2. Explain the purpose** Tell the user why the data is needed, how it will be used, and what happens if they decline. 3. **3. Authorize at the source** Keep hospital and portal credentials on the source-controlled page. 4. **4. Separate connection from sharing** Represent source authorization and app-specific consent clearly so the user can understand and control both. 5. **5. Show source and sync state** Make it obvious which systems are connected, when they last synced, and whether data is still arriving. ## What the easiest patient data API should include A thin proxy to a FHIR endpoint may save a few HTTP calls, but it leaves most product work untouched. The easiest useful platform owns the complete connection lifecycle. - Provider and organization search that uses names patients recognize. - Hosted authorization for supported record sources. - A normalized API for the record categories the product needs. - Source attribution and original identifiers for auditability. - Purpose-bound consent with approved categories and a versioned receipt. - Fail-closed enforcement after revocation or expiry. - Scheduled sync, change cursors, and signed webhooks. - Synthetic test data and a production readiness path. ## How FinchNode makes patient-authorized access easier FinchNode packages supported patient-access connections into one hosted flow and one server-side API. The user searches for a provider, authorizes on the source page, reviews the available categories, and decides what to share. The application reads only categories covered by active consent. The platform is intentionally scoped to read-only, patient-directed access in the United States. That makes it easier to evaluate: use FinchNode when users are connecting their own records; choose a provider, payer, network, or interface product when the application needs a different authority or workflow. [Start with the FinchNode EHR API overview](https://finchnode.com/ehr-integration-api) ## Do not trade implementation speed for data ambiguity An easy integration should make the hard cases visible. It should never imply that a returned bundle is the patient’s complete medical history. It should preserve sources, report unavailable categories, expose sync state, and let your product distinguish “no record,” “not returned,” “not authorized,” and “still processing.” Before launch, test a multi-source patient, an expired authorization, a revoked consent, an organization with partial FHIR support, a delayed sync, and duplicate observations. These are normal interoperability conditions, not rare exceptions. Production safeguards for patient data access | Safeguard | Product behavior | | --- | --- | | Minimum necessary access | Request only the categories the feature needs. | | Clear provenance | Show or retain the organization and source for each record. | | Honest completeness | Never translate missing data into a clinical conclusion. | | Revocation handling | Stop future reads and process lifecycle events promptly. | | Server-side secrets | Keep API keys out of browsers and mobile clients. | | Environment isolation | Prevent synthetic and production records from mixing. | ## A simple decision tree If your user is authorizing access to their own record and the product only needs to read data, start with a patient-authorized aggregation platform such as FinchNode. If a treating organization is querying a network, shortlist platforms built for treatment-based exchange. If you need write-back, scheduling, ADT, or embedded provider workflows, evaluate enterprise EHR integration infrastructure. If you need populations or payer compliance, use the relevant payer or bulk-data model. That one decision prevents the most expensive interoperability mistake: building the right API for the wrong authority. ## Frequently asked questions ### What is the easiest way to access patient data from EHRs? For a patient-facing read-only app, use a patient-authorized EHR API that includes provider search, hosted source authorization, consent, normalized data, sync, and webhooks. Provider, payer, population, and write-back workflows need different access models. ### Can patients connect their EHR without sharing their password with my app? Yes. With SMART on FHIR and similar source authorization flows, patients sign in on the hospital or EHR page. Their portal credentials should not pass through your application. ### Does FHIR provide a patient’s complete medical record? Not automatically. FHIR describes data formats and API behavior, but returned data depends on the source, organization, scopes, patient authorization, available history, and supported resources. Products should preserve provenance and avoid promising completeness. ### Can I use one patient data API for Epic, Oracle Health, and other EHRs? Yes, when those sources and organizations are supported by the platform. Your app can use one connection flow and backend contract while the platform handles supported source-specific behavior. Production availability and data still vary by organization.