Skip to content

NexusEmrCoreAppConsent Feature Overview

Introduction

The NexusEmrCoreAppConsent feature provides a standardized way to record and manage patient consent for third-party applications that integrate with healthcare data. This feature specifically addresses the scenario where patients sign up with apps that need access to their clinical information.

App consent is one of three Consent families in this guide, and they share a store. The other two are item consent for a clinic's email, SMS and AI-scribe preferences, and the privacy directive for a restriction on the record itself. All three carry scope = patient-privacy and all three come back from one GET Consent?patient={id}, so category is what tells them apart. Consent, Privacy and Record Integrity is the section overview, and it holds the rule that reads every family plus the discriminator — read it before writing a consumer that touches more than one.

An app consent does not override a privacy directive. A patient may grant an app access and separately restrict part of their record; both are in force, and reconciling them is the consumer's job, because nothing in this estate does it. The privacy directive page states what an active restriction means and the consent override page states the only lawful way past one.

Use Case

The Problem

When patients want to use third-party healthcare applications (like AI scribes, wellness apps, or clinical decision support tools), healthcare providers need a standardized way to:

  1. Record consent - Document that the patient has agreed to share their data
  2. Track app details - Maintain information about which specific application has access
  3. Manage consent lifecycle - Handle consent updates, withdrawals, and status changes
  4. Maintain compliance - Keep records for legal and regulatory requirements
  5. Enable interoperability - Use standardized FHIR structures for consent management

The Solution

NexusEmrCoreAppConsent uses two complementary FHIR profiles:

Profile Overview

NexusEmrCoreAppConsent Profile

The NexusEmrCoreAppConsent profile is based on the FHIR R4 Consent resource and follows a KISS (Keep It Simple, Stupid) approach, including only essential fields needed for app consent tracking.

Key Design Principles

  1. Focused Use Case - Specifically designed for patient app signup consent
  2. Required FHIR Compliance - Includes all mandatory R4 Consent fields
  3. Fixed Values - Uses appropriate fixed values for the app consent context
  4. Extensible - Can accommodate future enhancements while maintaining simplicity

Field Descriptions

Required Fields

Field Value Purpose Why Required
identifier Nexus EMR naming pattern Unique consent record ID Track individual consent instances
status active | draft | inactive | entered-in-error Current consent state FHIR R4 requirement, lifecycle management
scope patient-privacy (fixed) Type of consent FHIR R4 requirement, indicates privacy consent
category Two codings: v3-ActCode#INFA (pinned) and the family code nexus-consent-family#app (pinned) What the consent governs, and which Consent family it is INFA is the FHIR R4 category requirement, information access. The family code is how a mixed GET Consent?patient={id} is told apart -- all three families carry scope = patient-privacy, so only category separates them
patient Reference to NexusEmrCorePatient Who gave consent Identify the consenting patient
dateTime ISO 8601 timestamp When consent was given Legal requirement, audit trail
policy.uri 1..1 — a URI The policy the decision was recorded under FHIR R4 ppc-1 requires either policy or policyRule; this profile satisfies it with policy. policyRule is not used — see the profile for why the former fixed cric value was wrong
provision.type 1..1 — permit | deny on the root provision The decision One element, the same one every Consent profile in this guide uses
provision.actor Reference to NexusEmrCoreAppDevice Which app has access Identify the specific application

Optional Fields

Field Purpose When to Use
sourceAttachment Original signed consent document When you have a PDF/image of the signed form

FHIR R4 has a counterintuitive but official way to model consent decisions. We follow this for compliance, even though it's... not simple:

The Rules (From Official FHIR R4 Spec):

  1. status='proposed' - Request more information from patient
  2. status='active' + provision.type='permit' - GRANT CONSENT
  3. status='active' + provision.type='deny' - DENY CONSENT

Why This Complexity?

R4's element definition says provision.type is "Not permitted in root rule, required in all nested rules". This guide does not follow that reading, and the divergence is deliberate: IHE Privacy Consent on FHIR and Ontario's Provincial Consent Override Interface both require the root type, because a consent whose base rule states no decision states none where a reader looks first.

Refusal was previously a nested provision with type='deny', and a grant was the absence of one. Two problems with the absence: it is not a statement, so a truncated or partially-written resource read as a grant; and it disagreed with the sibling profiles, so a consumer needed a different rule per family. Both decisions are now stated positively on the root.

Result: one element, read the same way on every Consent profile in this guide.

Status Meanings:

