Skip to content

Nexus EMR Server Capability statement

Canonical../CapabilityStatement/nexus-emr-server
Statusdraft (experimental) · 1.26.0
Kindrequirements -- what a conformant endpoint must offer -- not a description of any one deployment
FHIR version4.0.1
Formatsapplication/fhir+json · application/fhir+xml
SourceFSH · JSON

The resource types, interactions and profiles a conformant Nexus EMR FHIR endpoint offers. The resource list is the set this IG marks smart-exposed; the interactions on each are the ones that extension declares. Types this IG profiles but does not expose are deliberately absent.

New to this artifact? How to read a CapabilityStatement explains what an interaction and a declared search parameter do -- and do not -- promise.

REST interface -- server

Every interaction below is authorized. Authorization is by SMART-on-FHIR scope, and the scope vocabulary is generated from this IG: a scope naming a resource type this statement does not list is not granted, and a scope asking for an interaction a type does not declare is dropped rather than honoured. Patient-compartment scoping is enforced separately, from the launch context, so a patient/ scope does not by itself widen to the population.

Security

Service: SMART-on-FHIR.

CORS is enabled.

SMART on FHIR. Clinical scopes name a resource type from the list below; * expands over exactly that list and no further.

Interactions on the endpoint itself

  • transaction -- All-or-nothing multi-resource write at the server root. Entries are applied as one unit and the bundle fails together, so a single nonconformant entry loses every other entry with it; read the returned OperationOutcome rather than retrying. Internal references between entries are resolved within the bundle.
  • batch -- Independent multi-resource write at the server root. Unlike transaction, each entry succeeds or fails on its own and the response carries one status per entry, so a caller MUST read every entry's status rather than the overall response code.

Operations

  • $billing-launch -- Billing launch. Open a signed-in ClinicAid session for a clinic, optionally prefilled from one appointment. Requires the billing-launch permission. Affects state: it spends a clinic credential and mints a single-use address.
  • $eligibility-check -- Eligibility check. Ask a patient's province, through the clinic's own payer account, whether that patient may be billed. Affects state: it spends a payer account and is not safe to repeat blindly, because one of its two 503 endings means the check may already have run.
  • $indexing-status -- Indexing status. Report which search parameters are defined and indexed on this tenant's store. ADMINISTRATIVE: the right is granted to an administrative role, not to an integration. This is how to find out whether a given tenant's store actually holds the non-base search parameters declared above. Reads only. Despite that, GET is refused; use POST.
  • $index-search-parameter -- Index search parameter. Start a background job that makes one search parameter usable for search on this tenant's store. ADMINISTRATIVE and heavy: for a custom parameter it WRITES the definition to the store before indexing begins, and a true reply is an acceptance rather than an outcome. Not a lever an integration should pull.

Resource types (37)

Interactions and search parameters are what each entry DECLARES. A type whose cell reads none declared declares none in this statement, which is not the same as the endpoint having none -- see how to read this. A linked type has further notes below it.

Resource type Profile Interactions Search parameters
AllergyIntolerance AllergyIntolerance read vread history-instance search-type create update delete none declared
Appointment Appointment read vread history-instance search-type create update delete none declared
AppointmentResponse Appointment Response read vread history-instance search-type create update none declared
Basic App State read vread history-instance search-type create update delete none declared
CareTeam CareTeam read vread history-instance search-type create update delete 2 declared
ClinicalImpression ClinicalImpression read vread history-instance search-type create update delete none declared
Composition Composition read vread history-instance search-type create update delete none declared
Condition Condition read vread history-instance search-type create update delete none declared
Consent App Consent
Item Consent
Privacy Directive
read vread history-instance search-type none declared
DetectedIssue DetectedIssue read vread history-instance search-type create update none declared
Device App Device
Device
read vread history-instance search-type none declared
DiagnosticReport DiagnosticReport read vread history-instance search-type create update delete none declared
DocumentReference DocumentReference read vread history-instance search-type create update delete 2 declared
Encounter Encounter read vread history-instance search-type create update delete none declared
Flag Flag read vread history-instance search-type create update delete none declared
Immunization Immunization read vread history-instance search-type create update delete none declared
Invoice Invoice read vread history-instance search-type create update delete none declared
List Template
Attachment Packet
read vread history-instance search-type create update 1 declared
Location Location read vread history-instance search-type none declared
MedicationDispense Medication Dispense read vread history-instance search-type create update delete none declared
MedicationRequest MedicationRequest read vread history-instance search-type create update delete none declared
MessageHeader MessageHeader read vread history-instance search-type none declared
Observation Observation read vread history-instance search-type create update delete none declared
Organization Organization read vread history-instance search-type none declared
Patient Patient read vread history-instance search-type create update none declared
Practitioner Practitioner read vread history-instance search-type none declared
PractitionerRole PractitionerRole read vread history-instance search-type none declared
Procedure Procedure read vread history-instance search-type create update delete none declared
Provenance Provenance read vread history-instance search-type create update none declared
Questionnaire Questionnaire read vread history-instance search-type create update none declared
QuestionnaireResponse QuestionnaireResponse read vread history-instance search-type none declared
RelatedPerson RelatedPerson read vread history-instance search-type create update delete none declared
Schedule Schedule read vread history-instance search-type none declared
ServiceRequest Referral
ServiceRequest
read vread history-instance search-type create update delete none declared
Slot Slot read vread history-instance search-type 1 declared
Specimen Specimen read vread history-instance search-type none declared
Task Task
Correction Task
read vread history-instance search-type create update delete 16 declared

