Skip to main content
Authenticate users with email and password credentials.

Endpoint

POST /api/auth/sign-in/email

Request parameters

email
string
required
User’s email address
password
string
required
User’s password
rememberMe
boolean
default:"false"
Extend session duration if enabled

Request example

{
  "email": "user@example.com",
  "password": "securePassword123",
  "rememberMe": true
}

Response

Success response

user
object
Authenticated user object
id
string
Unique user identifier (UUID)
email
string
User’s email address
name
string
User’s full name
type
string
User type: employee or organization
profession
string
User’s professional designation
avatar
string
Profile avatar URL
isActive
boolean
Account activation status
organizationId
string
Associated organization ID (for employees)
isEmailVerified
boolean
Email verification status
createdAt
string
Account creation timestamp (ISO 8601)
updatedAt
string
Last update timestamp (ISO 8601)
session
object
Session information
token
string
Session token
expiresAt
string
Session expiration timestamp (ISO 8601)

Success example

{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "name": "John Doe",
    "type": "employee",
    "profession": "Biotechnology Engineer",
    "avatar": "https://example.com/avatar.jpg",
    "isActive": true,
    "organizationId": null,
    "isEmailVerified": true,
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-02-28T14:22:00.000Z"
  },
  "session": {
    "token": "session_abc123def456",
    "expiresAt": "2026-03-07T14:22:00.000Z"
  }
}

Error response

error
string
Error message describing the failure
code
string
Error code identifier

Error example

{
  "error": "Invalid email or password",
  "code": "INVALID_CREDENTIALS"
}

Client usage

React hook

Use the signIn method from the auth client:
import { signIn } from "@/lib/auth-client"

const handleLogin = async () => {
  const { data, error } = await signIn.email({
    email: "user@example.com",
    password: "securePassword123",
    rememberMe: true,
  })

  if (error) {
    console.error("Login failed:", error)
    return
  }

  console.log("Logged in:", data.user)
}

Full component example

import { useState } from "react"
import { signIn } from "@/lib/auth-client"

export const LoginForm = () => {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)
    setError(null)

    const { data, error: authError } = await signIn.email({
      email,
      password,
      rememberMe: true,
    })

    if (authError) {
      setError(authError.message)
      setLoading(false)
      return
    }

    // Redirect based on user type
    if (data.user.type === "employee") {
      window.location.href = "/dashboard/employee"
    } else {
      window.location.href = "/dashboard/admin"
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
        required
      />
      {error && <p>{error}</p>}
      <button type="submit" disabled={loading}>
        {loading ? "Logging in..." : "Log in"}
      </button>
    </form>
  )
}

Rate limiting

Login attempts are rate-limited to 10 requests per minute per IP address. Exceeding this limit returns a 429 Too Many Requests response:
{
  "error": "Too many requests",
  "code": "RATE_LIMIT_EXCEEDED"
}

Session creation

Successful login creates a session with:
  • Expiration: 7 days from login
  • Auto-refresh: Sessions refresh after 1 day of activity
  • Cookie cache: 5-minute cookie cache for performance
  • Tracking: IP address and user agent stored for security

Error codes

CodeDescription
INVALID_CREDENTIALSEmail or password is incorrect
RATE_LIMIT_EXCEEDEDToo many login attempts
ACCOUNT_INACTIVEUser account is deactivated
EMAIL_NOT_VERIFIEDEmail verification required

Build docs developers (and LLMs) love