Status Meaning Provision Structure User Summary
proposed "We need more info before deciding" provision.type is present but not yet the patient's answer "Pending"
active "The record is operative — provision.type is the decision" permit grants, deny refuses "Granted" or "Denied"
draft Currently unused in our use case TBD "Pending"
inactive "Previously active consent now withdrawn" Any provision structure "Invalid" or "Cancelled"
entered-in-error "Consent record was created in error" N/A - record is invalid "Invalid" or "Cancelled"

Decision to User Summary Translation

The decision is provision.type on the root provision, and status says only whether the record is operative. Read them in that order:

For status = "active":

  • provision.type = "permit""Granted"
  • provision.type = "deny""Denied"

Do not walk the nested provisions looking for a deny. There are none, and a reader that infers a grant from their absence reads a refusal as permission.

For status = "proposed" or status = "draft":

  • "Pending" (whatever provision.type carries — nobody has answered yet)

For status = "inactive" or status = "entered-in-error":

  • "Invalid" or "Cancelled" (consent decision is no longer valid/relevant)

NexusEmrCoreAppDevice Profile

The NexusEmrCoreAppDevice profile represents the third-party application and includes:

  • identifier - App identifiers (including OAuth client_id)
  • deviceName - Human-readable app name
  • status - Whether the app registration is active
  • manufacturer - App developer/company (optional)
  • type - Software application type
  • note - Brief description of the app

Complete Example

Here's a complete example showing how a patient consents to use an AI scribe application:

Step 1: Create the App Device

{
  "resourceType": "Device",
  "id": "smartdocs-ai-scribe",
  "meta": {
    "profile": ["https://fhir.apps.health/StructureDefinition/nexus-emr-core-appdevice"]
  },
  "text": {
    "status": "generated",
    "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>SmartDocs AI Scribe</b></p><p>AI-powered clinical documentation assistant. Client ID: smartdocs-ai-scribe-prod</p></div>"
  },
  "identifier": [
    {
      "system": "https://fhir.apps.health/NamingSystem/nexus-emr-appdevice-identifier",
      "value": "smartdocs-ai-scribe"
    },
    {
      "system": "https://oauth.example.com/client-registry",
      "value": "smartdocs-ai-scribe-prod",
      "use": "secondary"
    }
  ],
  "status": "active",
  "deviceName": [
    {
      "name": "SmartDocs AI Scribe",
      "type": "user-friendly-name"
    }
  ],
  "manufacturer": "ClinicalAI Solutions",
  "type": {
    "text": "AI Clinical Documentation App"
  },
  "note": [
    {
      "text": "AI application for automated clinical note generation and transcription that integrates with patient data."
    }
  ]
}
{
  "resourceType": "Consent",
  "id": "nexus-emr-core-app-consent-scribe-ai-example",
  "meta": {
    "profile": ["https://fhir.apps.health/StructureDefinition/nexus-emr-core-app-consent"]
  },
  "text": {
    "status": "generated",
    "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>App Consent</b></p><p>Patient: <strong>Avery Linwood</strong> has <strong>CONSENTED</strong> to sign up with and share clinical data with <strong>SmartDocs AI Scribe</strong> application.</p><p>Date: April 8, 2025</p></div>"
  },
  "status": "active",
  "scope": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/consentscope",
        "code": "patient-privacy",
        "display": "Privacy Consent"
      }
    ]
  },
  "category": [
    {
      "coding": [
        {
          "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
          "code": "INFA",
          "display": "information access"
        }
      ]
    },
    {
      "coding": [
        {
          "system": "https://fhir.apps.health/CodeSystem/nexus-consent-family",
          "code": "app",
          "display": "Application consent"
        }
      ]
    }
  ],
  "patient": {
    "identifier": {
      "system": "https://fhir.apps.health/NamingSystem/cedarbrook-clinic-patient-raw-code",
      "value": "patient-avery-linwood"
    },
    "display": "Avery Linwood"
  },
  "dateTime": "2025-04-08T10:30:00-06:00",
  "policy": [
    {
      "uri": "https://fhir.apps.health/policy/nexus-privacy-policy"
    }
  ],
  "sourceAttachment": {
    "contentType": "application/pdf",
    "title": "SmartDocs AI Scribe Consent Form - Signed",
    "creation": "2025-04-08T10:30:00-06:00",
    "size": 12345,
    "hash": "ZGEwNTQwYTM5YTMwMGM5ZjYzZGI4YzJjYTI2ZWFmYzE=",
    "data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKPj4KZW5kb2JqCjIgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDEKPD4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCAyIDAgUgovTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzIDw8L0ZvbnQgPDwvRjEgNCAwIFI+Pj4+Ci9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoK"
  },
  "provision": {
    "type": "permit",
    "actor": [
      {
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
              "code": "IRCP",
              "display": "information recipient"
            }
          ]
        },
        "reference": {
          "identifier": {
            "system": "https://fhir.apps.health/NamingSystem/nexus-emr-appdevice-identifier",
            "value": "smartdocs-ai-scribe"
          },
          "display": "SmartDocs AI Scribe"
        }
      }
    ]
  }
}

