Patient-authorized EHR integration
Demo API
Call fictional patient records with no key and no account.
The demo API serves fictional patients from two synthetic health systems. Use it to prototype, write tests, or let a coding agent explore. Demo sessions and request bodies aren't kept; the service records usage metadata such as client type, scenario, and a hashed caller ID.
Make your first call
curl "https://api.finchnode.com/demo/v1/users/patient-demo-001/records"
You get a synthetic record in FinchNode's normalized format. It has the same structure as the sandbox and production API, with demo IDs and simulated consent and sync values. patient-demo-001 is the default baseline-adult scenario. An unknown subject returns 404 patient_not_found.
What is in the default record?
Omit categories to get all ten categories in one request. The default patient includes:
| Data | Examples |
|---|---|
| Demographics | Fictional name, date of birth, address, phone, and email |
| Medications | Two current prescriptions, one completed regimen, an administration, and two dispenses; doses, schedules, prescribers, reasons, and supply quantities |
| Labs and vitals | 18 lab results and 16 vital signs across three visits, with units, reference ranges, interpretations, and a diagnostic report |
| Conditions, allergies, vaccines | Two conditions, one allergy with a reaction, and two vaccine records with manufacturer and lot details |
| Visits and care team | An encounter, a booked appointment, and a care team with participants |
| Documents and claims | A readable fictional visit note, a document reference, insurance coverage, and a claim with billed and paid amounts |
Read the note directly from record.data.clinicalNotes[0].value. Every applicable normalized clinical field has a sample value. Ongoing prescriptions have endDate: null; demographic records have no clinical codes. Consent and sync metadata remain explicitly simulated. Other scenarios still include missing values and empty records for testing those states.
To request less data, add ?categories=medications,labs. For the complete FHIR R4 Bundle, fetch https://api.finchnode.com/demo/v1/fhir/Bundle/finchnode-visualizer-synthetic-bundle. The normalized response, raw Bundle, visualizer, and TEFCA simulation use the same fictional patient.
Call it from the browser
The demo accepts cross-origin requests from any site, so a frontend can call it directly with no backend. This works only because the demo needs no key; never put a sandbox or production key in a browser.
const response = await fetch('https://api.finchnode.com/demo/v1/users/patient-demo-001/records');
if (!response.ok) throw new Error(`Demo API returned ${response.status}`);
const record = await response.json();
console.log(record.data.medications.map((medication) => medication.name));
Beyond the headers browsers always allow, send only Accept and Content-Type; a custom header such as X-Trace-Id fails the browser's preflight check. Your code can read Retry-After, the RateLimit-* headers, and X-Request-Id from responses, including errors.
Pick a scenario
GET /scenarios lists the named scenarios. Record scenarios cover different patients, such as a senior on many medications or a sparse record. Behavior scenarios return a scripted error or a partial result, so you can test your error handling.
curl "https://api.finchnode.com/demo/v1/scenarios"
Record and behavior scenarios name a subject; pass it to /users/{subject}/records. That endpoint takes only categories: the demo has no pagination or change feed.
Endpoints
| Endpoint | Returns |
|---|---|
GET /users/{subject}/records |
A normalized record, shaped like the authenticated API |
GET /fhir/{resourceType} |
FHIR R4 resources of one type for baseline-adult; add ?patient={subject} for another scenario |
GET /fhir/metadata |
The sample FHIR capability statement |
POST /connect/sessions |
A Connect session that finishes in the response: complete, or cancelled or failed for the session scenarios |
GET /patients/{patientId}/records |
The older category-grouped format, with 8 categories |
The full list is in the demo API reference. The OpenAPI document is at https://api.finchnode.com/demo/v1/openapi.json.
Use it from an AI agent
The demo also runs as an MCP server at https://api.finchnode.com/demo/mcp, with no key. Start with the list_demo_scenarios tool. See MCP server for client setup.
Limits
By default each network address gets 120 requests a minute, with a separate budget for behavior scenarios. A 429 means wait and retry.
Moving to the sandbox
The demo takes shortcuts the sandbox and production API don't. When you switch to a ck_test_ key, change these:
| Demo | Sandbox |
|---|---|
external_user_id |
externalId |
connect_url |
url |
patient_id |
subject |
created_at, expires_at |
createdAt, expiresAt |
status: "complete" |
status: "completed" |
status: "cancelled" |
status: "canceled" |
scenario in the session request |
POST /connect/sessions/{sessionId}/simulate |
| Completes in the response | Completes later; poll simulation.state or use webhooks |
In production there is no simulate: the patient completes the session in their browser, and you learn the outcome from webhooks or the session. See After the patient connects.
The two session scenarios, connect-cancelled and connect-failed, exist only in the demo.