TotalBase
Data API

Authentication

Sessions and personal access tokens on the Data API: signing in, sending the credential, and what each one can reach.

Every Data API request carries a credential:

Authorization: Bearer <credential>

There is no anonymous access. A request without a valid credential is 401 AUTHENTICATION_REQUIRED. The only routes open without one are the public authentication routes, public workflow webhooks, and files marked PUBLIC.

There are two kinds of credential. Both identify a user, and that user's roles are read again on every request.

CredentialObtained byGood for
Sessionsigning in with email and password, an invitation, or an auth provideran application acting for a person who signed in
Personal access token (tb_…)created by its owner or an administratora program, device or agent: API tokens

Signing in

curl -s -X POST https://ops.acme-field.example/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email": "[email protected]", "password": "…"}'
{ "data": { "token": "Yk2…", "user": { "id": "…", "email": "[email protected]", "name": "Lucía Paz" } } }

The user needs a role with API access. The authentication routes take their fields directly, not inside data.

A failed sign-in always answers 401 with "Invalid email or password", whatever the reason: unknown email, wrong password, locked or inactive account. The one exception is an unverified email (403 EMAIL_NOT_VERIFIED), which is only revealed after the right password.

A session lasts auth.session_ttl_hours (30 days by default) from when it was created. It isn't extended by use. End it with:

POST /api/auth/logout
Authorization: Bearer <session>

GET /api/auth/me returns the signed-in user.

The authentication routes

RouteDoes
POST /api/auth/loginsign in with email and password
POST /api/auth/logoutend the session
GET /api/auth/methe current user
POST /api/auth/registercreate an account, if auth.registration_enabled
POST /api/auth/password/forgotemail a reset link (always answers success)
POST /api/auth/password/resetset a new password with a reset link's token
POST /api/auth/password/changechange your password (session only)
POST /api/auth/email/verifyverify an email with a link's token
POST /api/auth/email/resendsend a new verification link
POST /api/auth/invitations/acceptaccept an invitation and set a password
GET /api/auth/oauth/{provider}sign in with Google, GitHub or OIDC: Auth providers

Links in emails are built from the instance's public URL and point at the admin's own pages (/admin/auth/...), which call these routes. An application with its own pages can use the routes directly.

Sessions versus tokens

SessionPersonal access token
Lifetimeauth.session_ttl_hours1-3650 days, chosen when created
Account routes (password, email, sessions)yesno
Recorded in the audit log asthe userthe token
$USER.* in row filtersthe user's rowthe owner's row
NeedsAPI accessAPI access (plane=API) or Administrators (plane=ADMIN)

Either way, nothing about permissions is stored in the credential. A role removed from the user, a deactivated account, or a revoked token takes effect on the next request.

Time zone

Dates are calculated in the caller's time zone: what "today" means for $PERIOD.today, and where date_trunc cuts days. The zone is the user's own preference, else the instance's (system.timezone), else the one the client sends:

X-TotalBase-Timezone: America/Argentina/Salta

CORS

A browser application on another origin can call the API once its origin is allowed in Settings › Network (security.cors_origins). CORS is off by default and never allows * by default.

Next steps