Skip to main content

Share a record with a practitioner

A signed-in patient shares their whole record with a practitioner, by email. If the address is new, Ovok creates a practitioner account that already holds the share. If it belongs to a practitioner of the project, that practitioner receives an offer to accept.

StepMethodPathWho
1. InvitePOST/v1/invites/practitionerA patient
2. Accept (existing practitioners only)POST/v1/invites/practitioner/acceptThe invited practitioner

What the project needs​

Every row must hold before the address is even looked up.

RequirementDetail
Practitioner sharing onpractitionerSharingEnabled, set with PUT /v1/patient-sharing/settings. Off by default.
Practitioner invitations onPRACTITIONER_INVITATION_ENABLED must not be false.
A practitioner app URLPRACTITIONER_APP_URL. The request's Origin is never used here, because the caller is a patient.
A default practitioner AccessPolicyDEFAULT_PRACTITIONER_ACCESS_POLICY, or the older CLINICIAN_INVITE_ACCESS_POLICY.
Fewer than 20 pending offersPer patient.
Two email templates mappedPRACTITIONER_INVITED_BY_PATIENT and PRACTITIONER_PATIENT_SHARED, mapped with a provider that is ready.

Step 1: Invite​

curl --request POST \
--url 'https://api.sandbox.ovok.com/v1/invites/practitioner' \
--header "Authorization: Bearer ${PATIENT_TOKEN}" \
--header 'Content-Type: application/json' \
--data '{"email":"dr.smith@example.com","firstName":"Alex","lastName":"Smith"}'
Body fieldRequiredDescription
emailYesA valid address, up to 254 characters. Ovok lowercases it.
firstNameYes1 to 200 characters. Used when a new account is created.
lastNameYes1 to 200 characters.

The answer is always 202 Accepted, with the same response for every address outcome below:

FieldValue
statussent

What happens, by address​

The address…What Ovok does
Has no accountCreates a practitioner of the project with the default practitioner AccessPolicy and the patient's share, in one write, and emails a set-password link (PRACTITIONER_INVITED_BY_PATIENT).
Belongs to exactly one active practitioner of the projectCreates a pending offer and emails an accept link (PRACTITIONER_PATIENT_SHARED), valid for 7 days. The share starts only when step 2 succeeds.
Already holds this patient's shareSends nothing, unless their account still has no password, in which case the set-password email goes out again.
Anything elseWrites and sends nothing. For example an account that is not a practitioner of this project, or a practitioner with full project access.

Step 2: Accept​

The practitioner opens the link <practitioner app URL>/accept-invite?invite=<inviteId>&code=<code> in your app, signs in, and your app posts both values:

curl --request POST \
--url 'https://api.sandbox.ovok.com/v1/invites/practitioner/accept' \
--header "Authorization: Bearer ${PRACTITIONER_TOKEN}" \
--header 'Content-Type: application/json' \
--data '{"inviteId":"8c1e5a52-6f0b-4d9e-9a41-0b2f7c3d9e10","code":"<code from the link>"}'
Body fieldDescription
inviteIdThe invite value from the link. A UUID.
codeThe code value from the link, 16 to 128 characters.

On success the answer is 200 with the share:

FieldExampleMeaning
consentId…Id used to end the share later.
sharer.patientId…Patient whose record is shared.
sharer.nameJane DoePatient's display name.
practitioner.practitionerId…Practitioner receiving access.
practitioner.nameDr. Alex SmithPractitioner's display name.
startedAt2026-10-06T08:15:00.000ZTime the share began.
endsAtnullNo scheduled end time.

The practitioner now has access to the patient's whole record: they can read, search, create and update Observations, Communications, DocumentReferences, QuestionnaireResponses, ServiceRequests, Tasks and Appointments; read CommunicationRequests, Goals, CarePlans, Flags, EpisodeOfCare and DeviceUseStatements; and read, search and update the Patient. Nothing can be deleted. The change applies on the practitioner's next request.

What can go wrong​

Invite

StatusMessage or errorCause
401The token is missing or invalid.
403Only patients can invite practitioners.The caller is not a patient.
403Practitioner sharing is off, or PRACTITIONER_INVITATION_ENABLED is false.
409code app_url_not_configuredNo practitioner app URL. Fix the configuration; retrying will not help.
409error invitation_not_configuredNo default practitioner AccessPolicy.
409Another write holds the address, or the records kept changing. Retry.
429The patient already has 20 pending offers.
422A list of path and messageA field is missing or invalid.

Accept

StatusMessage or errorCause
401The token is missing or invalid.
403Practitioner sharing is not enabled for this project.Sharing is off. Checked before the caller's role.
403PRACTITIONER_INVITATION_ENABLED is false, or the caller is not a practitioner.
404No live offer has this inviteId, the code does not match, the offer names another practitioner, or the caller has no practitioner membership in the project.
409The offer was already used, the patient is no longer a member, or the records kept changing.
409error practitioner_without_access_policyThe practitioner has full project access, which a share would narrow.
410The offer expired.
422A list of path and messageinviteId is not a UUID, or code is shorter than 16 characters.

Gotchas​

  • 202 says nothing about the outcome. It is the same answer whether the address was new, existing, already shared, or ignored, so it cannot be used to learn which emails have accounts. Tell the patient "if they have an account, they will be emailed".
  • A failed email is silent. If the message cannot be sent, everything the invitation wrote is undone and the answer is still 202. Map the two templates first.
  • Practitioners with full project access can never receive a share. A project admin with no AccessPolicy is ignored on invite and refused at accept with practitioner_without_access_policy. Give people who should receive shares a limited AccessPolicy.
  • An offer is single use and lasts 7 days. A second accept answers 409.
  • Sharing is off until an admin turns it on. Check it first when every call answers 403.
  • The share covers the whole record. Unlike patient-to-patient sharing, there is no list of codes to choose.
  • The patient ends it. The share lasts until the patient ends it with DELETE /v1/patient-sharing/shares/:consentId.
  • Your app must serve the link. The email points at your practitioner app's /accept-invite and /setpassword paths.