AppointmentResponse

Appointment Response · read vread history-instance search-type create update

No delete: an answer to a booking is superseded by a newer answer rather than removed, and a consumer resolves the latest answer per appointment. Destroying one moves a booking's displayed confirmation state backwards with nothing recording that it moved. Create and update are both granted because the producer is an integrating system outside the EMR, reaching this type through the API rather than from inside it.

CareTeam

CareTeam · read vread history-instance search-type create update delete

Two parameters, and they are the two the searching surfaces use: one patient's own team, and the active standing teams work is pooled to. NEITHER IS MEASURED. Nothing in this estate exercises a CareTeam search against a store and asserts that the filter ran, which is a weaker footing than the Task entry further down, and it is stated rather than smoothed over. participant is deliberately absent: who is on a team is read off the bundle the search already returned rather than asked for again. So is subject:missing, which would be the direct way to separate a practice-wide pool (no subject) from one patient's team (a subject). That separation is done on the client instead, because a modifier the store ignores answers with every team, looking exactly like a match -- see the Task entry for the measurement that established that failure mode here.

Search parameters (2)

  • patient -- reference, http://hl7.org/fhir/SearchParameter/clinical-patient. A patient's own care team: CareTeam?patient={id}. NOT MEASURED against any store. The one surface issuing it re-filters the returned bundle by subject on the client, so a store that ignored the parameter would still look correct there -- and would look correct nowhere else.
  • status -- token, http://hl7.org/fhir/SearchParameter/CareTeam-status. The standing-team query: CareTeam?status=active lists the teams work may be pooled to. NOT MEASURED against any store.

App Consent, Item Consent, Privacy Directive · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Consent, so no scope grants them. THREE FAMILIES SHARE THIS TYPE and a scope cannot separate them -- an application granted consent:read reads app consents, item consents and privacy directives alike, because a SMART scope names a resource type rather than a profile. Read Consent.category to tell them apart before interpreting status, which means opposite things across families. Write is granted by no scope: an application able to write a Consent could post a permitting override for itself.

DetectedIssue

DetectedIssue · read vread history-instance search-type create update

No delete: a DetectedIssue is the record of a prescribing-safety finding and, where mitigation is present, of a prescriber deciding to proceed in spite of it. That override is a medico-legal trail, so no scope grants its destruction.

Device

App Device, Device · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Device, so no scope grants them.

DocumentReference

DocumentReference · read vread history-instance search-type create update delete

Search parameters (2)

  • identifier -- token, http://hl7.org/fhir/SearchParameter/clinical-identifier. The form discovery query: DocumentReference?patient={id}&identifier=../NamingSystem/nexus-form| finds the patient's forms and nothing else (see the nexus-form NamingSystem). MEASURED against the NativeFHIR store (2026-08-21): the parameter is served and genuinely filtered -- the system-only token returns exactly the marked documents.
  • description -- string, http://hl7.org/fhir/SearchParameter/DocumentReference-description. The template search query: DocumentReference?identifier=../NamingSystem/nexus-form-template|&description:contains={text} finds the templates whose title carries the text anywhere, case-insensitively -- the standard R4 string search with its :contains modifier (unmodified, a string search matches from the start of the value). MEASURED against the NativeFHIR store (2026-08-25): :contains matches the text anywhere in the title, case-insensitively (SIB and orm both find WSIB Form 8), and the unmodified search matches from the start of the value only (SIB finds nothing). A store that ignored the modifier would answer the start-of-value match, so a caller seeing prefix-only results should suspect that before suspecting the catalogue.

List

Template, Attachment Packet · read vread history-instance search-type create update

Templates (the nexus-template profile). No delete: destroying a template is an administrative act, not an app workflow step, and no scope grants it. Matches the charting permission grant exactly (list:read + list:write).

Search parameters (1)

  • identifier -- token, http://hl7.org/fhir/SearchParameter/clinical-identifier. The template discovery query: List?identifier=../NamingSystem/nexus-template| finds every template and nothing else. MEASURED against the NativeFHIR store (2026-08-19): the parameter is served and genuinely filtered -- a bogus identifier returns zero, not an unfiltered list.