Common Scenarios

Scenario 1: Request More Information

  • Create NexusEmrCoreAppConsent with status = "proposed"
  • Include provision with actor (the app requesting consent)
  • Patient/provider can review and decide
  • Create NexusEmrCoreAppDevice resource for the application
  • Create NexusEmrCoreAppConsent with:
    • status = "active"
    • Root provision.type = "permit"
    • provision.actor referencing the app
  • Result: Consent granted, stated positively
  • Create NexusEmrCoreAppDevice resource for the application
  • Create NexusEmrCoreAppConsent with:
    • status = "active"
    • Root provision.type = "deny"
    • provision.actor referencing the app
  • Result: Consent refused. No nested provision is involved, and status stays active — the record of a refusal is operative
  • Update existing NexusEmrCoreAppConsent
  • Set status = "inactive"
  • Update dateTime to withdrawal timestamp
  • Keep original provision structure for audit trail

Scenario 5: Error Correction

  • Set status = "entered-in-error"
  • Create new corrected consent resource
  • Not yet defined for our app consent use case
  • Could potentially be used for staged consent workflows

Examples

The three shapes differ in exactly two elements: status and provision.type. Everything else is the same resource.

Example 1: Request More Information (status='proposed')

{
  "resourceType": "Consent",
  "status": "proposed",
  "scope": { /* patient-privacy */ },
  "category": [{ /* INFA */ }, { /* family: app */ }],
  "patient": { /* patient reference */ },
  "dateTime": "2025-04-08T10:30:00-06:00",
  "policy": [{ "uri": "https://fhir.apps.health/policy/nexus-privacy-policy" }],
  "provision": {
    "type": "permit",
    "actor": [{
      "role": { /* information recipient */ },
      "reference": { /* app device reference */ }
    }]
  }
}

provision.type is required, so a proposed consent carries one — but status = "proposed" means nobody has answered yet, and the value is not the patient's decision. Read status before treating provision.type as an answer.

{
  "resourceType": "Consent",
  "status": "active",
  "scope": { /* patient-privacy */ },
  "category": [{ /* INFA */ }, { /* family: app */ }],
  "patient": { /* patient reference */ },
  "dateTime": "2025-04-08T10:30:00-06:00",
  "policy": [{ "uri": "https://fhir.apps.health/policy/nexus-privacy-policy" }],
  "provision": {
    "type": "permit",
    "actor": [{
      "role": { /* information recipient */ },
      "reference": { /* app device reference */ }
    }]
  }
}
{
  "resourceType": "Consent",
  "status": "active",
  "scope": { /* patient-privacy */ },
  "category": [{ /* INFA */ }, { /* family: app */ }],
  "patient": { /* patient reference */ },
  "dateTime": "2025-04-08T10:30:00-06:00",
  "policy": [{ "uri": "https://fhir.apps.health/policy/nexus-privacy-policy" }],
  "provision": {
    "type": "deny",
    "actor": [{
      "role": { /* information recipient */ },
      "reference": { /* app device reference */ }
    }]
  }
}

Note: a refusal is one value on one element, and it is the same element a grant uses. There is no nested provision and no inference from absence, so a truncated or partially-written resource cannot read as a grant. The published examples are the ones to copy.

Integration Patterns

With OAuth/OIDC

  • Store OAuth client_id in NexusEmrCoreAppDevice.identifier
  • Link consent decisions to OAuth authorization flows

With EMR Systems

  • Use the consent decision (provision.type, on an active record) to control data access APIs
  • Integrate with existing EMR consent workflows

With Audit Systems

  • Track all consent lifecycle events
  • Maintain compliance audit trails

Best Practices

  1. Always create the Device first - The app must exist before consent can reference it
  2. Use meaningful identifiers - Include clinic/system identifiers in naming systems
  3. Maintain source documents - Use sourceAttachment when available for legal compliance
  4. Update, don't delete - Use status changes rather than deletion for consent lifecycle
  5. Include narrative text - Provide human-readable summaries for clinical staff

Validation Notes

  • Both profiles include Nexus EMR identifier invariants for validation
  • Standard FHIR R4 validation applies to all fields
  • Fixed values for scope and category ensure consistency across implementations
  • Must Support (MS) flags indicate which fields should be supported by implementations