> ## Documentation Index
> Fetch the complete documentation index at: https://alliancebioversityciat-alliance-risk-analysis-tool.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Login

> Authenticates a user with email and password

Authenticates a user with email and password. Returns Cognito access/id/refresh tokens on success, or a `NEW_PASSWORD_REQUIRED` challenge on first login when an admin has created the account with a temporary password.

## Authentication

This is a public endpoint that does not require authentication.

## Rate Limiting

This endpoint is rate-limited to **5 requests per minute** per IP address.

## Request Body

**email** `string` *required*

User email address (case-insensitive, will be lowercased automatically)

Must be a valid email format.

**Example:** `user@example.com`

**password** `string` *required*

User password

Must be at least 8 characters long.

**Example:** `MyP@ssw0rd!`

## Request Example

```bash theme={null}
curl -X POST https://api.example.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "MyP@ssw0rd!"
  }'
```

## Response

### Success Response (200 OK)

The response varies depending on whether this is a first-time login:

#### Standard Login Success

**accessToken** `string`

Cognito JWT access token used for API authentication

Pass this token in the `Authorization: Bearer <token>` header for authenticated requests.

**refreshToken** `string`

Cognito refresh token used to obtain new access tokens

Use this with the `/api/auth/refresh-token` endpoint when the access token expires.

**expiresIn** `number`

Token expiration time in seconds

Typically 3600 (1 hour).

**requiresPasswordChange** `boolean`

Indicates whether a password change is required

Will be `false` for standard login success.

```json theme={null}
{
  "accessToken": "eyJraWQiOiJxYz...",
  "refreshToken": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ...",
  "expiresIn": 3600,
  "requiresPasswordChange": false
}
```

#### First-Time Login (Password Change Required)

When an admin creates a user account with a temporary password, the first login returns a challenge:

**requiresPasswordChange** `boolean`

Set to `true` to indicate password change is required

**session** `string`

Session token for completing the password change challenge

Must be provided to the `/api/auth/complete-password-change` endpoint.

**username** `string`

Username (email) of the account

```json theme={null}
{
  "requiresPasswordChange": true,
  "session": "AYABeD...",
  "username": "user@example.com"
}
```

## Error Responses

**400 Bad Request**

**Validation error** — Invalid email format or password too short

```json theme={null}
{
  "statusCode": 400,
  "message": ["email must be an email", "password must be longer than or equal to 8 characters"],
  "error": "Bad Request"
}
```

**401 Unauthorized**

**Invalid credentials** — Email or password is incorrect

The response is intentionally generic to prevent user enumeration attacks.

```json theme={null}
{
  "statusCode": 401,
  "message": "Invalid credentials",
  "error": "Unauthorized"
}
```

**429 Too Many Requests**

**Rate limit exceeded** — More than 5 requests in 1 minute

```json theme={null}
{
  "statusCode": 429,
  "message": "Too many requests",
  "error": "Too Many Requests"
}
```

## Notes

* Email addresses are automatically lowercased and trimmed for consistency
* The endpoint returns generic error messages on authentication failure to prevent user enumeration
* Access tokens are JWTs that expire after 1 hour (3600 seconds)
* Refresh tokens are long-lived and can be used to obtain new access tokens without re-entering credentials
* On first login with a temporary password, you must complete the password change flow using `/api/auth/complete-password-change`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.