Login
Authenticate a user and obtain access and refresh tokens.
Request
POST /api/v1/auth/login
Authentication
Public - No authentication required.
Request Body
{
"organizationSlug": "acme-corporation",
"email": "[email protected]",
"password": "SecurePass123!"
}
| Name | Type | Required | Description |
|---|---|---|---|
| organizationSlug | string | Yes | URL-friendly organization identifier |
| string | Yes | User's email address | |
| password | string | Yes | User's password |
Response
Success Response (200 OK)
Standard Login (No MFA, Password Valid)
{
"mfaRequired": false,
"mfaChallengeToken": null,
"mfaChallengeExpiresIn": null,
"passwordExpired": false,
"passwordChangeToken": null,
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"expiresIn": 3600,
"tokenType": "Bearer",
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "[email protected]",
"name": "John Doe",
"isOrgAdmin": true,
"organizationId": "223e4567-e89b-12d3-a456-426614174001",
"organizationName": "Acme Corporation",
"organizationSlug": "acme-corporation",
"subscriptionTier": "BUSINESS",
"mfaEnabled": false
}
}
MFA Required Response
{
"mfaRequired": true,
"mfaChallengeToken": "mfa_challenge_abc123xyz",
"mfaChallengeExpiresIn": 300,
"passwordExpired": false,
"passwordChangeToken": null,
"accessToken": null,
"refreshToken": null,
"expiresIn": null,
"tokenType": null,
"user": null
}
When mfaRequired is true, you must call POST /api/v1/auth/verify-mfa with the mfaChallengeToken and the user's MFA code.
Password Expired Response
{
"mfaRequired": false,
"mfaChallengeToken": null,
"mfaChallengeExpiresIn": null,
"passwordExpired": true,
"passwordChangeToken": "pwd_change_def456uvw",
"accessToken": null,
"refreshToken": null,
"expiresIn": null,
"tokenType": null,
"user": null
}
When passwordExpired is true, you must call POST /api/v1/auth/change-expired-password with the passwordChangeToken and a new password.
Response Fields
| Field | Type | Description |
|---|---|---|
| mfaRequired | boolean | Whether MFA verification is required |
| mfaChallengeToken | string | Token for MFA verification (present if mfaRequired is true) |
| mfaChallengeExpiresIn | number | MFA challenge token expiration in seconds |
| passwordExpired | boolean | Whether the password has expired per organization policy |
| passwordChangeToken | string | Token for password change (present if passwordExpired is true) |
| accessToken | string | JWT access token (present if login is complete) |
| refreshToken | string | Refresh token (present if login is complete) |
| expiresIn | number | Access token expiration time in seconds |
| tokenType | string | Token type (always "Bearer") |
| user | object | User information object (present if login is complete) |
Error Responses
| Status Code | Description |
|---|---|
| 400 Bad Request | Invalid request body (missing required fields) |
| 401 Unauthorized | Invalid credentials (wrong email/password or organization not found) |
| 403 Forbidden | User account is suspended or organization is suspended |
| 429 Too Many Requests | Rate limit exceeded |
| 500 Internal Server Error | Server error occurred |
Example
Standard Login
curl -X POST https://api.entryguard.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"organizationSlug": "acme-corporation",
"email": "[email protected]",
"password": "SecurePass123!"
}'
Example Response (Successful Login)
{
"mfaRequired": false,
"mfaChallengeToken": null,
"mfaChallengeExpiresIn": null,
"passwordExpired": false,
"passwordChangeToken": null,
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjNlNDU2Ny1lODliLTEyZDMtYTQ1Ni00MjY2MTQxNzQwMDAiLCJvcmdJZCI6IjIyM2U0NTY3LWU4OWItMTJkMy1hNDU2LTQyNjYxNDE3NDAwMSIsInJvbGVzIjpbIk9SR19BRE1JTiJdLCJpYXQiOjE3MDkwNDk2MDAsImV4cCI6MTcwOTA1MzIwMH0.xyz123",
"refreshToken": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"expiresIn": 3600,
"tokenType": "Bearer",
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "[email protected]",
"name": "John Doe",
"isOrgAdmin": true,
"organizationId": "223e4567-e89b-12d3-a456-426614174001",
"organizationName": "Acme Corporation",
"organizationSlug": "acme-corporation",
"subscriptionTier": "BUSINESS",
"mfaEnabled": false
}
}
Example Response (MFA Required)
{
"mfaRequired": true,
"mfaChallengeToken": "mfa_challenge_7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c",
"mfaChallengeExpiresIn": 300,
"passwordExpired": false,
"passwordChangeToken": null,
"accessToken": null,
"refreshToken": null,
"expiresIn": null,
"tokenType": null,
"user": null
}