EMR vendors
One integration across all your practices: each practice approves you in Norvya and chooses what you may use, then you embed Norvya's clinical intelligence by API, as native cards, or as documents filed in the chart.
- Credential model
- One vendor credential; a token per approving practice. EMR vendor tokens
- Before production
- Each practice's approval in Norvya and its BAA; SMART launch and a registered CDS Hooks service also need each EHR vendor's registration.
- Sandbox
- A vendor sandbox.
How it works
A practice approves you
Each practice's administrator approves your integration in Norvya and chooses the scopes you may use there. One credential serves every practice that approves you. Call /v1/oauth/token without practice for a vendor token, then list your practices.
- POST
/v1/oauth/tokenExchange client credentials for a bearer token - GET
/v1/practicesEMR vendors: the practices that approved your integration
Get a token per practice
Request a token with practice=$PRACTICE_REF. A practice that withdraws its approval stops your tokens for it at once.
- POST
/v1/oauth/tokenExchange client credentials for a bearer token
Find the patient
Find a patient's member_ref from your own MRN and date of birth.
- POST
/v1/patients/matchFind a patient's member_ref from your MRN and date of birth
Embed Norvya in the chart
Fetch the same CDS Hooks cards Norvya's hook service returns and render them natively, or get the pre-visit brief as a FHIR R4 DocumentReference to file in the chart.
- GET
/v1/patients/{member_ref}/cardsCDS Hooks-format cards for one patient, to render in your own UI - GET
/v1/patients/{member_ref}/brief/documentThe pre-visit brief as a FHIR R4 DocumentReference, ready to file in your chart - GET
/v1/patients/{member_ref}/briefClinician pre-visit brief for one patient
Work the panel
The ranked panel worklist with the evidence and guideline behind each item, and triage write-back.
- GET
/v1/panel/worklistYour practice's ranked worklist: who needs attention and why - POST
/v1/panel/worklist/items/{item_ref}/triageTriage one worklist finding (addressed, snoozed, dismissed or reopened)
Listen for events
Signed webhooks; payloads carry no health data, only a reference to fetch with your token.
- POST
/v1/webhooksRegister a webhook endpoint (secret shown once)
Families you'll use
| Family | Fit | Status |
|---|---|---|
| Clinical intelligence | Core | Built — gated |
| Data in | Core | Built — gated |
| EHR embedding: cards and chart documents | Core | Built — gated |
| Events (webhooks) | Core | Built — gated |
| Specialty care | Core | Built — gated |
| EHR embedding: SMART launch and CDS Hooks | Useful | Built — gated |
| Enrolment & messaging | Useful | Built — gated |
| Member data in: observations and workouts | Useful | Built — gated |
| Practice operations & reports | Useful | Built — gated |
Scopes to request
A practice can grant you fewer. Ask only for what your product uses.
| Scope | Allows |
|---|---|
members.read | List the organisation's linked members as opaque member references. |
vendor.practices.read | EMR vendors: list the practices that have approved your integration (a vendor-level token, requested without a practice; no patient data). |
clinical.patient.match | Find the member_ref of one of your practice's patients from your own identifier (MRN) plus date of birth; exactly one match or 404 (medical practices only; tightly rate limited, audited). |
clinical.brief.read | Read the clinician pre-visit brief for a patient (medical practices only; per-section consent). |
clinical.patient.read | Read a patient's care gaps and between-visit home-data signals (medical practices only; consent and data basis respected). |
clinical.panel.read | Read the practice's ranked panel worklist and start worklist runs (medical practices only). |
clinical.panel.write | Triage your practice's worklist findings from your system (addressed, snoozed until a date, dismissed with a reason, or reopened) with the same rules as Norvya's own worklist screen (medical practices only). |
clinical.loops.write | Close the loop on results and referrals from your system: record that a named clinician acknowledged a result, that the patient was told, the action taken, and move a tracked referral through scheduled, seen, report received and closed (medical practices only). |
instruments.request | Ask a patient to complete a validated questionnaire from Norvya's instrument library; Norvya sends its own generic notification (treating practices only). |
instruments.read | Read questionnaire scores (total, severity band, subscales) with the instrument version and completion time, never item-level answers; mental-health instruments only when the patient shares mental health with you (treating practices only). |
observations.write | Write measurements to a member's own record: vitals, lab results and body composition (practices with a BAA on file), or body composition and the vitals a gym measures (gyms; never labs). Idempotent per item by your external_id; units converted, implausible values refused; DELETE retracts only your own item. |
panel.import.write | Stage, review, commit and discard practice panel imports (FHIR Bulk Data, or a spreadsheet with a saved mapping profile; medical practices with a BAA on file only). |
webhooks.manage | Register HTTPS webhook endpoints (payloads carry no PHI). Each event also needs its own scope: worklist / attention events clinical.panel.read, import events panel.import.write, population.export_completed population.export (medical practices only), member.at_risk fitness.roster.read, public_health.iis_ack_received public_health.immunizations.read, public_health.case_report_response public_health.case_reports.read. claims.import_completed needs claims.import.write (medical practices only). member.account_claimed needs members.claim_invite (medical practices only). hospital_at_home.escalation needs hospital_at_home.read (hospitals only). hospice.idg_review_due needs hospice.read (hospice agencies only). pharmacy.refill_due and pharmacy.discharge_episode_opened need pharmacy.patients.read; care_site.change_of_condition, care_site.incident_recorded and care_site.mar_exception need care_sites.read (pharmacies and care-facility operators, their own sites). travel.journey_updated and travel.leg_status_changed need travel.journeys.read, travel.nursing_visit_recorded travel.nursing.read, travel.invoice_issued travel.billing.read (medical-travel desks only). travel.inquiry_updated needs travel.inquiries.read, travel.journey_message_posted travel.messages.read (medical-travel desks only). instrument.batch_dispatched needs instruments.request (medical practices only). roster.enrolment_summary needs members.roster.read (medical practices only). older_adults.falls_tier_raised needs older_adults.read (medical practices only). employer.challenge_completed needs employer.challenges.read and occupational.exam_due occupational.read (employers only); medspa.adverse_event_reported needs medspa.aftercare.read (treating practices only). rehab.goal_met needs rehab.read; nutrition.caseload_flagged needs nutrition.read (medical practices only). cocm.review_due needs behavioral.read (medical practices only). derm.lesion_recheck_due and derm.patch_test_read_recorded need derm.read (medical practices only). |
clinical.specialty.read | Read a patient's specialty hub results (cardio, nephro, endo, neuro, pulmo, rheum, GI and questionnaires) under their sharing switches, and run the stateless spirometry, lung-cancer screening and GI alarm checks (treating practices only). |
clinical.ratings.write | Record a clinician-rated or clinician-timed measure (for example FOIS, Nine-Hole Peg Test, AIMS) that a named clinician of your practice assigned; scored by Norvya (treating practices only). |
documents.read | List and download the documents Norvya already produces about a patient (care plans, survivorship plans, reviews, summaries, estimates) as PDF, in the patient's language where the document supports it; each document kind keeps its own consent gate (treating practices, including medical-travel desks, and pharmacies). |
clinical.record.read | Read one patient's record as a FHIR R4 Bundle (the same builders and the same consent scope as the population export: the patient's sharing choices, your practice's own records, 42 CFR Part 2 records only under a covering consent); size-capped, with the population export for large records (treating practices with a BAA on file, or a sandbox). |
Protocol endpoints outside /v1
Called by the EHR itself rather than with a partner token.
EHR embedding: SMART launch and CDS Hooks Built — gated
Gate: Registration with each EHR vendor's developer programme, then their review.
- GET
/ehr/launchSMART on FHIR EHR launch (the EHR opens Norvya with iss and launch) - GET
/ehr/callbackSMART authorization callback - GET
/ehr/.well-known/jwks.jsonNorvya's public keys for SMART backend authentication - GET
/cds-servicesCDS Hooks discovery - POST
/cds-services/norvya-patient-viewCDS Hooks patient-view: the card for the open chart - POST
/cds-services/norvya-patient-view/feedbackCDS Hooks card feedback
Not callable yet
- Enrolment & messaging Built — gated
- Practice operations & reports Built — gated Gate: Claim invitations need a BAA on file (a sandbox simulates).
Before production
Sandbox
Build and test against synthetic members before you touch real data. A vendor sandbox. What a sandbox holds, its credentials, limits, resets and expiry are in the Sandbox guide. To request one, write to [email protected] with your organisation and market.
Every endpoint for this market
The families this solution uses, filtered to the scopes it requests. Each link opens the endpoint on its family page.
Platform Built — gated4
- GET
/v1/members - POST
/v1/oauth/token - GET
/v1/practices - GET
/v1/usage
Events (webhooks) Built — gated5
- GET
/v1/webhooks - POST
/v1/webhooks - DELETE
/v1/webhooks/{webhook_id} - GET
/v1/webhooks/{webhook_id}/deliveries - POST
/v1/webhooks/{webhook_id}/enable
Records & documents Built — gated4
- GET
/v1/documents/{document_ref} - GET
/v1/documents/{document_ref}/content - GET
/v1/patients/{member_ref}/documents - GET
/v1/patients/{member_ref}/record
Clinical intelligence Built — gated23
- GET
/v1/instrument-requests/batch - POST
/v1/instrument-requests/batch - GET
/v1/instrument-requests/batch/{batch_ref} - GET
/v1/instruments - POST
/v1/members/{member_ref}/instrument-requests - POST
/v1/members/{member_ref}/instrument-requests/{response_ref}/simulate-completion - GET
/v1/members/{member_ref}/instrument-responses - GET
/v1/panel/clinicians - GET
/v1/panel/worklist - POST
/v1/panel/worklist/items/{item_ref}/triage - POST
/v1/panel/worklist/runs - GET
/v1/panel/worklist/runs/{run_id} - GET
/v1/patients/{member_ref}/between-visit - GET
/v1/patients/{member_ref}/brief - GET
/v1/patients/{member_ref}/care-gaps - POST
/v1/patients/{member_ref}/clinician-ratings - GET
/v1/patients/{member_ref}/referrals - POST
/v1/patients/{member_ref}/referrals/{referral_ref}/status - GET
/v1/patients/{member_ref}/results - POST
/v1/patients/{member_ref}/results/{result_ref}/acknowledge - POST
/v1/patients/{member_ref}/results/{result_ref}/action - POST
/v1/patients/{member_ref}/results/{result_ref}/close - POST
/v1/patients/{member_ref}/results/{result_ref}/informed
Specialty care Built — gated5
- POST
/v1/clinical/checks/gi-alarm - POST
/v1/clinical/checks/lung-cancer-screening - POST
/v1/clinical/checks/spirometry - GET
/v1/patients/{member_ref}/specialty-checks - GET
/v1/patients/{member_ref}/specialty/{hub}
Data in Built — gated4
- POST
/v1/panel/imports - GET
/v1/panel/imports/{import_id} - POST
/v1/panel/imports/{import_id}/commit - POST
/v1/panel/imports/{import_id}/discard