Sign-in flows create a session. The Tenant API offers four entry points:

  • signIn — email + password
  • signInIDP — third-party identity provider (see IdP)
  • signInPasswordless — magic link / OTP (see passwordless)
  • createSessionToken — admin impersonation, no credentials required

All of them rely on the same per-IP rate limiting, captcha, and revealUserExists masking described in anti-abuse. All of them are recorded in the audit log. (since 2.2) Sign-in anomaly detection, when enabled, scores only the password signIn path; the IdP and passwordless flows seed its baseline but are not themselves scored.

Password sign-in

mutation {
  signIn(email: "admin@example.com", password: "", expiration: 60) {
    ok
    result { token }
    error { code retryAfter }
  }
}
ArgNotes
email, passwordRequired.
expirationMinutes the session token should live. Capped at login.maxTokenExpiration.
otpTokenTOTP code if 2FA is enabled for the person.
options.trustForwardedClientInfo(since 2.2) See proxy trust.

Errors:

CodeCause
UNKNOWN_EMAILNo person with that email. Only returned when login.revealUserExists: true.
INVALID_PASSWORDWrong password. Only returned when login.revealLoginMethod: true (since 2.2).
INVALID_CREDENTIALSWrong email or password. Returned when login.revealUserExists: false (masks the email branch) and/or login.revealLoginMethod: false (masks the password/no-password branch).
PERSON_DISABLEDThe person has been disabled.
EMAIL_NOT_VERIFIED(since 2.2) The account was created while signup.requireEmailVerification was on and has not yet verified its e-mail. Prompt the user to verify, or resend via requestEmailVerification. See e-mail verification.
NO_PASSWORD_SETThe person has no password (IDP-only / passwordless-only). Only returned when login.revealLoginMethod: true (since 2.2); otherwise collapsed into INVALID_CREDENTIALS.
OTP_REQUIREDThe person has 2FA enabled and otpToken was missing — or (since 2.2) anomaly detection forced a step-up for an unusual sign-in. The step-up case can occur even for an account with no standing 2FA and is indistinguishable from the 2FA case at the API; recover it identically by retrying signIn with otpToken set to the emailed code.
INVALID_OTP_TOKEN2FA token rejected.
RATE_LIMIT_EXCEEDEDPer-IP login rate limit (since 2.2) or per-email exponential backoff hit. retryAfter carries the wait in seconds.

Signing out

signOut invalidates the current session token. To end every session for the caller (e.g. "log out everywhere"):

mutation { signOut(all: true) { ok } }

signOut requires a session token; it does not work with permanent API keys.

When the session was federated via an OIDC provider that supports RP-initiated logout, signOut also returns a logoutUrl (since 2.2). Redirect the browser there to terminate the session at the IdP as well (OIDC Single Logout); it is null for plain/password sessions and for IdPs without an end_session_endpoint, where only a local logout happens. The logoutUrl is only produced when the IdP session was captured at sign-in — i.e. when session re-validation (configuration.revalidation.enabled) is on for that provider; otherwise it is always null even if the IdP has an end_session_endpoint.

mutation { signOut { ok logoutUrl } }

Admin: create session token

A SUPER_ADMIN (or any role with the PERSON_CREATE_SESSION_KEY permission) can mint a session token for any person without credentials. Useful for impersonation and debugging:

mutation {
  createSessionToken(email: "user@example.com", expiration: 120) {
    ok
    result { token }
    error { code }
  }
}

Pass either email or personId. Records a create_session_token audit entry.

Login configuration

All login behavior is controlled by the login section of the tenant configuration:

FieldEffect
revealUserExistsSee anti-abuse — enumeration protection.
revealLoginMethod(since 2.2) When false, NO_PASSWORD_SET / INVALID_PASSWORD are collapsed into INVALID_CREDENTIALS and signUp omits the recommendedAction hint on EMAIL_ALREADY_EXISTS. Orthogonal to revealUserExists.
baseBackoff, maxBackoff, attemptWindowPer-email exponential backoff. Also drives the mail-init throttle for password reset and passwordless init.
defaultTokenExpirationLifetime applied when the client omits expiration.
maxTokenExpirationCap on client-requested expiration.
anomalyDetection(since 2.2) Opt-in sign-in anomaly detection for the password path — score thresholds that email the user or force a step-up second factor on an unusual login.

What the session can do

The session token authorizes subsequent Tenant API calls and Content API calls. The session's effective IP and User-Agent — visible in Identity.sessions and in audit-log entries — depend on whether the api_key has trust-forwarded-info.