Record Patient Consent

Use the RecordPatientConsent effect to record a patient’s consent decision on their chart. For example, a plugin can record the decision after the patient completes an intake form. The effect sets the consent’s state and effective date, and it can file the signed document with the consent.

Each patient has one PatientConsent record per consent coding. The first decision for a coding creates the record. A later decision updates it only when its effective_date is on or after the recorded one. See How Canvas records the decision.

Build a RecordPatientConsent with the attributes you want to set, then return its apply() from your handler.

Methods #

apply() → Effect #

Records the patient’s decision on one consent.

  • patient_id, consent, state, and effective_date are required.
  • patient_id must be the id of an existing patient.
  • consent must match exactly one PatientConsentCoding.
  • rejection_reason can be set only when state is REJECTED or REJECTED_VIA_PORTAL, and it must match exactly one PatientConsentRejectionCoding.
  • document.content must be a PDF file, base64 encoded. Line breaks in the encoded content are allowed. The decoded content must start with the PDF signature %PDF-, so another file type, such as a PNG, fails validation.

Attributes #

RecordPatientConsent #

AttributeTypeDescriptionRequired
patient_idstrThe id of the patient.Yes
consentConsentCodingReferenceThe consent coding the decision applies to.Yes
statePatientConsentStatusThe patient’s decision.Yes
effective_datedatetime.dateThe date the decision takes effect. It is also the date of the attached document.Yes
rejection_reasonConsentCodingReferenceThe reason the patient rejected the consent. Set it only with a rejected state.No
documentConsentDocumentThe signed consent document to file with the consent.No

The attributes are strictly typed. state takes a PatientConsentStatus member, not a string, and effective_date takes a datetime.date, not a datetime.datetime.

ConsentCodingReference #

Identifies a consent coding or a rejection coding.

AttributeTypeDescriptionRequired
systemstrThe coding system, such as LOINC or INTERNAL.Yes
codestrThe coding’s code.If display is empty
displaystrThe coding’s display text. Used to find the coding only when code is empty.If code is empty

When code is set, the effect finds the coding by system and code. Otherwise it finds the coding by system and display. The effect fails validation when the reference matches no coding or more than one. If a reference by code matches more than one coding, delete the duplicate coding in Canvas. If a reference by display matches more than one, reference the coding by its code instead.

ConsentDocument #

The signed copy of the consent.

AttributeTypeDescriptionRequired
filenamestrThe file name to store the document under, such as telehealth.pdf. It can be at most 255 characters and must not contain a path.Yes
contentstrThe bytes of a PDF file, base64 encoded. Other file types fail validation.Yes

How Canvas records the decision #

  • Earlier-dated decisions: The decision with the latest effective_date sets the consent’s state, dates, and rejection reason. A decision dated before the recorded one leaves the consent as it is, but Canvas still files its document. Use this to add an older signed copy without changing the current decision.
  • Expiration date: Canvas computes the consent’s expiration date from effective_date and the coding’s expiration rule.
  • Rejection reason: A decision that updates the consent replaces its rejection reason. A decision without rejection_reason, including any accepted decision, clears the earlier reason.
  • Signed documents: Each document you attach is added to the consent’s signed documents with effective_date as its date. The document with the latest date becomes the consent’s active_document, and earlier signed copies stay on the chart. Canvas codes each document LOINC 59284-0 (Consent Document), the same document type as a consent document staff upload, and its DocumentReference type carries that coding.
  • Other consents: The effect changes only the consent you name. A consent the patient did not answer keeps its current state.

Example #

This handler records an accepted telehealth consent and attaches the signed PDF:

import base64
import datetime

from canvas_sdk.effects import Effect
from canvas_sdk.effects.patient_consent import (
    ConsentCodingReference,
    ConsentDocument,
    RecordPatientConsent,
)
from canvas_sdk.handlers.base import BaseHandler
from canvas_sdk.v1.data import PatientConsentStatus


class RecordTelehealthConsent(BaseHandler):
    def compute(self) -> list[Effect]:
        # Replace with the bytes of the PDF the patient signed.
        signed_pdf = b"%PDF-1.7 ..."

        effect = RecordPatientConsent(
            # The handler responds to an event whose target is the patient.
            patient_id=self.event.target.id,
            consent=ConsentCodingReference(system="INTERNAL", code="TELEHEALTH"),
            state=PatientConsentStatus.ACCEPTED_VIA_PORTAL,
            effective_date=datetime.date.today(),
            document=ConsentDocument(
                filename="telehealth.pdf",
                content=base64.b64encode(signed_pdf).decode(),
            ),
        )
        return [effect.apply()]

To record a rejection, pass a rejected state and, optionally, the reason:

import datetime

from canvas_sdk.effects.patient_consent import ConsentCodingReference, RecordPatientConsent
from canvas_sdk.v1.data import PatientConsentStatus

effect = RecordPatientConsent(
    patient_id="1eed3ea2a8d546a1b681a2a45de1d790",
    consent=ConsentCodingReference(system="LOINC", code="59284-0"),
    state=PatientConsentStatus.REJECTED,
    effective_date=datetime.date.today(),
    rejection_reason=ConsentCodingReference(system="INTERNAL", display="Patient declined"),
)
effect.apply()