Email & Password
Email and password is the foundational authentication method in YorAuth. Users register with a name, email address, and password. After verifying their email, they can log in to receive a JWT access token and refresh token.
Register a User
Create a new user account for your application.
Endpoint: POST /api/v1/applications/{applicationId}/users/register
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Valid email address. Must be unique within the application. |
password | string | Yes | Must meet password strength requirements. |
name | string | Yes | Display name, up to 255 characters. |
metadata | object | No | Arbitrary JSON object for custom user data. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/register \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "Str0ng!Passw0rd",
"name": "Jane Doe",
"metadata": {
"plan": "starter",
"referral_code": "FRIEND10"
}
}'
const response = await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/users/register',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'jane@example.com',
password: 'Str0ng!Passw0rd',
name: 'Jane Doe',
metadata: { plan: 'starter' }
})
}
);
const data = await response.json();
Response 201 Created
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane@example.com",
"name": "Jane Doe",
"email_verified": false,
"created_at": "2026-02-25T10:00:00Z",
"metadata": {
"plan": "starter",
"referral_code": "FRIEND10"
}
},
"message": "Registration successful. Please check your email to verify your account."
}
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_MULTIPLE_ERRORS | Multiple field validation failures |
| 400 | VALIDATION_INVALID_FORMAT | Single field validation failure (e.g. invalid email format) |
| 409 | Inline message | Email already registered for this application |
| 422 | VALIDATION_PASSWORD_TOO_WEAK | Password does not meet requirements |
| 403 | tier_limit_exceeded | Application has reached its user limit |
After registration, a verification email is sent automatically. Users can log in before verifying their email, but your application may choose to enforce verification before granting access. Use the email verification endpoints to manage this.
Log In
Authenticate an existing user with their email and password.
Endpoint: POST /api/v1/applications/{applicationId}/users/login
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The user's email address. |
password | string | Yes | The user's password. |
remember_me | boolean | No | If true, the refresh token expires in 30 days instead of 7. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/login \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "Str0ng!Passw0rd",
"remember_me": false
}'
const response = await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/users/login',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'jane@example.com',
password: 'Str0ng!Passw0rd',
remember_me: false
})
}
);
const data = await response.json();
Response 200 OK — Successful Login
{
"data": {
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "ref_a1b2c3d4e5f6...",
"token_type": "Bearer",
"expires_in": 900,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane@example.com",
"name": "Jane Doe",
"email_verified": true,
"created_at": "2026-02-25T10:00:00Z",
"metadata": null
}
}
}
Response 200 OK — MFA Required
If the user has TOTP MFA enabled, login does not immediately return tokens. Instead, it returns a challenge token:
{
"data": {
"mfa_required": true,
"challenge_token": "mfa_challenge_xyz789abc",
"mfa_methods": ["totp"]
}
}
Pass the challenge_token and the user's TOTP code to the MFA verification endpoint to complete login. See Multi-Factor Authentication for details.
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 401 | AUTH_INVALID_CREDENTIALS | Email or password is incorrect. |
| 403 | AUTH_ACCOUNT_SUSPENDED | The account has been suspended. |
| 429 | AUTH_ACCOUNT_LOCKED | Too many failed attempts — account locked for 15 minutes. |
After 5 consecutive failed login attempts for the same email, the account is locked for 15 minutes. This is enforced per email address per application, not per IP address.
Log Out
Revoke the current session's refresh token. The access token remains valid until it expires (up to 15 minutes), but the refresh token is immediately invalidated so no new access tokens can be issued.
Endpoint: POST /api/v1/applications/{applicationId}/users/logout
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
refresh_token | string | Yes | The refresh token to revoke. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/logout \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{
"refresh_token": "ref_a1b2c3d4e5f6..."
}'
await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/users/logout',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify({ refresh_token: refreshToken })
}
);
Response 204 No Content
No body is returned on successful logout.
Change Password
Allow an authenticated user to update their own password. Requires the current password for verification.
Endpoint: POST /api/v1/applications/{applicationId}/users/{userId}/change-password
Authentication: JWT Bearer token required. The authenticated user must own the {userId} in the path.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
current_password | string | Yes | The user's existing password. |
new_password | string | Yes | The new password. Must meet strength requirements. |
new_password_confirmation | string | Yes | Must match new_password. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/change-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{
"current_password": "Str0ng!Passw0rd",
"new_password": "Even$tronger2026",
"new_password_confirmation": "Even$tronger2026"
}'
await fetch(
`https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/change-password`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify({
current_password: 'Str0ng!Passw0rd',
new_password: 'Even$tronger2026',
new_password_confirmation: 'Even$tronger2026'
})
}
);
Response 200 OK
{
"data": {
"message": "Password changed successfully."
}
}
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 422 | INVALID_PASSWORD | Current password is incorrect. |
| 400 | VALIDATION_MULTIPLE_ERRORS | Validation failures (e.g. passwords don't match). |
Forgot Password
Send a password reset email. Returns success regardless of whether the email exists to prevent email enumeration.
Endpoint: POST /api/v1/applications/{applicationId}/users/password/forgot
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The email address to send the reset link to. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/password/forgot \
-H "Content-Type: application/json" \
-d '{"email": "jane@example.com"}'
await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/users/password/forgot',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'jane@example.com' })
}
);
Response 200 OK
{
"data": {
"message": "If an account with that email exists, a password reset link has been sent."
}
}
| HTTP Status | Error Code | Description |
|---|---|---|
| 429 | AUTH_PASSWORD_RESET_RATE_LIMITED | More than 3 reset requests in 15 minutes for this email. |
Reset Password
Complete a password reset using the token from the reset email.
Endpoint: POST /api/v1/applications/{applicationId}/users/password/reset
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The reset token from the email link. |
email | string | Yes | The user's email address. |
password | string | Yes | The new password. Must meet strength requirements. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/password/reset \
-H "Content-Type: application/json" \
-d '{
"token": "abc123def456...",
"email": "jane@example.com",
"password": "NewStr0ng!Pass"
}'
await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/users/password/reset',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: 'abc123def456...',
email: 'jane@example.com',
password: 'NewStr0ng!Pass'
})
}
);
Response 200 OK
{
"data": {
"message": "Your password has been reset successfully."
}
}
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | AUTH_INVALID_RESET_TOKEN | Token does not match the email or was already used. |
| 410 | AUTH_RESET_TOKEN_EXPIRED | Token has expired. Request a new reset link. |
Email Verification
Verify Email Address
Endpoint: POST /api/v1/applications/{applicationId}/users/email/verify
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The verification token from the email link. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/email/verify \
-H "Content-Type: application/json" \
-d '{"token": "verify_token_here"}'
Response 200 OK
{
"data": {
"message": "Email address verified successfully."
}
}
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | AUTH_INVALID_VERIFICATION_TOKEN | Token is invalid or already used. |
| 410 | AUTH_VERIFICATION_TOKEN_EXPIRED | Token has expired. |
Resend Verification Email
Endpoint: POST /api/v1/applications/{applicationId}/users/email/resend
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The user's email address. |
curl -X POST https://api.yorauth.com/api/v1/applications/your-application-id/users/email/resend \
-H "Content-Type: application/json" \
-d '{"email": "jane@example.com"}'
Response 200 OK
{
"data": {
"message": "If an account with that email exists and is not verified, a verification email has been sent."
}
}
| HTTP Status | Error Code | Description |
|---|---|---|
| 429 | AUTH_VERIFICATION_RATE_LIMITED | More than 2 resend requests per minute for this email. |