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