Skip to content

Token Refresh Flow

The Token Refresh flow allows you to obtain new access tokens without re-authenticating.

Overview

When you authenticate with QLAM, you receive both an access token and a refresh token:

  • Access token: Short-lived (24 hours), used for API requests
  • Refresh token: Longer-lived (15 days), used only to get new access tokens
sequenceDiagram
    participant App as Application
    participant IdP as Identity Provider

    Note over App: Access token expired
    App->>IdP: Refresh token request
    IdP->>App: New access token + New refresh token
    Note over App: Continue API calls

When to Refresh

Refresh your token when:

  • The access token has expired (API returns 401)
  • The access token is near expiration (proactive refresh)

Rate Limiting

The refresh endpoint has rate limits. Only refresh when the token is near or past expiration—not on every API call.

Refresh Request

curl --request POST \
  --url "https://{auth_base_url}/oauth/token" \
  --header "content-type: application/x-www-form-urlencoded" \
  --data grant_type=refresh_token \
  --data "client_id={client_id}" \
  --data "refresh_token={refresh_token}"

Parameters:

Parameter Description
grant_type Always refresh_token
client_id Your OAuth2 client ID
refresh_token The refresh token from initial authentication

Response

Successful response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 86400,
  "refresh_token": "v1.MSjO...new",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "scope": "openid profile email offline_access"
}

Refresh Token Rotation

For security, refresh token rotation is enabled. Each refresh request returns a new refresh token, and the previous one is invalidated.

You must use the new refresh token for subsequent refresh requests. Using an old refresh token will fail.

Error Handling

Invalid Refresh Token

{
  "error": "invalid_grant",
  "error_description": "Unknown or invalid refresh token."
}

This occurs when:

  • The refresh token has expired (after 15 days)
  • The refresh token has already been used (rotation)
  • The refresh token was revoked

Resolution: Re-authenticate using Authorization Code or Device Code flow.

Rate Limited

{
  "error": "too_many_requests",
  "error_description": "Rate limit exceeded"
}

Resolution: Wait before retrying. Consider caching access tokens and only refreshing when near expiration.

Best Practices

  1. Store both tokens: After every refresh, save the new access token AND refresh token

  2. Refresh proactively: Refresh before the token expires to avoid failed API calls

  3. Handle failures gracefully: If refresh fails, fall back to full re-authentication

  4. Implement retry with backoff: For rate limit errors, use exponential backoff

  5. Secure token storage: Treat refresh tokens as sensitive credentials

Next Steps