Skip to content

Auth API

POST /auth/register

Register a new user.

Body

json
{
  "email": "user@example.com",
  "password": "min6chars",
  "name": "John Doe",
  "role": "tenant"
}
  • role accepts tenant (default) or landlord
  • Sends a welcome/verification email with a 24h token link
  • User can browse immediately (JWT issued), but email is unverified

Response (201)

json
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "John Doe",
    "role": "tenant"
  },
  "emailVerificationSent": true
}

Sets httpOnly token cookie.

POST /auth/login

Body

json
{
  "email": "user@example.com",
  "password": "password123"
}

Response (200)

json
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "John Doe",
    "role": "tenant"
  }
}

Sets httpOnly token cookie (7-day expiry).

POST /auth/logout

Clears the token cookie.

Response (200)

json
{
  "success": true
}

GET /auth/me

Get current authenticated user. Requires auth.

Response (200)

json
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "John Doe",
    "role": "tenant",
    "phone": "514-555-0123",
    "avatarUrl": null,
    "createdAt": "2026-02-28T00:00:00.000Z"
  }
}

Returns { "user": null } if not authenticated (no 401 error).

PUT /auth/profile

Update user profile. Requires auth.

Body

json
{
  "name": "Jane Doe",
  "phone": "514-555-0456"
}

Both fields are optional. Send only what you want to update.

Response (200)

json
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "Jane Doe",
    "role": "tenant",
    "phone": "514-555-0456",
    "avatarUrl": null
  }
}

PUT /auth/password

Change password. Requires auth.

Body

json
{
  "currentPassword": "oldpassword",
  "newPassword": "newpassword123"
}
  • newPassword must be at least 6 characters

Response (200)

json
{
  "success": true
}
  • Sends a password-changed notification email

Errors

  • 400 — "Current password is incorrect"

POST /auth/verify-email

Verify email address using a token from the welcome email.

Body

json
{
  "token": "hex-token-from-email-link"
}

Response (200)

json
{
  "success": true
}

Errors

  • 400 — "Invalid token", "Token already used", "Token expired"

POST /auth/resend-verification

Resend the email verification link. Requires auth. Rate limited: 1 per 5 minutes.

Response (200)

json
{
  "success": true
}

Errors

  • 400 — "Email already verified"
  • 429 — "Verification email recently sent"

POST /auth/forgot-password

Request a password reset email. Always returns 200 to prevent email enumeration. Rate limited: 3 per hour per email.

Body

json
{
  "email": "user@example.com"
}

Response (200)

json
{
  "success": true,
  "message": "If an account exists with that email, a reset link has been sent."
}

POST /auth/reset-password

Reset password using a token from the forgot-password email. Token expires after 30 minutes.

Body

json
{
  "token": "hex-token-from-email-link",
  "password": "newpassword123"
}
  • password must be at least 6 characters
  • Sends a password-changed notification email on success

Response (200)

json
{
  "success": true
}

Errors

  • 400 — "Invalid token", "Token already used", "Token expired"