# Share readings with a carer

Canonical page: https://docs.ovok.com/invitations/share-with-a-carer

A signed-in **patient** shares chosen readings with a **carer**, such as a family member, by email. The carer reads only the Observation codes the patient picks, plus the patient's name. In FHIR a carer is a `RelatedPerson`.

| Step | Method | Path | Who |
| --- | --- | --- | --- |
| 1. Invite | `POST` | `/v1/invites/record-share` with `"recipient": "related-person"` | A patient |
| 2. Accept | `POST` | `/v1/invites/record-share/accept` | The carer: without a token for a new address, signed in otherwise |

Unlike a [practitioner share](/invitations/share-with-practitioner), **every** carer invite must be accepted, and a new address gets its account at that moment. A carer account cannot be made any other way. See [Carers](/authentication/carers) for signing in and what a carer can do.

## What the project needs [#what-the-project-needs]

Every row must hold before the address is looked up.

| Requirement | Detail |
| --- | --- |
| Patient sharing on | `enabled`, set with [`PUT /v1/patient-sharing/settings`](/settings-and-features/settings/patient-sharing-enabled). **Off by default.** This is the patient-to-patient switch, not `practitionerSharingEnabled`. |
| Carer invitations on | [`RELATED_PERSON_INVITATION_ENABLED`](/settings-and-features/settings/related-person-invitation-enabled) must not be `false`. It also gates step 2. |
| A patient app URL | [`PATIENT_APP_URL`](/settings-and-features/settings/patient-app-url). Carers use the patient app, so the link is built on it. The request's `Origin` is never used. |
| Fewer than 20 pending carer invites | Per patient. |
| Two email templates mapped | `RELATED_PERSON_INVITED` and `RELATED_PERSON_RECORD_SHARED`. If neither is [mapped](/email-templates/map-templates), Ovok sends `PATIENT_INVITE` and `PATIENT_ASSIGNMENT_REQUEST` instead. |

No default AccessPolicy is needed. Ovok creates the carer's built-in policy the first time one is needed.

## Step 1: Invite [#step-1-invite]

```bash
curl --request POST \
  --url 'https://api.sandbox.ovok.com/v1/invites/record-share' \
  --header "Authorization: Bearer ${PATIENT_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data '{
    "recipient": "related-person",
    "email": "sam@example.com",
    "firstName": "Sam",
    "lastName": "Doe",
    "codes": ["8480-6", "8462-4"]
  }'
```

| Body field | Required | Description |
| --- | --- | --- |
| `recipient` | Yes | `related-person`. |
| `email` | Yes | A valid address, up to 254 characters. Ovok lowercases it. |
| `firstName` | Yes | 1 to 200 characters. Used when the carer's account is created. |
| `lastName` | Yes | 1 to 200 characters. |
| `codes` | Yes | 1 to 100 Observation codes to share, each made of letters, digits, `.` and `-`. The example shares systolic and diastolic blood pressure (LOINC `8480-6`, `8462-4`). |

The answer is always `202 Accepted` with `{ "status": "sent" }`, whatever the address turned out to be.

### What happens, by address [#what-happens-by-address]

| The address… | What Ovok does |
| --- | --- |
| Has no account | Creates a pending invite and emails `RELATED_PERSON_INVITED` with an accept link. **No account yet:** it is made when the carer accepts. |
| Belongs to exactly one carer of the project | Creates a pending invite and emails `RELATED_PERSON_RECORD_SHARED` with an accept link. The share starts when the carer, signed in, accepts it. |
| Anything else | Writes and sends nothing. For example a patient or a practitioner of the project. One address cannot be both a patient and a carer. |

The pending invite holds only a hash of the one-time code and grants nothing until it is accepted. The link is `<patient app URL>/accept-invite?invite=<inviteId>&code=<code>`, and it works for 7 days.

## Step 2: Accept [#step-2-accept]

