Authentication & accounts
Your app's end-users sign up and log in through the /account service. A
successful login returns a session; the client sends it back on every request (the SDK
handles this automatically via a cookie, or you pass the secret in X-Appwrite-Session).
Sign up & log in
# Create an account
curl -X POST "https://base.finiteskills.com/v1/account" -H "X-Appwrite-Project: <YOUR_PROJECT_ID>" \
-H "Content-Type: application/json" \
-d '{"userId":"unique()","email":"user@example.com","password":"password123","name":"Jane"}'
# Create a session (log in)
curl -X POST "https://base.finiteskills.com/v1/account/sessions/email" -H "X-Appwrite-Project: <YOUR_PROJECT_ID>" \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}'
Read the current account with GET /account, list sessions, and log out with
DELETE /account/sessions/current.
Login methods
- Email + password —
POST /account/sessions/email. - Anonymous —
POST /account/sessions/anonymous; later upgrade withPATCH /account/emailto attach an email + password. - Magic link —
POST /account/tokens/magic-urlemails a link; complete withPOST /account/sessions/token. - Email OTP —
POST /account/tokens/emailsends a 6-digit code. - Phone OTP —
POST /account/tokens/phone(requires an SMS gateway to be configured for the deployment). - OAuth / OIDC —
GET /account/sessions/oauth2/{provider}for Google, GitHub, or a generic OIDC provider your project admin configures.
Password policy
Passwords must be at least the deployment's minimum length (8 by default). When the breached-password check
is enabled, the password is additionally screened against the Have-I-Been-Pwned corpus using k-anonymity — only
the first five characters of its SHA-1 leave the process, and a match returns
400 password_policy_violation. OTP-based logins cap wrong attempts: after the limit a token is burned
and a fresh code must be requested.
Two-factor (TOTP)
A signed-in user can enable authenticator-app 2FA:
POST /account/mfa/totp -> { secret, uri } (show the uri as a QR code)
PUT /account/mfa/totp -> { recoveryCodes } (verify a 6-digit code to enable)
# Afterwards, email login also requires an `otp` field:
POST /account/sessions/email { email, password, otp }
Passkeys (WebAuthn)
Register a passkey for a signed-in user (a second factor / device credential), or let a user log in with a
passkey and no password at all. Each ceremony is two calls — start returns the WebAuthn options and
challenge, finish verifies the authenticator's response:
POST /account/mfa/webauthn/register/start -> { options } # pass to navigator.credentials.create()
POST /account/mfa/webauthn/register/finish { response } # verify + store the credential
POST /account/webauthn/login/start { email } -> { options } # navigator.credentials.get()
POST /account/webauthn/login/finish { email, response } # verifies + returns a session
SAML single sign-on
A project admin registers a SAML identity provider; your app then starts login by redirecting the browser to the SP endpoint, and the IdP posts its assertion back to the Assertion Consumer Service (ACS), which mints a session just like OAuth:
GET /account/sessions/saml/{provider} # 302 -> the IdP login page
POST /account/sessions/saml/{provider}/acs # IdP posts the assertion here -> session
Email verification & password reset
POST /account/verifications/email sends a verification link;
POST /account/recovery starts a password reset. When the deployment has email configured, the
link is emailed; otherwise the token is returned in the response for your app to deliver.
JWTs for your own backend
POST /account/jwt returns a short-lived JWT the client can forward to your backend, which
passes it to FiniteBase as X-Appwrite-JWT to act as that user. The token carries custom claims —
email, emailVerification, teams and roles — on top of the
project and user ids.
# Default: HS256, symmetric, verifiable only by the engine.
POST /account/jwt -> { jwt }
# RS256: asymmetric, signed with the project RSA key (carries a `kid`).
POST /account/jwt { "alg": "RS256" } -> { jwt }
An RS256 token can be verified offline by your own backend against the project's public keys — no round-trip to FiniteBase. Fetch the JSON Web Key Set (which includes the project header but needs no session) and the OIDC discovery document:
GET /keys # JWKS: the project RSA public key(s), keyed by `kid`
GET /openid-configuration # OIDC discovery: issuer + jwks_uri