Skip to main content
POST
/
api
/
v1
/
auth
/
refresh
Refresh Token
curl --request POST \
  --url https://api.example.com/api/v1/auth/refresh \
  --header 'Content-Type: application/json' \
  --data '
{
  "refresh_token": "<string>"
}
'
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJlbWFpbCI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImlzX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDk3MzU3NDV9.new...",
  "refresh_token": null,
  "token_type": "bearer",
  "expires_in": 900
}
This endpoint is currently under development and not yet available in production.

Endpoint

POST /api/v1/auth/refresh
Exchanges a valid refresh token for a new access token. Use this endpoint when your access token expires to maintain user sessions without requiring re-authentication.

Request Body

refresh_token
string
required
Valid refresh token obtained from the login endpoint.The refresh token must:
  • Be issued by the Soft-Bee API
  • Not be expired
  • Not be revoked or blacklisted
  • Belong to an active user account
Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response

access_token
string
New JWT access token for authenticating API requests.Use this token in the Authorization header: Authorization: Bearer {access_token}
refresh_token
string | null
New refresh token (optional).May be null if the system doesn’t rotate refresh tokens. If provided, store this new refresh token and discard the old one.
token_type
string
Token type for the Authorization header.Value: "bearer"
expires_in
integer
Access token expiration time in seconds.Default: Depends on the original login remember_me setting

Example Request

cURL
curl -X POST https://api.softbee.com/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJleHAiOjE3MTIyMzk2NDV9.abc..."
  }'
Python
import requests

url = "https://api.softbee.com/api/v1/auth/refresh"
payload = {
    "refresh_token": stored_refresh_token  # Retrieved from secure storage
}

response = requests.post(url, json=payload)

if response.status_code == 200:
    data = response.json()
    # Update stored access token
    access_token = data['access_token']
    
    # Update refresh token if rotated
    if data.get('refresh_token'):
        refresh_token = data['refresh_token']
    
    print("Token refreshed successfully")
else:
    print("Refresh failed, user needs to log in again")
JavaScript
fetch('https://api.softbee.com/api/v1/auth/refresh', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    refresh_token: localStorage.getItem('refresh_token')
  })
})
.then(response => {
  if (!response.ok) {
    throw new Error('Token refresh failed');
  }
  return response.json();
})
.then(data => {
  // Update stored tokens
  localStorage.setItem('access_token', data.access_token);
  if (data.refresh_token) {
    localStorage.setItem('refresh_token', data.refresh_token);
  }
  console.log('Token refreshed successfully');
})
.catch(error => {
  console.error('Refresh failed:', error);
  // Redirect to login page
  window.location.href = '/login';
});

Example Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJlbWFpbCI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwidXNlcm5hbWUiOiJqb2huX2RvZSIsImlzX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDk3MzU3NDV9.new...",
  "refresh_token": null,
  "token_type": "bearer",
  "expires_in": 900
}

Error Responses

{
  "error": "refresh_token is required"
}

Token Rotation

Depending on the API configuration, the system may implement refresh token rotation for enhanced security.

Without Rotation

  • Same refresh token can be used multiple times
  • refresh_token field in response will be null
  • Original refresh token remains valid

With Rotation

  • Each refresh generates a new refresh token
  • refresh_token field contains the new token
  • Old refresh token is immediately invalidated
  • Always use the most recent refresh token

Best Practices

Token Storage

  • Mobile Apps: Use secure storage (Keychain/KeyStore)
  • Web Apps: Use httpOnly cookies or secure session storage
  • Never store tokens in:
    • LocalStorage (vulnerable to XSS)
    • URL parameters
    • Plain text files
    • Version control

Refresh Strategy

  1. Proactive Refresh: Refresh before token expires
    // Refresh 5 minutes before expiration
    const refreshTime = (expires_in - 300) * 1000;
    setTimeout(refreshToken, refreshTime);
    
  2. Reactive Refresh: Refresh on 401 response
    // Intercept 401 responses and retry with new token
    if (response.status === 401) {
      await refreshToken();
      return retryRequest(originalRequest);
    }
    
  3. Silent Refresh: Refresh in background without user interaction

Error Handling

When refresh fails:
  1. Clear all stored tokens
  2. Redirect user to login page
  3. Optional: Show session expired message
  4. Preserve intended destination for post-login redirect

Implementation Status

Current Status: Under DevelopmentThis endpoint is currently commented out in the source code. Expected features when released:
  • JWT refresh token validation
  • Optional token rotation
  • Refresh token blacklisting
  • Rate limiting on refresh attempts

Login

Get initial access and refresh tokens

Logout

Invalidate refresh token and end session

Build docs developers (and LLMs) love