Location

Location · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Location, so no scope grants them.

MessageHeader

MessageHeader · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on MessageHeader, so no scope grants them. A MessageHeader is the ROUTING ENVELOPE of a message bundle, not chart content: it is read off the bundle to dispatch it and it carries no patient data of its own. Expect to meet it inside a bundle rather than to retrieve one by id -- a deployment need not file it as an independently addressable resource at all.

Organization

Organization · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Organization, so no scope grants them.

Patient

Patient · read vread history-instance search-type create update

No delete: Patient may be created and amended, but destroying the compartment root is data loss rather than a workflow step, and no scope grants it.

Practitioner

Practitioner · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Practitioner, so no scope grants them.

PractitionerRole

PractitionerRole · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on PractitionerRole, so no scope grants them.

Provenance

Provenance · read vread history-instance search-type create update

No delete, and the asymmetry is the point: a producer records its own attribution alongside the write it describes, but an audit trail a client can destroy is not an audit trail, so no scope grants a delete on any Provenance. Write it for what you produced; do not rewrite someone else's. A Provenance CONTAINED in another resource -- an AI-suggestion Task, for instance -- is not reached through this entry at all: it travels under the grant of the resource containing it. Read the ABSENCE of Provenance as inconclusive rather than as an assertion that no agent was involved; coverage is not universal.

QuestionnaireResponse

QuestionnaireResponse · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on QuestionnaireResponse, so no scope grants them.

Schedule

Schedule · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Schedule, so no scope grants them.

Slot

Slot · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Slot, so no scope grants them.

Search parameters (1)

  • end -- date, ../SearchParameter/slot-end. When a slot finishes. NOT A BASE R4 PARAMETER: R4 defines start on Slot and no counterpart, so this is this estate's own definition, published as an artifact. A store that was never given that definition IGNORES the parameter rather than refusing it, and answers with everything -- so a test asserting 200 proves nothing here. What separates an applied parameter from a dropped one is a bound past every slot's end returning ZERO rather than the whole set.

Specimen

Specimen · read vread history-instance search-type

Read-only: the IG declares no create, update or delete on Specimen, so no scope grants them. A Specimen arrives with the lab result it produced and is reached from DiagnosticReport.specimen; nothing in this estate authors one on its own.

Task

Task, Correction Task · read vread history-instance search-type create update delete

Sixteen parameters and five includes: the set the searching surfaces reach for, which is a narrower claim than the set R4 defines on Task. FIVE ARE MEASURED and eleven are not, and every entry says which it is. A measured entry here rests on a STANDING conformance request against a seeded NativeFHIR store rather than on a one-off run, and each such request asserts what the filter must EXCLUDE rather than merely that a bundle came back. That shape is forced by how the store fails: an unsupported parameter is not an error to it -- it drops the parameter, answers with everything, and explains itself in an OperationOutcome entry inside an otherwise ordinary searchset. A test asserting 200 proves nothing at all here.

:missing IS NOT DECLARED, AND TWO MEASUREMENTS DISAGREE ABOUT WHY. On 2026-08-25, against a store holding one patientless task among nine, patient:missing returned the unfiltered set for true and for false alike, indistinguishably from a parameter that does not exist. On 2026-09-08 the opposite was measured directly against the store image this estate runs: with one owned and one unowned Task present, owner:missing=true returned only the unowned one, owner:missing=false only the owned one, and an unfiltered control returned both. The store's own source agrees with the second result -- the modifier is parsed explicitly and compiled to a not-exists condition, unconditionally. Each hop between the client and the store was also checked in isolation and preserves the modifier. What has NOT been measured is the whole chain at once, which is the only thing that would settle it, so this surface still declares nothing. Until it does, a client wanting the tasks filed against nobody should narrow the result itself rather than trust the modifier -- the cost of being wrong is that every task in the tenant reads as a match, and that failure is silent. :not is likewise undeclared: nothing isolates it, and its semantics differ between servers, so an OR-list of the values wanted is the portable spelling of the same query.

CHAINING AND REVERSE CHAINING ARE NOT DECLARED. patient.name and patient.identifier narrow a worklist by the patient a task is filed against, and _has:Communication:based-on:recipient answers addressed-to-me. All three go over this surface today and none has been measured. They are named here so that an implementer meeting one knows it is unverified, which is a different thing from knowing it works.

RESULT PARAMETERS. _count, _total=accurate and _sort accompany every search these surfaces issue, and -authored-on is the sort the worklists use. _include:iterate takes a second hop off what the first one brought back -- the Practitioner behind an included PractitionerRole, the patient behind an included ServiceRequest. That hop leaves this resource type, so it is not listed in searchInclude above and its support is a question for the type it lands on. Task:location is an include over a parameter this guide does not define -- see that entry.