Your patient app serves `/accept-invite`. It reads `invite` and `code` from the link and posts them. How depends on whether the carer already has an account.

### A new carer: choose a password, no token [#a-new-carer-choose-a-password-no-token]

```bash
curl --request POST \
  --url 'https://api.sandbox.ovok.com/v1/invites/record-share/accept' \
  --header 'Content-Type: application/json' \
  --data '{
    "inviteId": "8c1e5a52-6f0b-4d9e-9a41-0b2f7c3d9e10",
    "code": "<code from the link>",
    "password": "<the password the carer chose>"
  }'
```

Holding the code proves the address is theirs, so no token is needed. In one write, Ovok creates the carer's user, a `RelatedPerson` linked to the patient, and a membership with the share. The carer then [signs in](/authentication/carers#sign-in) with the address and that password. The answer contains no tokens.

### An existing carer: signed in [#an-existing-carer-signed-in]

```bash
curl --request POST \
  --url 'https://api.sandbox.ovok.com/v1/invites/record-share/accept' \
  --header "Authorization: Bearer ${CARER_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data '{"inviteId":"8c1e5a52-6f0b-4d9e-9a41-0b2f7c3d9e10","code":"<code from the link>","password":null}'
```

The new share is added to the carer's account, next to any shares from other patients.

| Body field | Description |
| --- | --- |
| `inviteId` | The `invite` value from the link. A UUID. |
| `code` | The `code` value from the link, 16 to 128 characters. |
| `password` | The new carer's password, which must meet the password policy. `null`, or left out, for anyone who already has an account. |

### Which form to show [#which-form-to-show]

The link looks the same in both emails. To choose the screen, post the link's values with no token and `"password": null`:

| Answer | Show |
| --- | --- |
| `422` with `error` [`password_required`](/errors/password-required) | A "choose a password" form, then post again with `password`. |
| `401` | A sign-in form for the carer, then post again with their token. |

The code is checked first, so a wrong or used code answers `404`, `409` or `410` before either of these.

### The answer [#the-answer]

On success the answer is `200` with the share:

| Field | Example | Meaning |
| --- | --- | --- |
| `consentId` | `…` | Id the patient uses to end the share. |
| `sharer.patientId` | `…` | Patient whose readings are shared. |
| `sharer.name` | `Jane Doe` | Patient's display name. |
| `relatedPerson.relatedPersonId` | `…` | The carer's `RelatedPerson` id. |
| `relatedPerson.name` | `Sam Doe` | Carer's display name. |
| `codes` | `["8480-6", "8462-4"]` | The shared Observation codes. |
| `startedAt` | `2026-10-22T18:30:00.000Z` | Time the share began. |
| `endsAt` | `null` | No scheduled end time. |

The change applies on the carer's next request.

## What the carer can read [#what-the-carer-can-read]

| Resource | Access |
| --- | --- |
| The patient's Observations with a shared code | Read and search |
| The patient's `Patient` resource | Read and search, with `identifier`, `telecom`, `gender`, `birthDate`, `address`, `photo`, `contact`, `communication`, `generalPractitioner`, `managingOrganization`, extensions, narrative and the other personal fields hidden. The name stays visible. |
| The carer's own `RelatedPerson` | Read and search |

Nothing else, and nothing can be written or deleted. Another code, another patient's data, or any other resource answers `403` or `404` (an empty search). See [Carers](/authentication/carers#what-a-carer-can-and-cannot-do).

## End a share [#end-a-share]

The patient ends a carer share, or cancels a pending invite, with [`DELETE /v1/patient-sharing/shares/:consentId`](/settings-and-features/settings/patient-sharing-enabled). Access stops at once. The patient lists their carer shares in `relatedPersons` of `GET /v1/patient-sharing/shares`. A carer cannot list or leave shares yet.

## What can go wrong [#what-can-go-wrong]

**Invite**

