Account & tokens
The signed-in person
The signed-in person (roles, is_admin, namespace, `email_verified`: false until the emailed link is opened — runs wait for it; resend with POST /csl/auth/v1/email/verification-notification), `terms_accepted` (false when the person never accepted the terms in force: no version, or older than `terms_version`; accept with POST /api/v3/me/terms) and `terms_version`, the account the request acts for (`account`, with the member's `permissions`, `custom_role` and agency `branding`), every account they can switch to (`accounts`: own, organizations, and client workspaces of agencies they run; each with is_agency, status, parent) `pending_invitations`, `locale` (en|vi|null) and `theme` (light|dark|system|null, see /api/v3/me/preferences), `username` and `avatar_url` (see /api/v3/me/profile). One query for the agencies of the listed client workspaces, none per client
Deletes the person's own account
Deletes the person's own account: {password, code (when 2FA is on), confirm: their email}. Only from their own dashboard session (an API token or an organization context gets 403). Refused (422 on confirm) for Lantfly staff, owners of an organization, and while a deletion guard objects (live subscription, credit, open payout, active runs). Sign-in stops at once; data is purged by a queued job. DELETE /csl/auth/v1/profile is refused (403)
Replace preference (me)
The person's own preferences, whichever account they act for: {locale: en|vi} and/or {theme: light|dark|system} (kept across devices; `/me` returns it as `theme`). locale is the dashboard language. Mail and notifications to them go in it (your profile); `/me` returns it as `locale`. Every `/api/v3` response (validation and error messages) follows the request's Accept-Language (en|vi), else this saved locale. Never with an organization API token (403)
Create term (me)
The person accepts the terms of service and privacy policy in force: {accepted: true}. Stamps terms_accepted_at and terms_version once per version; a second call keeps the first time. Returns {terms_accepted, terms_version, terms_accepted_at}. Never with an organization API token (403)
Get profile (me)
Settings → Account: the person's username, avatar_url, first_name, last_name, bio (≤200), readme (Markdown ≤2000), website_url, github_username, twitter_username, linkedin_url, discord_user_id, is_public, show_email, public_url. Stored as your profile; always the person, whichever account the request acts for. An organization API token gets 403 here and on every /api/v3/me/profile, /me/avatar, /me/preferences, /me/security, /me/session-lifetime and /me/sessions route
Update any of the fields above
Update any of the fields above (null or empty clears). username is lowercase [a-z][a-z0-9.-], 3-30, unique, not reserved nor u⟨digits⟩; it names the public profile, actor slugs keep u{id}. first_name + last_name become `name`. is_public needs a username; dropping the username turns it off. Everything is checked before anything is written
Create avatar (me)
Multipart `avatar`: PNG, JPEG or WebP, ≤ lantfly.accounts.avatar_max_kb (1024), 32-4000 px. Replaces the previous picture; returns the profile
Removes the picture
Removes the picture
What a limited API token can be given
Dashboard session only. What a limited API token can be given: [{key, label}] (actors.read|run|build|write, runs.read|write, tasks.read|run|write, schedules.read|write, storages.read|write, webhooks.read|write)
A new secret for the API token, same name, abilities
Dashboard session only. A new secret for the API token, same name, abilities (scope, actors, permissions, creator) and expiry; the old one stops at once. Returns {id, name, token, expires_at}. In an organization only the member who created the token rotates it (owner and admins revoke the others' ones), and it takes `tokens.create`
Get security (me)
Dashboard session only. Settings → Login & Privacy: recent_until (sensitive changes open until; null = confirm the password at POST /csl/auth/v1/reauth {password, code}), reauth_minutes, session_lifetime_days (the person's, null = default_session_days), the person's dashboard sessions (id, ip_address, user_agent, created_at, last_used_at, expires_at, is_current), trusted_devices (browsers where sign-in skips the 2FA code: id, device, ip_address, created_at, last_used_at, expires_at, is_current) with trusted_device_days (0 = off), and general_access of the acting account (RESTRICTED | ANYONE_WITH_ID_CAN_READ) with can_manage_general_access
Replace session lifetime (me)
{days: 1-365 | null}: how long a dashboard sign-in of the person lasts, sessions already open included (checked on every request). null = platform default. Needs a recent sign-in
Signs one of the person's dashboard sessions out
Dashboard session only. Signs one of the person's dashboard sessions out (the current one too). API tokens are not sessions
Create revoke other (me › sessions)
Dashboard session only. Signs out every dashboard session of the person but the current one, and forgets every trusted browser but this one; returns {revoked}
Forgets every browser the person trusted
Dashboard session only. Forgets every browser the person trusted (this one too): the next sign-in there asks for the 2FA code. Returns {forgotten}. A new password, a password reset, and turning 2FA off or on do it too
Forgets one trusted browser of the person
Dashboard session only. Forgets one trusted browser of the person
Create email code (auth › 2fa)
Public, 10 per minute per IP. Mails the 6-digit code of a sign-in's 2FA challenge (`challenge_token` from POST /csl/auth/v1/login or the social exchange), for accounts with two-factor by email only (`methods` has `email`); then send it to POST /csl/auth/v1/2fa/challenge. A code works once for 10 minutes; at most 3 mails per challenge
Mails the signed-in person a code
Dashboard session only. Mails the signed-in person a code: to confirm a sensitive change (reauth, account deletion, conversion) with two-factor by email, or to turn it on or off. At most 3 per 10 minutes
Create email (me › 2fa)
Dashboard session and a recent sign-in. Turns two-factor by email on with a code from /api/v3/me/2fa/email-code. Refused (409 two_factor_app_on) while an authenticator app is on; turning the app on later turns this off. Security email sent
Delete email (me › 2fa)
Dashboard session and a recent sign-in. Turns two-factor by email off with a fresh code from /api/v3/me/2fa/email-code
The Getting started checklist of the acting account
The Getting started checklist of the acting account: {hidden, done, total, complete, tracks: [{key: listening|actors, steps: [{key, done, detail?}]}]}. Steps come from each module (OnboardingSteps): project_created (detail.project_id), source_added, collected, channel_set; run_started, run_succeeded (detail.run: the latest run, id, status, actor, default_dataset_id), schedule_created, token_created. The listening track shows only to who may see listening and while the account has 2 projects or fewer
Create hide (me › onboarding)
Hides the checklist for this person and the acting account, on every browser (not with an organization's token)
Shows it again
Shows it again
The consent page of an MCP OAuth request
Dashboard session only. The consent page of an MCP OAuth request (`request` in the dashboard URL): {id, client_name, redirect_uri, redirect_host, scope, expires_at}. The app named itself; `redirect_host` is where the access goes
Approves the request for account_id
Dashboard session only. Approves the request for `account_id` (the person's own account when omitted, or an organization they may make tokens for: `tokens.create`), read-only when `read_only`. Answers {redirect_to}: the app's redirect URI with a one-time `code`, `state` and `iss`; send the browser there. The app is told by email (security notice)
Turns the request down
Dashboard session only. Turns the request down: {redirect_to} carries `error=access_denied` back to the app
Connected apps
Dashboard session only. Connected apps: AI apps the person connected to the MCP server through OAuth, for any of their accounts: [{id, client_name, redirect_host, account {id, name}, read_only, scope, created_at, last_used_at}]. Their hourly tokens are not listed under /api/v3/me/tokens. A new password disconnects every app
Disconnects an app
Dashboard session only. Disconnects an app: its tokens stop working at once and its refresh tokens are spent
Replace general access (account)
{general_access: RESTRICTED | ANYONE_WITH_ID_CAN_READ} for the acting account (organizations: owner/admin only; a custom role with team.manage gets 403). ANYONE_WITH_ID_CAN_READ lets /api/v3 dataset items, key-value store keys and records be read by id without a token or signature. Needs a recent sign-in; logged as account.general_access_changed
API tokens of the acting account
Dashboard session only. API tokens of the acting account (in an organization: your own, or all for owner/admin, with `created_by`). Dashboard sessions are never listed here (see /api/v3/me/security). Every /api/v3/me/tokens* call answers 403 `session_required` for any API token (credentials are managed from the dashboard). Ended dashboard sessions, sessions unused for a platform setting (30) and tokens past expires_at are deleted hourly
Create a token for the acting account
Dashboard session only. Create a token for the acting account (the plain token is in the answer, once). In an organization it acts for the organization and stops working when its creator leaves. `permissions` (keys from /api/v3/me/token-permissions) limits the token to those (`perm:⟨key⟩` abilities): anything they do not cover (billing, team, token management, …; listening needs `listening.read` / `listening.write`) answers 403 `insufficient_permissions`; `GET /api/v3/me` stays open. `scope: read_only` tokens may only GET/HEAD. `actor_ids` (ids or `user~name`) limits the token to those actors (read, builds, start runs), their runs (read, log, abort) and reading the default storages of those runs (by id; writes are the run's own token's); on /api/v3/mcp and /api/v3/standby the same scope applies. Stored as Sanctum abilities `*` or `read`, `actor:⟨id⟩`, plus `member:⟨id⟩` for organization tokens. The list answers `scope` and `actor_ids` per token.
Update token (me)
Renames an API token {name} (not a dashboard session). In an organization only its creator, with `tokens.create`
Revoke an API token
Dashboard session only. Revoke an API token: your own, or in an organization any token when you manage the team (no `tokens.create` needed). A dashboard session id is not an API token: nothing is revoked (sign it out at /api/v3/me/sessions/{session})
Create convert to organization (me)
Settings → Organizations: turns the person's own account into an organization. Dashboard session of the person's own account only. The account keeps its id and everything keyed by it (actors and `u{id}` namespace, runs, storages, plan, credit, Paddle customer, earnings, username and profile); a new personal account with the same email, password and 2FA becomes its owner. Dashboard sessions end (sign in again); API tokens keep working as organization tokens of the owner; AI apps connected through OAuth are disconnected (connect them again for the organization). Refused for Lantfly staff and for members of any organization