Integration brief
Everything an integrator (human or agent) needs to hold in context to build
against the Ava EMR FHIR API. Values in {braces} are per-registration; find
yours in the portal or the quickstart.
What this API is
- FHIR R4 (4.0.1), JSON only. Requests and responses use
application/fhir+json; errors are FHIROperationOutcomeresources. - SMART App Launch 2.2, EHR launch only. Public clients, authorization code + PKCE S256, OpenID Connect. There are no client secrets and no refresh tokens; standalone launch and Backend Services registration are not available through this portal today.
- Canadian profiles. Most resources advertise CA Core+ profiles
(
ca.infoway.io.core); responses may include profile extensions — ignore elements you don't recognize.
URLs
| Thing | Shape |
|---|---|
| FHIR base | {issuer}/fhir/r4/{partition_id} — every clinic partition has its own base URL |
| CapabilityStatement | {fhir_base_url}/metadata |
| SMART discovery | {issuer}/.well-known/smart-configuration |
| Sandbox issuer | https://sandbox.avaemr.ca (your portal shows your real one) |
The two discovery documents are authoritative: anything advertised there is implemented; anything absent must not be relied on.
Authorization in five lines
- EMR opens
{launch_uri}?iss=…&launch=…. - Fetch
{iss}/.well-known/smart-configuration. - Redirect to
authorization_endpointwithresponse_type=code,client_id,redirect_uri,scope,state,aud={iss},launch,code_challenge(+=S256). - Exchange the returned
code+code_verifierattoken_endpoint(no secret). - Call FHIR with
Authorization: Bearer …; the token response'spatientfield is the launched patient's id.
Full walkthrough: App launch & PKCE.
Scope grammar
<context>/<ResourceType>.<interactions> e.g. patient/Patient.rs
- Contexts:
patient/(confined to the launched patient) anduser/(whatever the signed-in clinician can see). - Interactions: SMART v2 granular letters —
ccreate,rread,ssearch (so.rs= read + search,.c= create-only). - Protocol scopes:
launch(always required),openid,fhirUser(requiresopenid),launch/servicerequest. - Scopes are selected per app in a versioned permission schema, each with
a written rationale shown to users at consent. Requesting a scope outside
your deployed schema fails with
invalid_scope.
Sharp edges (read before coding)
- The write surface is narrow and create-only:
DocumentReferenceandMediasupportcreateand nothing else. No resource supports update, patch, or delete. - Observation has no launch scopes —
patient/Observation.*anduser/Observation.*do not exist; do not request them. - ServiceRequest is read-only without search (
user/ServiceRequest.r). - Sandbox HTTP URIs must use a loopback IP literal —
127.0.0.1works,localhostis rejected. Deployed apps use HTTPS. - EHR launch only — your app cannot start a session on its own; it is launched from a patient chart in the EMR.
- The granted
scopein the token response may be narrower than requested.
Search & pagination
- Search results are
searchsetBundles. - Universal parameters:
_id,_lastUpdated,_count, and opaque_page_tokencursor pagination — follow the Bundle'snextlink rather than constructing page URLs. - Per-resource search parameters are advertised in the CapabilityStatement.
Errors
Non-2xx FHIR responses carry an OperationOutcome with machine-readable
issue[].code and human diagnostics. OAuth endpoints return standard OAuth
error codes (invalid_scope, invalid_grant, …).
Sandbox facts
- Synthetic dataset
ontario_primary_care_v1: a generated Ontario primary-care clinic — realistic, deterministic, and containing no real patient data. - Your sandbox is private to your organization and comes with its own EMR login for launching apps from charts.
- Every API change reaches the sandbox at least one release cycle before production.
Versioning promises
- The FHIR major version is in the URL path (
/fhir/r4/…); meanings of existing paths never change in place. - Additions (resources, elements, scopes) ship continuously — write clients defensively.
- Breaking changes get
Deprecation/Sunsetheaders and a minimum 6-month window (12 months when response shapes change), announced to registered app owners.