Tenant Authentication

Register a practitioner

  • Sandbox: available
  • Staging: available
  • Production: unknown
POST
/auth/tenant/Practitioner/register

Registers a new practitioner account in a tenant and returns its tokens, so the user is signed in straight away.

Auth: none. The tenant is named by tenantCode. Scope: the project that owns tenantCode.

Behaviour

  • The project setting PRACTITIONER_REGISTRATION_ENABLED must be true. It is off unless set.
  • The new membership gets the project's default practitioner access policy: the text setting DEFAULT_PRACTITIONER_ACCESS_POLICY, else CLINICIAN_INVITE_ACCESS_POLICY. Without a valid one, nothing is created and the answer is a 409 with error: "practitioner_registration_not_configured".
  • An email that already has a practitioner account (a server-wide User) joins this project when the request brings that account's own password: a new practitioner profile and membership, and the password is never changed. It is refused, with nothing written, for any other password, an account with MFA on, an account that is already a practitioner here, and an email that has a patient account in any project.
  • The password must have at least 12 characters, not counting spaces at either end, and must not be on Ovok's list of common and breached passwords. Any character is allowed and none is required. A refused password answers 422 with the error on password.
  • The User, the Practitioner profile and the membership are written in one atomic step. No email is sent.
  • Rate limit: 5 requests per minute per IP address.
  • Error responses are delayed to take at least one second.
  • A 409 with practitioner_registration_not_configured means the project has no practitioner registration setup.
  • A 429 means more than 5 requests in a minute from your IP address.

Example

curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/register' \  -H 'Content-Type: application/json' \  -d '{    "email": "max.mustermann@example.com",    "password": "your-password",    "name": "Max",    "surname": "Mustermann",    "tenantCode": "my-medical-project"  }'

Request Body

application/json
  1. body
email*string
Formatemail
password*string
Length12 <= length <= 128
name*string
surname*string
tenantCode*string

Response Body

Access token, refresh token, expiry, project and profile.

application/json
  1. response
accessToken*string

Bearer access token. Expires in 1 hour.

refreshToken?string

Refresh token.

expiresIn?integer

Token expiration.

Default3600
project*
profile*
Example Request
curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/register' \  -H 'Content-Type: application/json' \  -d '{  "email": "user@example.com",  "password": "stringstring",  "name": "string",  "surname": "string",  "tenantCode": "string"}'
Example Response
{  "accessToken": "string",  "refreshToken": "string",  "expiresIn": 3600,  "project": {    "reference": "string",    "display": "string"  },  "profile": {    "reference": "string",    "display": "string"  }}

Verify practitioner MFA code POST

Verifies the TOTP code of a practitioner who has MFA enrolled, after `login/start` answered `nextStep: "mfa"`. Returns the session code for `login/token` and the list of tenants the practitioner can enter. **Auth:** none. The `loginId` from `login/start` identifies the login. ## Behaviour - `mfaToken` must equal the current TOTP code generated from the user's MFA secret. - On success the login is marked MFA-verified and the response is `{ "nextStep": "token", "sessionCode": ..., "profiles": [...] }`. `profiles` is the same list `login/start` returns without MFA. - Pass `sessionCode` and one `tenantCode` from `profiles` to `POST /auth/tenant/Practitioner/login/token`. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Practitioner/login/mfa' \ -H 'Content-Type: application/json' \ -d '{ "loginId": "c3499c27-2973-0a7f-807e-fb8676a92dcb", "mfaToken": "123456" }' ```

Start patient login POST

Starts a patient login for one tenant: checks the email and password and returns either a session code to exchange for tokens or, when the user has MFA enrolled, a login ID for the MFA step. **Auth:** none. The tenant is named by `tenantCode`. **Scope:** the project that owns `tenantCode`. ## Behaviour - This is step 1 of a PKCE login. Generate a random `codeVerifier`, send its S256 hash as `codeChallenge` here, and send the `codeVerifier` itself to `POST /auth/tenant/Patient/login/token`. - The account must be a Patient of the tenant's project. A Practitioner with the same email cannot log in here. - `PATIENT_LOGIN_ENABLED` on the project must not be `false` (it defaults to on). - Response `nextStep`: - `token`: no MFA. Pass `sessionCode` to `login/token`. - `mfa`: the user has MFA enrolled. Pass `loginId` and the current TOTP code to `POST /auth/tenant/Patient/login/mfa`. - A wrong email, an unknown account, an account without a password and a wrong password all give the same 401 `Invalid email or password.` - After 5 failed sign-ins for one email within 15 minutes, that email's sign-ins answer 429 with `Retry-After` for 15 minutes, the right password included, whether or not the email has an account. A successful sign-in resets the count. - Error responses are delayed to take at least one second. ## Example ```bash curl -X POST 'https://api.sandbox.ovok.com/auth/tenant/Patient/login/start' \ -H 'Content-Type: application/json' \ -d '{ "email": "max.mustermann@example.com", "password": "your-password", "tenantCode": "my-medical-project", "codeChallenge": "<base64url S256 hash of your codeVerifier>" }' ```