# Consent, revocation, and deletion

> Every read checks consent first, so plan for sharing to end and for deletion requests.

## Consent receipts

When a patient shares with your app, FinchNode writes a [consent receipt](/docs/resources/glossary#consent-receipt). It records the categories, the source, how long the share lasts, and its status. `GET /consents/{receiptId}` returns one, and every snapshot lists the receipts behind it.

A patient who shares from two health systems has a receipt for each.

## What a read can return

| Response | Means | Do this |
| --- | --- | --- |
| `403 app_scope_exceeded` | The category isn't on your application's list. | Add it in the console, or stop asking for it. |
| `403 consent_scope_exceeded` | Your app may read it, but this patient didn't share it. | Read only shared categories. A new session can ask for more. |
| `410 consent_inactive` | No active receipt is left: the patient revoked sharing, or it expired. | Stop reading this subject and apply your retention policy. |
| `404 not_found` | The subject is gone, for example after a deletion request. | Stop reading and make sure you've deleted your copy. |

Record and change-feed reads keep returning `410` once consent is inactive. Expiry is enforced at read time, even before the expiry webhook arrives.

## Handle revocation and expiry

A patient can revoke sharing from their FinchNode account at any time. A share also ends when its `durationDays` runs out. With a webhook URL set, you hear about both:

| Event | `data` includes |
| --- | --- |
| `consent.revoked` | `receiptId`, `action`, `status`, `revokedAt` |
| `consent.expired` | `receiptId`, `action`, `status`, `expiredAt` |

When one receipt ends but another is still active, reads keep working, minus that source. Its records drop out of reads and the change feed without `delete` entries. To remove them:

1. Read `GET /consents/{receiptId}` for the receipt that ended.
2. Take its `source` and `categories`.
3. Delete the records you hold with that `source` in those categories.

## Handle a deletion request

When a patient asks FinchNode to delete all their data, every app they shared with gets `deletion.requested` for that subject. FinchNode then revokes their receipts and deletes its own copy, so the subject starts returning `404 not_found` and no `delete` changes follow.

Your copy is now the only one. Delete what you hold for that subject, following your retention policy and the law that applies to you.

## Keep a record of what you did

Log the event ID, the categories, and how many records you removed. Don't log record IDs or contents. See [Handling patient data](/docs/go-live/handling-patient-data).