| Status | Message or `error` | Cause |
| --- | --- | --- |
| `401` | | The token is missing or invalid. |
| `403` | `Only patients can share their record.` | The caller is not a patient. |
| `403` | `Sharing is not enabled for this project.` | Patient sharing is off. |
| `403` | `Invitation is not enabled for this project.` | [`RELATED_PERSON_INVITATION_ENABLED`](/settings-and-features/settings/related-person-invitation-enabled) is `false`. |
| `409` | `code` [`app_url_not_configured`](/errors/app-url-not-configured) | No patient app URL. Fix the configuration; retrying will not help. |
| `409` | | Another write holds the address, or the records kept changing. Retry. |
| `422` | A list of `path` and `message` | A field is missing or invalid: `recipient` is neither `practitioner` nor `related-person`, or `codes` is missing, empty, longer than 100 or holds a malformed code. |
| `429` | | The patient already has 20 pending carer invites. |

**Accept**

| Status | Message or `error` | Cause |
| --- | --- | --- |
| `401` | `Sign in as the related person this invite is for.` | No token for an invite to an existing carer. Also, with no message, when the token is invalid. |
| `403` | `Invitation is not enabled for this project.` | [`RELATED_PERSON_INVITATION_ENABLED`](/settings-and-features/settings/related-person-invitation-enabled) is `false`, even for an invite sent while it was on. |
| `403` | `Sharing is not enabled for this project.` | Patient sharing is off. |
| `403` | `Only the related person this invite is for can accept it.` | The caller is signed in, but not as a carer, for an invite to an existing carer. |
| `404` | | No live invite has this `inviteId`, the `code` does not match, the invite names another carer, or it belongs to another project than the caller's. |
| `409` | | The invite was already used, or the records kept changing. |
| `409` | `error` [`address_has_account`](/errors/address-has-account) | A new carer's address got an account after the invite was sent, for example as a patient. Nothing was written. Ask the patient for a new invite to another address. |
| `409` | `error` [`sharing_not_configured`](/errors/sharing-not-configured) | The project lost its patient-sharing AccessPolicy. An admin turns patient sharing on again. |
| `409` | `error` [`related_person_without_access_policy`](/errors/related-person-without-access-policy) | The carer's membership has no AccessPolicy, so a share would narrow its access. |
| `410` | | The invite expired. |
| `422` | `error` [`password_required`](/errors/password-required) | The invite creates an account and `password` is `null`. |
| `422` | A list of `path` and `message` | `inviteId` is not a UUID, `code` is not 16 to 128 characters, or `password` fails the password policy. |

## Gotchas [#gotchas]

- **Patient sharing gates this, not practitioner sharing.** A project with only `practitionerSharingEnabled` on answers `403`. Turn `enabled` on.
- **A new carer has no account until they accept.** Until then, a reset or sign-in for that address finds nothing.
- **One address, one kind of account.** An address that belongs to a patient or practitioner of the project is ignored on invite and refused on accept with [`address_has_account`](/errors/address-has-account).
- **`202` says nothing about the outcome.** It is the same answer whatever the address was. Tell the patient "if the address can receive it, an invitation is on its way".
- **A failed email is silent.** If the message cannot be sent, the invite is undone and the answer is still `202`. Map the templates first.
- **Turning invitations off also blocks pending invites.** With [`RELATED_PERSON_INVITATION_ENABLED`](/settings-and-features/settings/related-person-invitation-enabled) off, accepting answers `403` and no account is made.
- **Carer accounts belong to one project.** A carer of two projects has two accounts, one per tenant.

## Related [#related]

- [Carers](/authentication/carers): sign-in, password reset, and what a carer can do
- [Invitations](/invitations)
- [Share a record with a practitioner](/invitations/share-with-practitioner), the same route with `recipient: "practitioner"`
- [RELATED_PERSON_INVITATION_ENABLED](/settings-and-features/settings/related-person-invitation-enabled)
- [PATIENT_SHARING_ENABLED](/settings-and-features/settings/patient-sharing-enabled)
