Skip to main content

Invite a patient

A signed-in practitioner invites a patient by email. If the address is new, Ovok creates a patient account whose record is already shared with the inviter. If it belongs to a patient of the project, that patient receives an invitation to accept.

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

What the project needs​

Every row must hold before the address is looked up.

RequirementDetail
Practitioner sharing onpractitionerSharingEnabled, set with PUT /v1/patient-sharing/settings. Off by default.
Patient invitations onPATIENT_INVITATION_ENABLED must not be false.
A patient app URLPATIENT_APP_URL. The request's Origin is never used here.
A default patient AccessPolicydefaultPatientAccessPolicy on the project; see set up your project.
An inviter with an AccessPolicyThe practitioner's membership must have one. A member with full project access is refused.
Fewer than 20 pending invitationsPer practitioner.
Two email templates mappedPATIENT_INVITE and PATIENT_ASSIGNMENT_REQUEST, mapped with a provider that is ready.

Step 1: Invite​

curl --request POST \
--url 'https://api.sandbox.ovok.com/v1/invites/patient' \
--header "Authorization: Bearer ${PRACTITIONER_TOKEN}" \
--header 'Content-Type: application/json' \
--data '{"email":"jane@example.com","firstName":"Jane","lastName":"Doe"}'
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 patient of the project with the default patient AccessPolicy and shares the record with the inviter, in one write, and emails a set-password link (PATIENT_INVITE).
Belongs to exactly one active patient of the projectCreates a pending invitation and emails an accept link (PATIENT_ASSIGNMENT_REQUEST), valid for 7 days. The share starts only when step 2 succeeds.
Already shares their record with the inviterSends 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 patient of this project.

Step 2: Accept​

The patient opens <patient 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/patient/accept' \
--header "Authorization: Bearer ${PATIENT_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 (the same shape as sharing with a practitioner). The practitioner then holds the patient's whole record, with the same access described there: no deletes, and the Patient can be read, searched and updated.

What can go wrong​

Invite

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

Accept

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

Gotchas​

  • Project admins with full access cannot use this route. A member with no AccessPolicy gets 409 practitioner_without_access_policy, because the share would narrow their access. Give inviters a limited AccessPolicy, or onboard patients another way, for example registration.
  • 202 says nothing about the outcome. It is the same answer for a new, existing, already-shared or ignored address, so it cannot be used to learn who has an account.
  • 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.
  • The patient controls the share. An invitation is single use and expires after 7 days, and the patient can end the share later with DELETE /v1/patient-sharing/shares/:consentId.
  • Sharing is off until an admin turns it on. Check it first when every call answers 403.
  • This is a way to create a patient, besides registration. Turning PATIENT_REGISTRATION_ENABLED off does not stop it. Turn off PATIENT_INVITATION_ENABLED or practitioner sharing to stop invitations.
  • Your app must serve the link. The email points at your patient app's /accept-invite and /setpassword paths.