Skip to main content
POST
/
auth
/
login
Login
curl --request POST \
  --url https://api.example.com/auth/login \
  --header 'Content-Type: application/json' \
  --data '
{
  "email": "<string>",
  "password": "<string>"
}
'
{
  "success": true,
  "data": {
    "data.token": "<string>",
    "data.role": "<string>",
    "data.employee": {
      "data.employee.id": "<string>",
      "data.employee.company_id": "<string>",
      "data.employee.email": "<string>",
      "data.employee.phone": "<string>",
      "data.employee.first_name": "<string>",
      "data.employee.last_name": "<string>",
      "data.employee.employee_code": "<string>",
      "data.employee.department_id": "<string>",
      "data.employee.designation_id": "<string>",
      "data.employee.level_id": "<string>",
      "data.employee.manager_id": "<string>",
      "data.employee.role_id": "<string>",
      "data.employee.status": "<string>",
      "data.employee.employment_type": "<string>",
      "data.employee.date_of_birth": "<string>",
      "data.employee.hire_date": "<string>",
      "data.employee.termination_date": "<string>",
      "data.employee.gender": "<string>",
      "data.employee.address": "<string>",
      "data.employee.emergency_contact_name": "<string>",
      "data.employee.emergency_contact_phone": "<string>",
      "data.employee.profile_image_url": "<string>",
      "data.employee.last_login_at": "<string>",
      "data.employee.created_at": "<string>",
      "data.employee.updated_at": "<string>"
    },
    "data.company": {
      "data.company.id": "<string>",
      "data.company.name": "<string>",
      "data.company.slug": "<string>",
      "data.company.industry": "<string>",
      "data.company.country": "<string>",
      "data.company.timezone": "<string>",
      "data.company.currency": "<string>",
      "data.company.registration_number": "<string>",
      "data.company.tax_id": "<string>",
      "data.company.address": "<string>",
      "data.company.phone": "<string>",
      "data.company.logo_url": "<string>",
      "data.company.status": "<string>",
      "data.company.settings": {},
      "data.company.created_at": "<string>",
      "data.company.updated_at": "<string>"
    }
  }
}

Overview

The login endpoint authenticates employees using their email and password credentials. Upon successful authentication, it returns a JWT token valid for 24 hours along with employee and company information.

Authentication Flow

  1. Employee submits email and password
  2. System validates credentials against the database
  3. Checks if employee status is “active”
  4. Verifies password hash using bcrypt
  5. Generates JWT token with 24-hour expiration
  6. Returns token with employee and company details

Request

email
string
required
Employee email address. Must be a valid email format.Example: [email protected]
password
string
required
Employee password. Minimum 8 characters required.Example: SecurePass123!

Request Example

{
  "email": "[email protected]",
  "password": "SecurePass123!"
}

Response

success
boolean
Indicates if the request was successful
data
object
Contains the authentication response data
data.token
string
JWT authentication token valid for 24 hours. Use this token in the Authorization header for subsequent API requests.
data.role
string
Employee’s role name (e.g., “admin”, “manager”, “employee”)
data.employee
object
Employee details
data.employee.id
string
Employee UUID
data.employee.company_id
string
Company UUID
data.employee.email
string
Employee email address
data.employee.phone
string
Employee phone number
data.employee.first_name
string
Employee first name
data.employee.last_name
string
Employee last name
data.employee.employee_code
string
Internal employee code (e.g., “EMP001”)
data.employee.department_id
string
Department UUID
data.employee.designation_id
string
Designation UUID
data.employee.level_id
string
Level UUID
data.employee.manager_id
string
Manager’s employee UUID (if applicable)
data.employee.role_id
string
Role UUID
data.employee.status
string
Employee status: active, inactive, on_leave, terminated, or probation
data.employee.employment_type
string
Employment type: full_time, part_time, contract, or intern
data.employee.date_of_birth
string
Date of birth in ISO 8601 format
data.employee.hire_date
string
Hire date in ISO 8601 format
data.employee.termination_date
string
Termination date in ISO 8601 format (if applicable)
data.employee.gender
string
Employee gender
data.employee.address
string
Employee address
data.employee.emergency_contact_name
string
Emergency contact name
data.employee.emergency_contact_phone
string
Emergency contact phone number
data.employee.profile_image_url
string
Profile image URL
data.employee.last_login_at
string
Last login timestamp in ISO 8601 format
data.employee.created_at
string
Account creation timestamp in ISO 8601 format
data.employee.updated_at
string
Last update timestamp in ISO 8601 format
data.company
object
Company details
data.company.id
string
Company UUID
data.company.name
string
Company name
data.company.slug
string
Company slug (URL-friendly identifier)
data.company.industry
string
Company industry
data.company.country
string
Company country
data.company.timezone
string
Company timezone
data.company.currency
string
Company currency code
data.company.registration_number
string
Company registration number
data.company.tax_id
string
Company tax ID
data.company.address
string
Company address
data.company.phone
string
Company phone number
data.company.logo_url
string
Company logo URL
data.company.status
string
Company status: active, suspended, or inactive
data.company.settings
object
Company-specific settings (JSON blob)
data.company.created_at
string
Company creation timestamp in ISO 8601 format
data.company.updated_at
string
Last update timestamp in ISO 8601 format

