Skip to main content

Endpoint

method
string
required
POST
url
string
required
/auth/refresh

Request

Headers

Content-Type
string
required
application/json

Body Parameters

refreshToken
string
required
The refresh token received during login or registrationMust be a 128-character hexadecimal string

Example Request

cURL
curl -X POST https://api.ceboelha.com/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678"
  }'
JavaScript
const response = await fetch('https://api.ceboelha.com/auth/refresh', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  credentials: 'include', // Important: include cookies
  body: JSON.stringify({
    refreshToken: 'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678'
  })
});

const data = await response.json();
Python
import requests

response = requests.post(
    'https://api.ceboelha.com/auth/refresh',
    json={
        'refreshToken': 'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678'
    }
)

data = response.json()

Response

Success Response (200)

success
boolean
required
Always true for successful requests
data
object
required
data.expiresIn
number
Seconds until the new access token expires (typically 900 = 15 minutes)
message
string
required
Success message: “Token renovado com sucesso”

Response Cookies

The following HttpOnly cookies are automatically set with NEW values:
  • accessToken: New JWT access token (expires in 15 minutes)
  • refreshToken: New JWT refresh token (expires in 7 days)
Important: The old refresh token is automatically revoked and cannot be reused.

Example Success Response

{
  "success": true,
  "data": {
    "expiresIn": 900
  },
  "message": "Token renovado com sucesso"
}

Error Responses

Invalid Refresh Token (401)

{
  "success": false,
  "error": "Unauthorized",
  "code": "UNAUTHORIZED",
  "message": "Token de refresh inválido"
}

Expired or Revoked Token (401)

{
  "success": false,
  "error": "Unauthorized",
  "code": "UNAUTHORIZED",
  "message": "Token de refresh expirado ou revogado"
}

User Not Found (401)

{
  "success": false,
  "error": "Unauthorized",
  "code": "UNAUTHORIZED",
  "message": "Usuário não encontrado ou inativo"
}

Validation Error (400)

{
  "success": false,
  "error": "Validation failed",
  "code": "VALIDATION_ERROR",
  "message": "Token de refresh inválido"
}

Rate Limit Exceeded (429)

{
  "success": false,
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT",
  "message": "Muitas requisições. Tente novamente mais tarde."
}

Token Rotation Security

This endpoint implements automatic token rotation for enhanced security:
  1. Old Token Revoked: When you use a refresh token, it’s immediately revoked
  2. New Tokens Issued: Both a new access token AND a new refresh token are generated
  3. One-Time Use: Each refresh token can only be used once
  4. Theft Detection: If a revoked token is reused, ALL tokens for that user are revoked as a security measure

Why Token Rotation?

Token rotation prevents token theft attacks:
  • If an attacker steals a refresh token, they can only use it once
  • When the legitimate user tries to refresh, the system detects token reuse
  • All tokens are revoked, forcing the attacker out and alerting the user

When to Refresh

You should refresh the access token:
  • Before it expires: Check the expiresIn value from login/register
  • When receiving 401 errors: If your access token has expired
  • Proactively: Refresh 1-2 minutes before expiration to avoid interruptions

Example: Automatic Token Refresh

JavaScript
let accessTokenExpiry = null;

// After login/register, store the expiry time
function handleAuthResponse(data) {
  accessTokenExpiry = Date.now() + (data.expiresIn * 1000);
}

// Check if token needs refresh before each request
async function makeAuthenticatedRequest(url, options) {
  // Refresh if token expires in less than 2 minutes
  if (accessTokenExpiry && Date.now() > accessTokenExpiry - 120000) {
    const refreshResponse = await fetch('/auth/refresh', {
      method: 'POST',
      credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refreshToken: getRefreshToken() })
    });
    
    const refreshData = await refreshResponse.json();
    handleAuthResponse(refreshData);
  }
  
  // Now make the actual request
  return fetch(url, {
    ...options,
    credentials: 'include'
  });
}

Notes

  • Rate Limit: 5 requests per 15 minutes per IP
  • Token Format: Refresh tokens are 128-character hexadecimal strings
  • Token Storage: Tokens are stored hashed in the database for security
  • Device Tracking: Each refresh maintains the device session information
  • Automatic Cleanup: Expired tokens are automatically cleaned up from the database

Build docs developers (and LLMs) love