> ## Documentation Index
> Fetch the complete documentation index at: https://doc-dev.weir.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Refresh Token

> Refresh expired access tokens using refresh tokens

# Refresh Token

Refresh expired access tokens using a valid refresh token to maintain uninterrupted API access.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://api.weir.ai/auth/refresh/token' \
    -H 'Content-Type: application/json' \
    -d '{
      "refreshToken": "refresh_token_123456789"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "data": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
      "refreshToken": "new_refresh_token_987654321",
      "expiresIn": 3600
    },
    "message": "Token refreshed successfully",
    "status": "success"
  }
  ```
</ResponseExample>

## Authentication

This endpoint does not require authentication as it's used to refresh expired tokens.

## Request Body

<ParamField body="refreshToken" type="string" required>
  The refresh token obtained from the login endpoint.
</ParamField>

## Response Fields

<ResponseField name="data" type="object" required>
  Token refresh data object containing new tokens.

  <Expandable title="Token Data Properties">
    <ResponseField name="data.accessToken" type="string" required>
      New JWT access token for authenticated API requests. Valid for 1 hour (3600 seconds).
    </ResponseField>

    <ResponseField name="data.refreshToken" type="string" required>
      New refresh token to use for future token refreshes. The old refresh token is invalidated.
    </ResponseField>

    <ResponseField name="data.expiresIn" type="integer" required>
      Access token expiration time in seconds. Always 3600 (1 hour) for access tokens.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable message describing the result of the operation.
</ResponseField>

<ResponseField name="status" type="string" required>
  Operation status. Always "success" for successful token refresh.
</ResponseField>

## Error Responses

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="exclamation-triangle">
    ```json theme={null}
    {
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Invalid request parameters",
        "details": {
          "refreshToken": "Refresh token is required"
        }
      },
      "status": "error"
    }
    ```

    **Causes**:

    * Missing refresh token
    * Invalid request format
  </Accordion>

  <Accordion title="401 Unauthorized" icon="ban">
    ```json theme={null}
    {
      "error": {
        "code": "INVALID_REFRESH_TOKEN",
        "message": "Invalid or expired refresh token",
        "details": "The provided refresh token is invalid or has expired"
      },
      "status": "error"
    }
    ```

    **Causes**:

    * Invalid refresh token
    * Expired refresh token
    * Already used refresh token
  </Accordion>

  <Accordion title="429 Too Many Requests" icon="clock">
    ```json theme={null}
    {
      "error": {
        "code": "RATE_LIMIT_EXCEEDED",
        "message": "Too many refresh requests",
        "details": "Rate limit of 20 refresh requests per minute exceeded"
      },
      "status": "error"
    }
    ```

    **Solution**: Wait for the rate limit window to reset before making another refresh request.
  </Accordion>
</AccordionGroup>

## Usage Examples

<CodeGroup>
  ```javascript JavaScript theme={null}
  const refreshToken = async (refreshTokenValue) => {
    try {
      const response = await fetch('https://api.weir.ai/auth/refresh/token', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ refreshToken: refreshTokenValue })
      });
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      
      const data = await response.json();
      
      // Update stored tokens
      localStorage.setItem('accessToken', data.data.accessToken);
      localStorage.setItem('refreshToken', data.data.refreshToken);
      
      return data;
    } catch (error) {
      console.error('Token refresh error:', error);
      throw error;
    }
  };

  // Usage
  const newTokens = await refreshToken('refresh_token_123456789');
  console.log('New access token:', newTokens.data.accessToken);
  ```

  ```python Python theme={null}
  import requests

  def refresh_token(refresh_token_value):
      try:
          response = requests.post(
              'https://api.weir.ai/auth/refresh/token',
              json={'refreshToken': refresh_token_value}
          )
          response.raise_for_status()
          
          data = response.json()
          
          # Update stored tokens
          access_token = data['data']['accessToken']
          new_refresh_token = data['data']['refreshToken']
          
          return data
      except requests.exceptions.RequestException as e:
          print(f'Token refresh error: {e}')
          raise

  # Usage
  new_tokens = refresh_token('refresh_token_123456789')
  print(f'New access token: {new_tokens["data"]["accessToken"]}')
  ```

  ```php PHP theme={null}
  function refreshToken($refreshTokenValue) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, 'https://api.weir.ai/auth/refresh/token');
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
      curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
          'refreshToken' => $refreshTokenValue
      ]));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      
      $response = curl_exec($ch);
      $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);
      
      if ($httpCode !== 200) {
          throw new Exception("HTTP error: $httpCode");
      }
      
      $data = json_decode($response, true);
      
      // Update stored tokens
      $_SESSION['accessToken'] = $data['data']['accessToken'];
      $_SESSION['refreshToken'] = $data['data']['refreshToken'];
      
      return $data;
  }

  // Usage
  $newTokens = refreshToken('refresh_token_123456789');
  echo "New access token: " . $newTokens['data']['accessToken'];
  ```
</CodeGroup>

## Token Management Best Practices

<AccordionGroup>
  <Accordion title="Automatic Refresh" icon="refresh">
    ```javascript theme={null}
    class TokenManager {
      constructor() {
        this.accessToken = localStorage.getItem('accessToken');
        this.refreshToken = localStorage.getItem('refreshToken');
        this.tokenExpiresAt = localStorage.getItem('tokenExpiresAt');
      }
      
      async makeRequest(url, options = {}) {
        // Check if token needs refresh (5 minutes before expiration)
        if (this.tokenExpiresAt && Date.now() >= this.tokenExpiresAt - 300000) {
          await this.refreshAccessToken();
        }
        
        return fetch(url, {
          ...options,
          headers: {
            'Authorization': `Bearer ${this.accessToken}`,
            'x-source': 'console',
            ...options.headers
          }
        });
      }
      
      async refreshAccessToken() {
        const data = await refreshToken(this.refreshToken);
        this.accessToken = data.data.accessToken;
        this.refreshToken = data.data.refreshToken;
        this.tokenExpiresAt = Date.now() + (data.data.expiresIn * 1000);
        
        // Update stored tokens
        localStorage.setItem('accessToken', this.accessToken);
        localStorage.setItem('refreshToken', this.refreshToken);
        localStorage.setItem('tokenExpiresAt', this.tokenExpiresAt);
      }
    }
    ```
  </Accordion>

  <Accordion title="Error Handling" icon="exclamation-triangle">
    ```javascript theme={null}
    async function handleTokenRefresh() {
      try {
        await refreshToken(currentRefreshToken);
        return true; // Success
      } catch (error) {
        if (error.message.includes('401') || error.message.includes('INVALID_REFRESH_TOKEN')) {
          // Refresh token is invalid, redirect to login
          localStorage.clear();
          window.location.href = '/login';
          return false;
        }
        throw error; // Re-throw other errors
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Rate Limits

* **Rate Limit**: 20 requests per minute per user
* **Burst Limit**: 50 requests per 5-minute window

## Security Considerations

<AccordionGroup>
  <Accordion title="Token Rotation" icon="refresh">
    * Refresh tokens are rotated on each use for enhanced security
    * Old refresh tokens become invalid immediately after use
    * Always store the new refresh token returned from this endpoint
  </Accordion>

  <Accordion title="Token Storage" icon="database">
    * Store refresh tokens securely with appropriate encryption
    * Use secure storage mechanisms (not localStorage for sensitive apps)
    * Implement proper token cleanup on logout
  </Accordion>

  <Accordion title="Network Security" icon="shield">
    * Always use HTTPS for token refresh requests
    * Implement proper error handling without exposing sensitive information
    * Monitor for suspicious refresh patterns
  </Accordion>
</AccordionGroup>

## Best Practices

<Steps>
  <Step title="Implement Auto-Refresh" icon="refresh">
    Set up automatic token refresh before expiration to ensure uninterrupted API access.
  </Step>

  <Step title="Handle Refresh Failures" icon="exclamation-triangle">
    Implement proper error handling for refresh token failures and redirect to login when needed.
  </Step>

  <Step title="Update Token Storage" icon="database">
    Always update stored tokens with the new values returned from the refresh endpoint.
  </Step>

  <Step title="Monitor Token Usage" icon="eye">
    Monitor token refresh patterns and implement alerts for suspicious activity.
  </Step>
</Steps>

<Tip>
  **Pro Tip**: Implement a token manager that automatically handles token refresh in the background, so your application code doesn't need to worry about token expiration.
</Tip>
