> ## 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.

# User Login

> Authenticate users with username and password to get access and refresh tokens

# User Login

Authenticate users with their username and password to receive access and refresh tokens for Console API access.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://api.weir.ai/auth/login' \
    -H 'Content-Type: application/json' \
    -d '{
      "username": "Jane Doe",
      "password": "securePassword123"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "data": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
      "refreshToken": "refresh_token_123456789",
      "expiresIn": 3600,
      "user": {
        "id": "user_123456789",
        "fullname": "Jane Doe",
        "email": "jane@example.com",
        "role": "Organization_Admin"
      }
    },
    "message": "Login successful",
    "status": "success"
  }
  ```
</ResponseExample>

## Authentication

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

## Request Body

<ParamField body="username" type="string" required>
  The user's username or email address for authentication.
</ParamField>

<ParamField body="password" type="string" required>
  The user's password for authentication.
</ParamField>

## Response Fields

<ResponseField name="data" type="object" required>
  Authentication data object containing tokens and user information.

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

    <ResponseField name="data.refreshToken" type="string" required>
      Refresh token used to obtain new access tokens when they expire.
    </ResponseField>

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

    <ResponseField name="data.user" type="object" required>
      User information object.

      <Expandable title="User Properties">
        <ResponseField name="data.user.id" type="string" required>
          Unique identifier for the user.
        </ResponseField>

        <ResponseField name="data.user.fullname" type="string" required>
          User's full name.
        </ResponseField>

        <ResponseField name="data.user.email" type="string" required>
          User's email address.
        </ResponseField>

        <ResponseField name="data.user.role" type="string" required>
          User's role within the organization (e.g., "Organization\_Admin", "Organization\_User").
        </ResponseField>
      </Expandable>
    </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 login.
</ResponseField>

## Error Responses

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

    **Causes**:

    * Missing username or password
    * Invalid request format
  </Accordion>

  <Accordion title="401 Unauthorized" icon="ban">
    ```json theme={null}
    {
      "error": {
        "code": "INVALID_CREDENTIALS",
        "message": "Invalid username or password",
        "details": "The provided credentials are incorrect"
      },
      "status": "error"
    }
    ```

    **Causes**:

    * Incorrect username or password
    * User account not found
    * Account is disabled
  </Accordion>

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

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

## Usage Examples

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

  // Usage
  const loginData = await login('jane.doe@example.com', 'securePassword123');
  console.log('User:', loginData.data.user);
  ```

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

  def login(username, password):
      try:
          response = requests.post(
              'https://api.weir.ai/auth/login',
              json={'username': username, 'password': password}
          )
          response.raise_for_status()
          
          data = response.json()
          
          # Store tokens securely
          access_token = data['data']['accessToken']
          refresh_token = data['data']['refreshToken']
          
          return data
      except requests.exceptions.RequestException as e:
          print(f'Login error: {e}')
          raise

  # Usage
  login_data = login('jane.doe@example.com', 'securePassword123')
  print(f'User: {login_data["data"]["user"]}')
  ```

  ```php PHP theme={null}
  function login($username, $password) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, 'https://api.weir.ai/auth/login');
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
      curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
          'username' => $username,
          'password' => $password
      ]));
      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);
      
      // Store tokens securely
      $_SESSION['accessToken'] = $data['data']['accessToken'];
      $_SESSION['refreshToken'] = $data['data']['refreshToken'];
      
      return $data;
  }

  // Usage
  $loginData = login('jane.doe@example.com', 'securePassword123');
  echo "User: " . json_encode($loginData['data']['user']);
  ```
</CodeGroup>

## Rate Limits

* **Rate Limit**: 5 requests per minute per IP address
* **Burst Limit**: 10 requests per 5-minute window

## Security Considerations

<Warning>
  **Important**: Never store passwords in plain text or expose them in client-side code. Always use secure password transmission and storage mechanisms.
</Warning>

<AccordionGroup>
  <Accordion title="Password Security" icon="lock">
    * Use strong passwords with minimum complexity requirements
    * Implement password hashing on the server side
    * Never log or expose passwords in error messages
    * Use HTTPS for all login requests
  </Accordion>

  <Accordion title="Token Security" icon="shield">
    * Store access and refresh tokens securely
    * Implement automatic token refresh before expiration
    * Use secure storage mechanisms (not localStorage for sensitive apps)
    * Implement proper logout functionality to invalidate tokens
  </Accordion>

  <Accordion title="Rate Limiting" icon="clock">
    * Implement rate limiting to prevent brute force attacks
    * Consider implementing account lockout after failed attempts
    * Monitor for suspicious login patterns
    * Use CAPTCHA for repeated failed attempts
  </Accordion>
</AccordionGroup>

## Best Practices

<Steps>
  <Step title="Secure Token Storage" icon="database">
    Store tokens securely using appropriate storage mechanisms for your application type.
  </Step>

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

  <Step title="Handle Errors Gracefully" icon="exclamation-triangle">
    Implement proper error handling for authentication failures and network issues.
  </Step>

  <Step title="Implement Logout" icon="sign-out-alt">
    Provide logout functionality to properly invalidate tokens and clear user session.
  </Step>
</Steps>

<Tip>
  **Pro Tip**: Implement a token manager class that handles login, token storage, automatic refresh, and logout to simplify your authentication flow.
</Tip>
