Skip to content

Authentication

The Flatstack API accepts either a dashboard session or a token.

Signing in

Sign in to the dashboard with email and password, Google or GitHub. Account owners must also set up an authenticator app (TOTP) or a passkey before they can use the dashboard. This applies however the owner signs in.

A new email login gets an email with a link to confirm the address, and can’t sign in until it’s opened. The link works for 1 hour and signs you in the first time it’s used. Signing in with the right password before then sends a fresh link. Google and GitHub logins arrive confirmed.

Forgot your password? Ask for a reset link at /forgot-password in the dashboard. It works once, for 1 hour. Resetting signs out every session, and we email you to say it happened. Owners still need their second factor to sign in afterwards.

Sign-up, sending a new confirmation link and asking for a reset all answer the same whether or not an address has a login, so they can’t be used to find out who has one. If someone signs up with an address that already has a login, its owner gets an email instead.

Each address gets at most 5 confirmation and 5 reset emails an hour; past that, requests succeed but send nothing. Each IP can make 5 of these requests in any 15 minutes and 3 sign-in attempts in 10 seconds; past that, 429.

Request What it does
POST /auth/sign-up/email { "name", "email", "password", "callbackURL"? }. Sends the confirmation email. No session yet.
POST /auth/send-verification-email { "email", "callbackURL"? }. Sends a new confirmation link if the address has an unconfirmed login.
GET /auth/verify-email?token= Confirms the address and, the first time, signs in.
POST /auth/request-password-reset { "email" }. Sends a reset link if the address has a login.
POST /auth/reset-password { "token", "newPassword" }. At least 12 characters.

Until checkout completes, a new login can only see the plan picker and checkout. Every other request returns 403 with the code checkout_required. A login that never completes checkout is deleted after 7 days.

If you belong to more than one account, send the fs-account header with the account ID.

Tokens

Send a token as Authorization: Bearer <token>.

Kind Prefix Belongs to Scopes it can carry
Personal access token fs_pat_ You, in one account Any
Deploy token fs_dep_ One project deploy, env:read, logs:read, data:read

Scopes: projects:read, projects:write, deploy, env:read, env:write, logs:read, data:read, data:write. A personal access token can only carry scopes your role has, and is limited by your role as it is now (see Teams and roles).

Every token expires: after 90 days unless you choose otherwise, and after 365 days at most. The token is shown once when you create it; Flatstack stores only a hash. Revoke a token at any time and it stops working immediately.

Request What it does
GET /v1/tokens Lists your account’s tokens (never the token values).
POST /v1/tokens Creates a personal access token: { "name", "scopes", "expiresInDays"? }.
POST /v1/projects/{projectId}/deploy-tokens Creates a deploy token for one project.
DELETE /v1/tokens/{tokenId} Revokes a token.

Creating and revoking tokens needs a dashboard session, not a token. Each is recorded in the audit log.

Errors

Status Code Meaning
401 unauthenticated No session, or the token is unknown, expired or revoked.
403 checkout_required The login has no account yet. Choose a plan and finish checkout.
403 two_factor_required Account owners need TOTP or a passkey. Set one up in your profile.
403 forbidden Your role, or the token’s scopes, don’t allow this request.

As Markdown: api/authentication.md