Success Response Example

{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "role": "admin",
    "employee": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "company_id": "987fcdeb-51a2-43f7-9876-543210fedcba",
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "John",
      "last_name": "Doe",
      "employee_code": "EMP001",
      "department_id": "456e7890-e12b-34d5-a678-901234567890",
      "designation_id": "789f0123-e45c-67d8-a901-234567890123",
      "level_id": "012g3456-e78d-90e1-a234-567890123456",
      "manager_id": "345h6789-e01e-23f4-a567-890123456789",
      "role_id": "678i9012-e34f-56g7-a890-123456789012",
      "status": "active",
      "employment_type": "full_time",
      "date_of_birth": "1990-05-15T00:00:00Z",
      "hire_date": "2023-01-15T00:00:00Z",
      "termination_date": null,
      "gender": "male",
      "address": "123 Main St, City, Country",
      "emergency_contact_name": "Jane Doe",
      "emergency_contact_phone": "+0987654321",
      "profile_image_url": "https://example.com/avatar.jpg",
      "last_login_at": "2024-03-01T10:30:00Z",
      "created_at": "2023-01-15T09:00:00Z",
      "updated_at": "2024-03-01T10:30:00Z"
    },
    "company": {
      "id": "987fcdeb-51a2-43f7-9876-543210fedcba",
      "name": "Acme Corporation",
      "slug": "acme-corp",
      "industry": "Technology",
      "country": "United States",
      "timezone": "America/New_York",
      "currency": "USD",
      "registration_number": "REG123456",
      "tax_id": "TAX789012",
      "address": "456 Corporate Blvd, City, State",
      "phone": "+1555123456",
      "logo_url": "https://example.com/logo.png",
      "status": "active",
      "settings": {},
      "created_at": "2022-01-01T00:00:00Z",
      "updated_at": "2024-02-15T14:20:00Z"
    }
  }
}

Error Responses

400 Bad Request

Returned when the request body is malformed or missing required fields.
{
  "success": false,
  "error": "invalid request body"
}
Common causes:
  • Missing email or password field
  • Invalid JSON format
  • Email not in valid format

401 Unauthorized

Returned when the credentials are invalid or the employee account is not active.
{
  "success": false,
  "error": "invalid credentials"
}
Common causes:
  • Incorrect email or password
  • Employee not found in database
  • Employee status is not “active” (e.g., inactive, terminated, on_leave, probation)
  • Password hash verification failed

500 Internal Server Error

Returned when an unexpected server error occurs.
{
  "success": false,
  "error": "internal server error message"
}
Common causes:
  • Database connection failure
  • JWT token generation failure
  • Missing JWT_SECRET environment variable

JWT Token Details

The returned JWT token contains the following claims:
  • employee_id: Employee UUID
  • role: Employee role name
  • company_id: Company UUID
  • email: Employee email
  • first_name: Employee first name
  • last_name: Employee last name
  • sub: Subject (employee ID)
  • iat: Issued at timestamp
  • exp: Expiration timestamp (24 hours from issuance)
The token is signed using HS256 algorithm with the JWT_SECRET environment variable.

Usage Example

cURL

curl -X POST https://api.companyflow.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!"
  }'

JavaScript (fetch)

const response = await fetch('https://api.companyflow.com/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: '[email protected]',
    password: 'SecurePass123!',
  }),
});

const data = await response.json();

if (data.success) {
  // Store the token for subsequent requests
  const token = data.data.token;
  localStorage.setItem('authToken', token);
  
  console.log('Login successful:', data.data.employee);
} else {
  console.error('Login failed:', data.error);
}

Python (requests)

import requests

url = 'https://api.companyflow.com/auth/login'
payload = {
    'email': '[email protected]',
    'password': 'SecurePass123!'
}

response = requests.post(url, json=payload)
data = response.json()

if data['success']:
    token = data['data']['token']
    print(f"Login successful. Token: {token}")
else:
    print(f"Login failed: {data['error']}")

Using the Token

After successful login, include the JWT token in the Authorization header for subsequent API requests:
curl -X GET https://api.companyflow.com/api/employees \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Security Notes

  • Passwords are hashed using bcrypt with default cost factor
  • JWT tokens expire after 24 hours
  • Only employees with “active” status can login
  • Failed login attempts do not reveal whether the email exists
  • Tokens should be stored securely (e.g., httpOnly cookies or secure storage)
  • Always use HTTPS in production to protect credentials in transit

Build docs developers (and LLMs) love