Log in Request access

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 FHIR OperationOutcome resources.
  • 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

  1. EMR opens {launch_uri}?iss=…&launch=….
  2. Fetch {iss}/.well-known/smart-configuration.
  3. Redirect to authorization_endpoint with response_type=code, client_id, redirect_uri, scope, state, aud={iss}, launch, code_challenge (+=S256).
  4. Exchange the returned code + code_verifier at token_endpoint (no secret).
  5. Call FHIR with Authorization: Bearer …; the token response's patient field 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) and user/ (whatever the signed-in clinician can see).
  • Interactions: SMART v2 granular letters — c create, r read, s search (so .rs = read + search, .c = create-only).
  • Protocol scopes: launch (always required), openid, fhirUser (requires openid), 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: DocumentReference and Media support create and nothing else. No resource supports update, patch, or delete.
  • Observation has no launch scopespatient/Observation.* and user/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 literal127.0.0.1 works, localhost is 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 scope in the token response may be narrower than requested.

Search & pagination

  • Search results are searchset Bundles.
  • Universal parameters: _id, _lastUpdated, _count, and opaque _page_token cursor pagination — follow the Bundle's next link 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/Sunset headers and a minimum 6-month window (12 months when response shapes change), announced to registered app owners.