Auth endpoints
POST /api/v1/auth/email/verify/confirm
Section titled “POST /api/v1/auth/email/verify/confirm”Confirm Email Verification
Verify an address with the token from the emailed link.
No session is needed: the link is often opened in a browser that is not signed in, and the token alone proves the inbox. Unknown, used, expired and wrong-kind tokens all answer the same 404.
Request body (application/json, required): EmailVerifyConfirmIn
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: UserOut |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/email/verify/request
Section titled “POST /api/v1/auth/email/verify/request”Request Email Verification
Send the signed-in user a fresh verification link, at most 3 per hour.
| Status | Description | Body |
|---|---|---|
| 202 | Successful Response | application/json: AcceptedOut |
POST /api/v1/auth/login
Section titled “POST /api/v1/auth/login”Login
Check the password. A user with two-factor authentication gets a challenge, not a session.
The challenge is issued only after everything a session needs has held (throttle, password, a password that is still current), so it means exactly “the first step passed”.
Request body (application/json, required): LoginIn
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: LoginSignedInOut or LoginTotpRequiredOut |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/logout
Section titled “POST /api/v1/auth/logout”Logout
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
GET /api/v1/auth/me
Section titled “GET /api/v1/auth/me”Me
The caller’s account and memberships: for a browser session, and for a personal access token.
This is the one /auth route a token may call, so a tool can check that its token works and
whose it is.
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: MeOut |
DELETE /api/v1/auth/oauth/{provider}
Section titled “DELETE /api/v1/auth/oauth/{provider}”Unlink
Unlink a provider account. The provider need not still be configured.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
provider |
path | string | yes |
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
| 422 | Validation Error | application/json: HTTPValidationError |
GET /api/v1/auth/oauth/{provider}/callback
Section titled “GET /api/v1/auth/oauth/{provider}/callback”Callback
Finish a sign-in or link, then redirect: to next on success, to an error page if not.
Every query parameter is optional so a callback that is wrong in any way still gets the redirect the user can read, not a JSON validation error.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
provider |
path | string | yes | |
code |
query | string or null | no | |
state |
query | string or null | no | |
error |
query | string or null | no |
| Status | Description | Body |
|---|---|---|
| 302 | Redirect to next (with session cookies for a sign-in), or to /login?error=<CODE> (to next with error=<CODE> for a link). Clears spl_oauth. |
none |
| 422 | Validation Error | application/json: HTTPValidationError |
GET /api/v1/auth/oauth/{provider}/start
Section titled “GET /api/v1/auth/oauth/{provider}/start”Start
Send the browser to the provider. intent=link links it to the signed-in user instead.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
provider |
path | string | yes | |
intent |
query | "sign_in" | "link" |
no | Default "sign_in". |
next |
query | string or null | no |
| Status | Description | Body |
|---|---|---|
| 302 | Redirect to the provider’s sign-in page; sets spl_oauth. |
none |
| 422 | Validation Error | application/json: HTTPValidationError |
GET /api/v1/auth/oauth/identities
Section titled “GET /api/v1/auth/oauth/identities”List Identities
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: array of OAuthIdentityOut |
GET /api/v1/auth/oauth/providers
Section titled “GET /api/v1/auth/oauth/providers”List Providers
The providers that can be used to sign in, so the login page shows only working buttons.
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: array of OAuthProviderOut |
POST /api/v1/auth/password/forgot
Section titled “POST /api/v1/auth/password/forgot”Forgot Password
Email a reset link if the address has an account. The answer never says whether it does.
A known and an unknown address take the same path and get the same response: both are counted by the limits first, and neither is turned away early. The only difference is that a known address also gets a token and a queued email. The demo account counts as unknown.
Request body (application/json, required): PasswordForgotIn
| Status | Description | Body |
|---|---|---|
| 202 | Successful Response | application/json: AcceptedOut |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/password/reset
Section titled “POST /api/v1/auth/password/reset”Reset Password
Set a new password with the token from the emailed link.
No session is needed (the person forgot their password) and none is created: they sign in afterwards with the new password. Every session of the account is ended. Unknown, used, expired and wrong-kind tokens all answer the same 404.
Request body (application/json, required): PasswordResetIn
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
| 422 | Validation Error | application/json: HTTPValidationError |
DELETE /api/v1/auth/sessions
Section titled “DELETE /api/v1/auth/sessions”Delete Other Sessions
Sign out everywhere else: end every session of the user except the one making the call.
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
GET /api/v1/auth/sessions
Section titled “GET /api/v1/auth/sessions”List Sessions
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: array of SessionOut |
DELETE /api/v1/auth/sessions/{session_id}
Section titled “DELETE /api/v1/auth/sessions/{session_id}”Delete Session
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
session_id |
path | string (uuid) | yes |
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/signup
Section titled “POST /api/v1/auth/signup”Signup
Request body (application/json, required): SignupIn
| Status | Description | Body |
|---|---|---|
| 201 | Successful Response | application/json: UserOut |
| 422 | Validation Error | application/json: HTTPValidationError |
GET /api/v1/auth/tokens
Section titled “GET /api/v1/auth/tokens”List Tokens
The caller’s tokens that can still be used. Never includes a secret.
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: array of PersonalAccessTokenOut |
POST /api/v1/auth/tokens
Section titled “POST /api/v1/auth/tokens”Create Token
Create a token. The 201 is the only time its secret is shown.
Request body (application/json, required): PersonalAccessTokenCreateIn
| Status | Description | Body |
|---|---|---|
| 201 | Successful Response | application/json: PersonalAccessTokenCreatedOut |
| 422 | Validation Error | application/json: HTTPValidationError |
DELETE /api/v1/auth/tokens/{token_id}
Section titled “DELETE /api/v1/auth/tokens/{token_id}”Revoke
Revoke a token. Repeating it is fine; a token that is not the caller’s is a 404.
| Parameter | In | Type | Required | Notes |
|---|---|---|---|---|
token_id |
path | string (uuid) | yes |
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
| 422 | Validation Error | application/json: HTTPValidationError |
GET /api/v1/auth/totp
Section titled “GET /api/v1/auth/totp”Totp Status
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: TotpStatusOut |
POST /api/v1/auth/totp/disable
Section titled “POST /api/v1/auth/totp/disable”Totp Disable
Turn it off. Needs a valid code (TOTP or recovery), which is spent.
Request body (application/json, required): TotpCodeIn
| Status | Description | Body |
|---|---|---|
| 204 | Successful Response | none |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/totp/enable
Section titled “POST /api/v1/auth/totp/enable”Totp Enable
Turn it on with a code from the app. Returns the recovery codes, this once.
Request body (application/json, required): TotpCodeIn
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: TotpEnabledOut |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/totp/setup
Section titled “POST /api/v1/auth/totp/setup”Totp Setup
Make a secret for an authenticator app. Replaces one from an earlier, unconfirmed setup.
Needs the current password, or a sign-in in the last 10 minutes for an account without one.
Request body (application/json): TotpSetupIn or null
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: TotpSetupOut |
| 422 | Validation Error | application/json: HTTPValidationError |
POST /api/v1/auth/totp/verify
Section titled “POST /api/v1/auth/totp/verify”Totp Verify
The second step of signing in: a challenge and a code make a session.
The user row is locked before the failure count is read, so concurrent attempts for one account run one after another: the limit is exact, and a code cannot be spent twice. Wrong codes are recorded as failed sign-ins, so they share the password’s limit. A challenge issued before the password changed is refused: it passed the first step against a password that no longer exists.
Request body (application/json, required): TotpVerifyIn
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json: LoginSignedInOut |
| 422 | Validation Error | application/json: HTTPValidationError |