Authentication API
16 endpoints, generated from packages/core/openapi/v1.snapshot.json (OpenAPI 3.1.0, contract version 1.0). Conventions for lists, errors, money and authentication are on the API conventions page.
GET/api/v1/auth/demo/personas
Demo personas (demo mode only)
Responses
200 Success. object
itemsarray of objectrequiredmembershipIdstring (uuid)requireddisplayNamestringrequiredemailstringrequiredrolesarray of stringrequired
- 404
not_found
POST/api/v1/auth/demo/sign-in
Sign in as a demo persona (demo mode only)
Request body
application/json, object, required
membershipIdstring (uuid)required
Responses
204 No content.
- 400
validation_failed - 404
not_found
POST/api/v1/auth/invitations/accept
Accept an invitation with a password
Sets the password (or confirms the existing one for people already on Crow HR), activates the membership and signs in.
Request body
application/json, object, required
tokenstringrequiredmin length 20 · max length 200
passwordstringrequiredmin length 1 · max length 1024
displayNamestringmin length 1 · max length 120
codestringmax length 20
Responses
200 Success. object
orgSlugstring | nullrequired
- 400
validation_failed - 401
invalid_credentials,invalid_mfa_code - 403
password_sign_in_disabled - 409
conflict
POST/api/v1/auth/invitations/inspect
Look up an invitation link
Request body
application/json, object, required
tokenstringrequiredmin length 20 · max length 200
Responses
200 Success. object
statusenumrequiredone of "valid", "expired", "used", "revoked", "unknown"
organisationobject or nullrequirednamestringrequiredslugstring | nullrequired
emailstring | nullrequireddisplayNamestring | nullrequiredexistingAccountbooleanrequiredmfaRequiredbooleanrequiredpasswordAllowedbooleanrequiredprovidersarray of objectrequiredidstring (uuid)requiredkindstringrequireddisplayNamestringrequired
- 400
validation_failed
GET/api/v1/auth/methods
Sign-in methods an organisation has enabled
Public. Without `org`, resolves the only organisation of a single-organisation install.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
org | query | string | no |
Responses
200 Success. object
orgSlugRequiredbooleanrequiredorganisationobject or nullrequirednamestringrequiredslugstring | nullrequired
passwordobjectrequiredenabledbooleanrequired
providersarray of objectrequiredidstring (uuid)requiredkindenumrequiredone of "google", "entra", "singpass", "oidc"
displayNamestringrequiredallowedDomainsarray of stringrequired
demoModebooleanrequiredsingpassLogoUrlstring | nullrequired
- 400
validation_failed - 404
not_found
POST/api/v1/auth/mfa/verify
Complete a sign-in with a TOTP or recovery code
Completes a password sign-in (token from `/auth/sign-in`) or an SSO sign-in that needs Crow HR's TOTP (token in the `crowhr_mfa` cookie set by the SSO callback; omit `mfaToken`). Wrong codes count toward the account's MFA lock; requests are also limited per network.
Request body
application/json, object, required
mfaTokenstringmin length 1 · max length 200
codestringrequiredmin length 6 · max length 20
Responses
200 Success. object
mfaRequiredbooleanrequiredmfaTokenstringmfaExpiresAtstring (date-time)redirectTostring
- 400
validation_failed - 401
invalid_mfa_code - 429
rate_limited
GET/api/v1/auth/oidc/{providerId}/callback
Identity provider callback
The only cookie-authenticated GET with side effects; protected by `state`. Validates the ID token (signature, issuer, audience, expiry, nonce) and the provider restrictions, links or matches the identity, then signs in.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
providerId | path | string (uuid) | yes |
state | query | string | no |
Responses
302 Redirect into the app, or back to the sign-in page with an error.
- 400
validation_failed - 403
forbidden,reauth_required - 404
not_found
GET/api/v1/auth/oidc/{providerId}/jwks.json
Relying-party public keys for a provider (Singpass)
Parameters
| Name | In | Type | Required |
|---|---|---|---|
providerId | path | string (uuid) | yes |
Responses
200 Success. object
keysarray of objectrequiredktystringrequiredkidstring
- 400
validation_failed - 404
not_found
GET/api/v1/auth/oidc/{providerId}/start
Start single sign-on with a provider
Redirects to the identity provider (authorization code + PKCE S256, state and nonce kept server-side for 10 minutes). `purpose=test` is an owner's test sign-in; `purpose=link` links the provider to the signed-in user. `purpose=demo` (only on a server configured with `DEMO_SINGPASS_PROVIDER_ID` and `DEMO_SINGPASS_RETURN_URL`, only for that Singpass provider) is the in-browser demo's Singpass round trip: nobody is signed in or linked, and the browser returns to the demo with `singpass=ok` or `singpass=failed`.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
providerId | path | string (uuid) | yes |
purpose | query | enum | no |
invitation | query | string | no |
native | query | string (uuid) | no |
Responses
302 Redirect to the identity provider.
- 400
validation_failed - 403
disabled_in_demo,forbidden,reauth_required - 404
not_found
POST/api/v1/auth/password-reset/complete
Set a new password from a reset link
Single use. Revokes every session and device of the user.
Request body
application/json, object, required
tokenstringrequiredmin length 20 · max length 200
passwordstringrequiredmax length 1024
Responses
200 Success. object
orgSlugstring | nullrequired
- 400
validation_failed - 409
conflict
POST/api/v1/auth/password-reset/inspect
Check a password reset link before showing the form
Request body
application/json, object, required
tokenstringrequiredmin length 20 · max length 200
Responses
200 Success. object
statusenumrequiredone of "valid", "expired_or_used"
orgSlugstring | nullrequired
- 400
validation_failed
POST/api/v1/auth/password-reset/request
Request a password reset email
Always answers 202, whether or not the email belongs to a member.
Request body
application/json, object, required
orgstringrequiredmin length 1
emailstringrequiredmax length 254
Responses
202 Success. object
acceptedtruerequiredemailConfiguredbooleanrequired
- 400
validation_failed
POST/api/v1/auth/reauth
Confirm it's you before a sensitive action
Password sessions: password, plus a TOTP or recovery code when MFA is enrolled. SSO sessions re-authenticate by an SSO round-trip instead.
Request body
application/json, object, required
passwordstringrequiredmin length 1 · max length 1024
codestringmax length 20
Responses
200 Success. object
authenticatedAtstring (date-time)required
- 400
validation_failed - 401
invalid_credentials,invalid_mfa_code,session_expired,session_revoked,unauthenticated - 403
csrf_rejected
POST/api/v1/auth/sign-in
Sign in with email and password
Every failure (unknown email, wrong password, suspended, locked) answers the same 401 invalid_credentials. When MFA is enrolled the response carries a pending-sign-in token instead of a session.
Request body
application/json, object, required
orgstringrequiredmin length 1
emailstringrequiredmax length 254
passwordstringrequiredmin length 1 · max length 1024
nativeRequestIdstring (uuid)
Responses
200 Success. object
mfaRequiredbooleanrequiredmfaTokenstringmfaExpiresAtstring (date-time)redirectTostring
- 400
validation_failed - 401
invalid_credentials - 403
password_sign_in_disabled - 429
rate_limited
POST/api/v1/auth/sign-out
Sign out of this browser session
Responses
204 No content.
POST/api/v1/auth/switch-organisation
Switch the session to another organisation you belong to
Issues a new session token (rotation) scoped to the target organisation.
Request body
application/json, object, required
orgstringrequiredmin length 1 · max length 100
Responses
200 Success. object
orgSlugstringrequired
- 400
validation_failed - 401
session_expired,session_revoked,unauthenticated - 403
csrf_rejected,mfa_enrolment_required - 404
not_found