consent.withdrawn
consent.withdrawn fires when a patient revokes an authorization they had previously granted to one of your projects. It is the notification that you must stop using that patient's data for that project, in accordance with the Data Use Policy the patient agreed to when they granted consent.
This event is time-sensitive and carries legal weight, so HealthEx targets sub-minute p95 delivery for it — stricter than the delivery target for other events.
When It Fires
The event is emitted when a patient revokes a previously-granted authorization for one of your projects from the authorization list on the Sharing tab of their Consumer Health Wallet.
Three conditions must all hold, which is worth knowing precisely so you don't wait for events that will never arrive:
- The consent transition is a revocation — the patient had opted in, and has now opted out. A patient who declines at the outset never generates this event, because there was no authorization to withdraw.
- The consent is scoped to a project. A user's consent to use HealthEx is not project-scoped, and a user deleting their HealthEx account or revoking consent to use HealthEx will not emit this event.
- The consent is a data consent —
consentTypeis eitherDATA_AUTHORIZATIONorPATIENT_DIRECTED_DATA_EXCHANGE. Withdrawal of aFUTURE_DATA_USEconsent does not emit this event.
The event is delivered to every active webhook whose project scope covers the project and whose subscribed events include consent.withdrawn.
Example Payload
For this example, we will use the following values:
- Organization ID:
56696fdb-2e0d - Project ID:
694d61c2-3f1b-4dc8 - Patient ID:
17d4513f-73e8-4b2a-9c1d-5e6f7a8b9c0d
A patient withdrawing access to their full record produces:
{
"type": "consent.withdrawn",
"timestamp": "2026-08-19T14:32:07.421Z",
"apiVersion": 1,
"deliveryAttempt": 1,
"organizationId": "56696fdb-2e0d",
"projectId": "694d61c2-3f1b-4dc8",
"data": {
"patientId": "17d4513f-73e8-4b2a-9c1d-5e6f7a8b9c0d",
"consentType": "PATIENT_DIRECTED_DATA_EXCHANGE",
"withdrawnAt": "2026-08-19T14:32:05.891Z",
"fullRecordWithoutRestrictedData": true,
"consentDataResourceScopes": null,
"consentDataSensitivityScopes": null,
"withdrawalSource": "PATIENT",
"effectiveImmediately": true
}
}
The envelope fields are documented in the Webhooks overview. Note that the project is identified by the envelope's projectId, not by a field inside data — consent is inherently project-scoped, and the envelope is the canonical location.
Key Fields
| Field | Description |
|---|---|
patientId | The HealthEx identifier for the patient whose consent was withdrawn. Map this to your own member identifier using whatever you recorded when consent was granted. |
consentType | Which kind of consent was withdrawn. Either DATA_AUTHORIZATION or PATIENT_DIRECTED_DATA_EXCHANGE. |
withdrawnAt | ISO 8601 timestamp of the patient's withdrawal action. Distinct from the envelope's timestamp, which is when the event was emitted — they will be very close but are not identical. |
fullRecordWithoutRestrictedData | true when the withdrawal covers the patient's full record. When true, both scope arrays below are null. |
consentDataResourceScopes | The categories of data the consent covered, or null when fullRecordWithoutRestrictedData is true. |
consentDataSensitivityScopes | The sensitivity classifications the consent covered, or null when fullRecordWithoutRestrictedData is true. |
withdrawalSource | Where the withdrawal originated. Currently always PATIENT. |
effectiveImmediately | Whether the withdrawal takes effect immediately. Currently always true. |
consentDataResourceScopes and consentDataSensitivityScopes describe the scopes that were in force before the withdrawal — that is, what the patient is revoking. They are not a description of what access remains. After a consent.withdrawn event, treat the listed scopes as no longer authorized.
Partial Withdrawal Example
When the withdrawn consent covered specific data categories rather than the full record, fullRecordWithoutRestrictedData is false and both arrays are populated. Patients can only withdraw from specific data categories if your project is configured to use data categories rather than the patient's full record:
{
"type": "consent.withdrawn",
"timestamp": "2026-08-19T16:08:44.102Z",
"apiVersion": 1,
"deliveryAttempt": 1,
"organizationId": "56696fdb-2e0d",
"projectId": "694d61c2-3f1b-4dc8",
"data": {
"patientId": "17d4513f-73e8-4b2a-9c1d-5e6f7a8b9c0d",
"consentType": "DATA_AUTHORIZATION",
"withdrawnAt": "2026-08-19T16:08:43.760Z",
"fullRecordWithoutRestrictedData": false,
"consentDataResourceScopes": ["MEDICATIONS", "LABS", "DIAGNOSES"],
"consentDataSensitivityScopes": ["NORMAL"],
"withdrawalSource": "PATIENT",
"effectiveImmediately": true
}
}
An array can be present but empty. Treat an empty array as "no scopes of this kind", distinct from null, which means the field doesn't apply because the whole record was withdrawn.
withdrawalSource and effectiveImmediately each have exactly one possible value today. They exist so that future withdrawal flows — a support-initiated withdrawal, or a scheduled rather than immediate one — can reuse this event without a breaking change.
Treat them as open enumerations. Don't assert that withdrawalSource === "PATIENT" or that effectiveImmediately is true; read them, and handle an unfamiliar value by processing the withdrawal and logging the unexpected value for review.
Enumerations
consentType is one of:
| Value | Emits consent.withdrawn |
|---|---|
DATA_AUTHORIZATION | Yes |
PATIENT_DIRECTED_DATA_EXCHANGE | Yes |
FUTURE_DATA_USE | No |
consentDataResourceScopes entries are drawn from:
ADMINISTRATIVE_AND_BILLING, ALLERGIES, CLINICAL_NOTES, CLINICAL_VITALS, CONTACT_INFO, DEMOGRAPHICS, DIAGNOSES, DIAGNOSTIC_REPORTS, FAMILY_HISTORY, GENOMIC_DATA, IMAGING, IMMUNIZATIONS, LABS, MEDICATIONS, PROCEDURES, SOCIAL_HISTORY, TREATMENT_PLAN, VISITS
consentDataSensitivityScopes entries are drawn from:
GENETIC_TESTING, HIV_OR_STI, MENTAL_HEALTH, NORMAL, PSYCHOTHERAPY_NOTES, REPRODUCTIVE_HEALTH_DATA, SICKLE_CELL, SUBSTANCE_USE_OR_DRUG_ABUSE, SUD_PART_2
New values may be added to either list over time. Handle unrecognized entries without failing the delivery.
Your Obligations On Receipt
Partners receiving consent.withdrawn are obligated to act in accordance with the Data Use Policy they presented to the patient during the consent grant flow. HealthEx's responsibility is to deliver the notification; acting on it is yours.
In practice:
- Suspend downstream use of that patient's data for that project.
- Propagate the withdrawal to any internal systems or caches holding the data.
- Retain your own record of when you received and acted on the event. The
webhook-idheader is a stable identifier to log alongside it.
Webhook delivery is reliable but not infallible — events are dropped while a webhook is paused, and a sustained outage on your side can exhaust the retry window. Check current consent state via the API as well. See Basic Consent Checking.
If a delivery fails permanently after all retry attempts, HealthEx Support is alerted and will contact you directly so the withdrawal is honored by other means.
Next Steps
- Verifying Signatures: Confirm the event really came from HealthEx
- Idempotency and Ordering: Handle repeat and out-of-order deliveries
- Troubleshooting: Diagnose an event you expected but never received