Getting started
Authenticate against the Febasi Auth API in five minutes — log in, hold an access token, call /me.
This page takes you from "I have a tenant code" to "I'm holding a verified
access token." Five minutes, two curl commands.
What you need
A tenant code
The unique slug of your organization — for the Febasi internal tenant
this is febasi. You receive yours during onboarding.
A user identifier
Your email, username, or cpf_cnpj — whichever your tenant has
enabled. The Auth API accepts whichever the tenant configured.
A password
Bcrypt-hashed at rest with 12 rounds. Sent only over HTTPS.
Step 1 — Log in
Send credentials
POST /api/v1/login returns an access token and a refresh token.
curl -X POST https://auth.febasi.com.br/api/v1/login \
-H "Content-Type: application/json" \
-d '{
"tenantCode": "febasi",
"identifier": "you@febasi.com.br",
"password": "your-password"
}'Read the response
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "8c9a3a48-7b9d-...",
"expiresIn": 900,
"user": {
"id": "01HXY...",
"email": "you@febasi.com.br",
"username": null,
"tenantId": "01HX0...",
"tenantCode": "febasi"
}
}
}The access token is a JWT signed with HS256. It already contains your
roles, permissions, tenantId, and tenantCode, so most consumers do not
need to call /me on every request.
Step 2 — Call an authenticated endpoint
curl https://auth.febasi.com.br/api/v1/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"success": true,
"data": {
"id": "01HXY...",
"email": "you@febasi.com.br",
"tenantCode": "febasi",
"roles": ["super_admin"],
"permissions": ["users:read", "users:create", "..."]
}
}If the token has expired, you will get:
{ "success": false, "error": "Token expired", "code": "TOKEN_EXPIRED" }…which is your cue to refresh.
Step 3 — Refresh before the access token expires
curl -X POST https://auth.febasi.com.br/api/v1/refresh \
-H "Content-Type: application/json" \
-d '{ "refreshToken": "8c9a3a48-7b9d-..." }'The response is identical to /login — you get a brand-new access token and
a brand-new refresh token. The old refresh token is revoked the moment the new
one is minted (token rotation).
Sessions are atomic
Each successful /login opens a session backed by a refresh token. Tenants
configure a max-concurrent-sessions limit; when you exceed it, the oldest
session is revoked automatically so the new one fits. Read more in
Sessions.
Step 4 — Log out
curl -X POST https://auth.febasi.com.br/api/v1/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{ "refreshToken": "8c9a3a48-7b9d-..." }'This explicitly revokes the refresh token. The access token will continue to
work until its exp claim, but it cannot be refreshed any longer.
Where to go next
Login flow in depth
Edge cases: wrong identifier, password policy violations, brute-force protection, the dummy-hash timing-attack mitigation.
Refresh & rotation
The full lifecycle of a refresh token, including session limits and revocation reasons.
Authorization with RBAC
Roles, permissions, hierarchy, and effective grants — when does the JWT payload need to be re-issued?