Authentication
Sign in for a session, and what to do when two-factor or single sign-on is in the way.
Most routes need a caller. There are two kinds:
| Session | API key | |
|---|---|---|
| How you get it | Signing in (email and password, an identity provider, or SSO) | Created by a signed-in user under Account → API keys |
| How you send it | The session cookie the sign-in sets | The x-api-key header |
| What it reaches | Everything the user may do | An organization's projects and their content, within the key's permissions — see API keys |
| Good for | The web app, interactive tools | Scripts, integrations, other servers |
Each operation in the reference lists which of the two it accepts.
Signing in with email and password
curl -i -X POST https://gamma.example.com/api/auth/sign-in/email \
-H "Content-Type: application/json" \
-d '{ "email": "ana@example.com", "password": "…" }' \
-c cookies.txtThe response sets the session cookie (gamma.session_token unless the deployment renames it, with a __Secure- prefix over HTTPS). Send it back on every request — a browser does that on its own; with curl, pass -b cookies.txt.
curl https://gamma.example.com/api/projects -b cookies.txtPOST /api/auth/sign-out ends the session. GET /api/auth/get-session tells you who you are signed in as.
From a browser on another origin
The server accepts cross-origin requests only from the origins it is configured for, and the session cookie is SameSite=Lax. A page on your own domain cannot use a Gamma session; use an API key from your server instead.
Two-factor authentication
When the account has a second factor, the sign-in answers { "twoFactorRedirect": true } instead of a full session. Finish it with one of:
POST /api/auth/two-factor/verify-totp— the code from an authenticator app;POST /api/auth/two-factor/send-otp, thenPOST /api/auth/two-factor/verify-otp— a code by email;POST /api/auth/two-factor/verify-backup-code— one of the backup codes.
An organization can require two-factor of its members. Until a member enrols, every route under that organization and its projects refuses them with 403.
Passkeys
A browser can sign in with a passkey instead: GET /api/auth/passkey/generate-authenticate-options, the WebAuthn ceremony in the browser, then POST /api/auth/passkey/verify-authentication with its result. That answers a full session, with no second step, because the passkey must verify its user (PIN or biometric); one that did not is refused with PASSKEY_USER_NOT_VERIFIED. The Passkeys section of the reference also covers registering, listing, renaming and deleting them. A script has no authenticator: use a password or an API key.
Single sign-on
An organization can bring its own identity provider (OIDC or SAML) for its email domain. Ask GET /api/auth-config/sso-domain?domain=example.com whether a domain signs in that way, then start with POST /api/auth/sign-in/sso. The Single sign-on section of the reference covers registering a provider and verifying its domain.
Public routes
A few routes need no caller at all: the routes under /api/auth that sign you in, the sign-in page's configuration under /api/auth-config, and /api/openapi.json.