Search parameters (16)

  • _id -- token, http://hl7.org/fhir/SearchParameter/Resource-id. Fetch a known set in one request: Task?_id={id},{id}. This is load-bearing rather than a convenience -- a worklist whose question this surface cannot express as a filter computes the ids some other way and reads them back here. NOT MEASURED.
  • _lastUpdated -- date, http://hl7.org/fhir/SearchParameter/Resource-lastUpdated. The delta re-read: a chart already holding a patient's tasks asks what changed with _lastUpdated=gt{instant} rather than reading the whole module again. NOT MEASURED.
  • authored-on -- date, http://hl7.org/fhir/SearchParameter/Task-authored-on. The received-date window on a worklist, sent as a pair: authored-on=ge{date}&authored-on=lt{date}. The bounds are the calendar days they fall on LOCALLY, so a task authored late in the local day is not reported against the following UTC one. NOT MEASURED.
  • based-on -- reference, http://hl7.org/fhir/SearchParameter/Task-based-on. The work raised for an order or a referral: Task?based-on=ServiceRequest/{id}. NOT MEASURED.
  • business-status -- token, http://hl7.org/fhir/SearchParameter/Task-business-status. The workflow state inside a lifecycle status -- a received task still awaiting review, for instance. The profile binds businessStatus REQUIRED as of 1.26.0, so the set of values a search can return is closed and known -- a code from outside it is an error rather than a local extension. Two vocabularies share that set and only one belongs on any given task: the correction lifecycle appears only on privacy-request tasks. NOT MEASURED.
  • code -- token, http://hl7.org/fhir/SearchParameter/Task-code. The task type, as a system-qualified token and usually as an OR-list: a worklist's type filter is this parameter and nothing else. NOT MEASURED.
  • focus -- reference, http://hl7.org/fhir/SearchParameter/Task-focus. The chart element the work is about: Task?focus=DocumentReference/{id} finds the tasks raised against a document. NOT MEASURED.
  • identifier -- token, http://hl7.org/fhir/SearchParameter/Task-identifier. The business key a producer minted: Task?identifier={system}|{value} retrieves that one task, and the system-only form {system}| sweeps every task from one producer. MEASURED: the request asserts an exact count of one, and a parameter the store dropped would answer with the tenant's whole task set.
  • intent -- token, http://hl7.org/fhir/SearchParameter/Task-intent. Assigned work versus a suggestion awaiting approval -- the distinction every worklist here is built on, since an inbox admits everything but proposal and a suggestions panel admits only it. MEASURED: the request asserts that an intent=proposal search returns no option-intent task, so a store collapsing the two fails it.
  • location -- reference, http://services.well.com/fhir/task/location. Where the work is to happen. NOT A BASE R4 PARAMETER: it is declared by the estate over Task.location at the canonical above, on a host this guide does not own, and a store never given that definition ignores it. MEASURED: a reference naming nothing returns zero rather than everything, which is exactly what separates a parameter that was applied from one that was dropped.
  • owner -- reference, http://hl7.org/fhir/SearchParameter/Task-owner. Whose work it is, as an OR-list over the practitioner AND the roles work reaches them through -- stored data holds both forms, so naming only one of them under-reports. NOT MEASURED. Asking instead for the tasks nobody owns is not something this surface can express; see the entry note on :missing.
  • patient -- reference, http://hl7.org/fhir/SearchParameter/Task-patient. The patient the task is filed against, resolved from Task.for. MEASURED: the request asserts that EVERY task returned is filed against the patient asked for, because a parameter silently ignored answers with the whole tenant's tasks and a count alone would not say so.
  • priority -- token, http://hl7.org/fhir/SearchParameter/Task-priority. Urgency, as an OR-list of the priorities wanted. NOT MEASURED.
  • requester -- reference, http://hl7.org/fhir/SearchParameter/Task-requester. Who raised the work, as a reference to a practitioner or one of their roles. A created-by worklist is this parameter. NOT MEASURED.
  • restriction-period-end -- date, http://services.well.com/fhir/task/restriction-period-end. The due date, from Task.restriction.period.end, used both to filter and as a sort key. NOT A BASE R4 PARAMETER: declared by the estate at the canonical above, on a host this guide does not own. MEASURED, on the same reasoning as location -- a date nothing falls on returns zero rather than everything.
  • status -- token, http://hl7.org/fhir/SearchParameter/Task-status. The lifecycle status, sent as an OR-list of the statuses wanted rather than as an exclusion. NOT MEASURED ON ITS OWN: the request that carries it carries other filters too, so nothing isolates this one.

Includes: Task:based-on Task:location Task:owner Task:patient Task:requester