# POST /auth/login

> Authenticate with email and password

Authenticate existing users with **email and password** (password required). Returns a JWT for subsequent authenticated requests.

  **Password sign-in:** For passwordless (no password field), use [OTP Send](/reference/authentication/otp-send) + [OTP Verify](/reference/authentication/otp-verify) instead.

  **Email verification:** If your project requires email verification, users must verify their email before logging in. Otherwise they receive `emailNotVerified: true` with status 403.

## Endpoint

```http
POST /v1/public/projects/:projectSlug/auth/login
```

## Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `email` | string | ✅ | User's email address |
| `password` | string | ✅ | User's password |
| `turnstileToken` | string | ❌ | Turnstile token for captcha (if project uses it) |

### Example Request Body

```json
{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}
```

## Response

### Success (200 OK)

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "user-uuid-here",
    "email": "user@example.com",
    "name": "Jane Doe"
  }
}
```

Store the `token` and send it in `Authorization: Bearer <token>` for protected endpoints like [GET /auth/me](/reference/authentication/me).

### Error Responses

| Status Code | Description |
|-------------|-------------|
| 400 | Validation failed (invalid email/password format) |
| 401 | Invalid email or password |
| 403 | Account locked (too many failed attempts) or email not verified |
| 429 | Too many login attempts (rate limited) |

## Related Endpoints

- [POST /auth/register](/reference/authentication/register) - Create account
- [POST /auth/otp/send](/reference/authentication/otp-send) - Passwordless login
- [GET /auth/me](/reference/authentication/me) - Get current user
