Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Glemynart/SaaS/llms.txt

Use this file to discover all available pages before exploring further.

When an access token expires, the client can obtain a fresh token pair without asking the user to log in again by presenting a valid refresh token to this endpoint. The platform implements refresh token rotation: every successful call to /auth/refresh immediately revokes the presented token and issues a new refresh token. This means each refresh token can only be used once. If the server detects that a token which was already revoked is being presented again, it interprets this as a potential token-theft replay attack and revokes all active refresh tokens for that user, terminating every session.

POST /auth/refresh

POST /auth/refresh
No authentication required. Returns 200 OK on success.

Request body

refreshToken
string
required
The opaque refresh token string received from a previous call to POST /auth/login or POST /auth/refresh. Encoded as base64(tokenId:secret). Single-use — presenting it here invalidates it immediately.

Response

A 200 OK response with a new token pair:
accessToken
string
A freshly signed JWT valid for 15 minutes. Replace the previous access token in memory.
refreshToken
string
A new opaque refresh token valid for 7 days. Replace the previous refresh token in storage. The old refresh token is permanently invalidated.

Example request

curl -X POST https://api.oficina-nitida.com/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "YjdlMWYzYTItNWM2ZC00ZTdmLTlhMGItMWMyZDNlNGY1YTZiOnNlY3JldA=="
  }'

Example response

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "ZjRkMmE1YjMtNmQ3ZS01ZjhmLTBiMWMtMmQzZTVmNmE3YjhjOnNlY3JldDI="
}

Token rotation security model

The refresh token lifecycle enforces the following invariants:
  1. Single-use: a token is marked revokedAt the moment it is successfully consumed. A second attempt with the same token yields 401.
  2. Replay detection: if a token that already has a revokedAt timestamp is presented, the server revokes all refresh tokens for that userId. This terminates every active session for the account and forces the user to log in again on all devices.
  3. Expiry: tokens that have passed their expiresAt date (7 days after issuance) are rejected even if they have not been explicitly revoked.
  4. User and tenant liveness checks: the refresh succeeds only if both the user (activo: true) and the tenant (activo: true) are currently active.
Rate limit: 10 requests per minute per IP address.

Error cases

StatusCause
401 UnauthorizedThe token string is malformed (not valid base64, or does not contain the expected tokenId:secret format); the token ID does not exist in the database; the token has already been revoked; or the token has expired. In the revoked-token case, all sessions for the user are additionally terminated.

POST /auth/logout

POST /auth/logout
No authentication required. Returns 200 OK on success. Invalidates a specific refresh token server-side, ending the associated session. The client should also discard the access token from memory. This endpoint accepts the same refreshToken field as /auth/refresh.

Request body

refreshToken
string
required
The refresh token to invalidate. The corresponding database row is updated with revokedAt: now(), preventing future use.

Example request

curl -X POST https://api.oficina-nitida.com/auth/logout \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "YjdlMWYzYTItNWM2ZC00ZTdmLTlhMGItMWMyZDNlNGY1YTZiOnNlY3JldA=="
  }'

Example response

{
  "message": "Sesión cerrada exitosamente."
}
Logout errors are handled silently on the server — if the token cannot be found or is already revoked, the endpoint still returns 200 OK. This prevents information leakage and makes logout safe to call idempotently (e.g. on app teardown or tab close).

Build docs developers (and LLMs) love