Authentication
oikapi uses session-based authentication with secure cookies.
Endpoints
Section titled “Endpoints”POST /api/auth/loginContent-Type: application/json
{ "identifier": "user@example.com", "password": "Pass123!"}Sets a session cookie and returns {"user": {...}}. All subsequent browser requests use the cookie for authentication. Native (non-browser) clients additionally receive a session_token in the response body, which they may send as Authorization: Bearer <session_token>.
The identifier field accepts either an email address or a handle — an identifier containing @ is treated as an email, otherwise as a handle. This lets organizations that don’t use email addresses log users in by handle. (The older email field is still accepted.)
If your account has a second factor (an authenticator app or a passkey), login returns an mfa_required challenge instead of a session; complete it at POST /api/auth/mfa/verify.
Passkey login (passwordless)
Section titled “Passkey login (passwordless)”Oikapi supports WebAuthn/FIDO2 passkeys. A passwordless passkey login is phishing-resistant and needs no second step:
POST /api/auth/webauthn/login/begin → { "ceremony_id", "options" }POST /api/auth/webauthn/login/finish → { "user": {...} } + sessionHand options to navigator.credentials.get() and post the result to /finish. You can register additional passkeys on your account via POST /api/auth/webauthn/register/begin and /finish.
Register
Section titled “Register”POST /api/auth/registerContent-Type: application/json
{ "email": "user@example.com", "password": "Pass123!", "name": "Jane Smith"}Password requirements: at least one uppercase, one lowercase, one number, and one special character. The minimum length defaults to 8 characters and is admin-configurable (via the security.password_min_length setting) up to 72.
Get current user
Section titled “Get current user”GET /api/auth/meReturns the authenticated user’s profile.
Logout
Section titled “Logout”POST /api/auth/logoutDestroys the current session.
Rate limiting
Section titled “Rate limiting”Auth endpoints are always rate-limited regardless of global rate limiting configuration:
| Endpoint | Limit |
|---|---|
POST /api/auth/login | 5 per minute per IP |
POST /api/auth/register | 3 per minute per IP |
POST /api/auth/forgot-password | 5 per hour per IP |
POST /api/auth/reset-password | 5 per hour per IP |
GET /api/auth/verify-email | 10 per hour per IP |
POST /api/auth/resend-verification | 10 per hour per IP |
The email-verification and resend-verification limits are configurable via the rate_limiting.auth.email_verification_per_hour setting (default 10).
Account lockout
Section titled “Account lockout”After 5 failed login attempts within 15 minutes, the account is temporarily locked. The lockout duration starts at 15 minutes and doubles with each subsequent lockout (capped at 24 hours). A successful login resets the lockout counter.
Lockout responses return HTTP 429 with a retry_after value in seconds.
Session configuration
Section titled “Session configuration”Sessions auto-renew on each request. There is no manual refresh endpoint.
| Setting | Default | Description |
|---|---|---|
security.session.lifetime | 168h | Maximum session duration |
security.session.idle_timeout | 8h | Timeout after inactivity |
security.session.cookie_same_site | Lax | Cookie SameSite policy. Lax, not Strict — this instance is also an OpenID Provider, and Strict withholds the session cookie on the cross-site navigation to /oauth/authorize, silently breaking silent SSO for relying parties on a different registrable domain. |
API keys
Section titled “API keys”For programmatic access, use API keys instead of sessions. Pass the key with the ApiKey authorization scheme:
GET /api/apps/myapp/tables/projects/recordsAuthorization: ApiKey <api-key>API keys are managed as records on the api_keys system table:
POST /api/apps/system/tables/api_keys/recordsGET /api/apps/system/tables/api_keys/recordsDELETE /api/apps/system/tables/api_keys/records/{id}The raw key value is returned only once, at creation time. API keys inherit the permissions of the user they’re created for.
Emailless accounts & recovery
Section titled “Emailless accounts & recovery”Oikapi does not require every user to have an email address. Organizations can identify users by handle instead, in which case the traditional “verify by email” and “reset password by email” links don’t apply. For those accounts, first-time credential setup and account recovery run through a one-time setup token rather than an email link:
POST /api/auth/setup/password { "token": "...", "password": "..." }POST /api/auth/setup/passkey/begin { "token": "..." } # → drives a passkey registrationSetting up a password also returns one-time recovery codes — save them; they let you regain access offline if you lose your credential.
If your account has a phone number on file and your organization has enabled it, you can recover access via a one-time SMS code:
POST /api/auth/recover/sms/begin { "identifier": "<email or handle>" }POST /api/auth/recover/sms/verify { "identifier": "<email or handle>", "code": "123456" }verify returns a setup token you exchange at /api/auth/setup/password or /api/auth/setup/passkey/begin. SMS recovery is off by default and must be enabled by an administrator. For security, begin always returns a generic success response and never reveals whether an account or phone number exists.