Skip to main content

Login

Authenticates a user with email and password, and returns access and refresh tokens.

Endpoint​

POST /api/v1/auth/login

Authentication​

No authentication required (public endpoint).

Request​

Content-Type​

application/json

Request Body​

FieldTypeRequiredDescription
emailstringYesUser's email address
passwordstringYesUser's password

Example Request​

{
"email": "john@example.com",
"password": "SecurePass123!"
}

Response​

Success Response (200 OK)​

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}

Response Fields​

FieldTypeDescription
access_tokenstringJWT access token for API requests (expires in 30 minutes)
refresh_tokenstringJWT refresh token for getting new access tokens (expires in 7 days)
token_typestringAlways "bearer"

Examples​

curl -X POST https://api.callcov.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "SecurePass123!"
}'

Login Flow with Token Management​

import requests
from datetime import datetime, timedelta

class CallCovClient:
def __init__(self):
self.base_url = "https://api.callcov.com/api/v1"
self.access_token = None
self.refresh_token = None
self.token_expiry = None

def login(self, email, password):
"""Login and store tokens"""
response = requests.post(
f"{self.base_url}/auth/login",
json={"email": email, "password": password}
)

if response.status_code == 200:
data = response.json()
self.access_token = data['access_token']
self.refresh_token = data['refresh_token']
# Access token expires in 30 minutes
self.token_expiry = datetime.now() + timedelta(minutes=30)
return True
return False

def get_headers(self):
"""Get authorization headers with token refresh"""
# Refresh token if expired or expires soon (within 5 minutes)
if (self.token_expiry and
datetime.now() + timedelta(minutes=5) >= self.token_expiry):
self.refresh_access_token()

return {"Authorization": f"Bearer {self.access_token}"}

def refresh_access_token(self):
"""Refresh the access token"""
response = requests.post(
f"{self.base_url}/auth/refresh",
json={"refresh_token": self.refresh_token}
)

if response.status_code == 200:
data = response.json()
self.access_token = data['access_token']
self.refresh_token = data['refresh_token']
self.token_expiry = datetime.now() + timedelta(minutes=30)

# Usage
client = CallCovClient()
if client.login("john@example.com", "SecurePass123!"):
# Make authenticated requests
response = requests.get(
f"{client.base_url}/users/me",
headers=client.get_headers()
)
print(response.json())

Errors​

401 Unauthorized​

Incorrect email or password:

{
"detail": "Incorrect email or password"
}

403 Forbidden​

User account is inactive:

{
"detail": "User account is inactive"
}

Email not verified:

{
"detail": "Please verify your email address before logging in"
}

Pre-Login Checks​

Before allowing login, the API verifies:

  1. User exists: Email is registered
  2. Password correct: Password matches hashed password
  3. Account active: is_active is true
  4. Email verified: is_verified is true

If any check fails, login is rejected.

Security Considerations​

  • Password never returned: Passwords are never included in responses
  • Rate limiting: Login endpoint is rate-limited to prevent brute force attacks
  • Account lockout: After 5 failed attempts, account is temporarily locked (configurable)
  • Secure password storage: Passwords are hashed with bcrypt
  • HTTPS required: Always use HTTPS in production

Token Expiration​

Token TypeExpirationAction When Expired
Access Token30 minutesUse refresh token to get new one
Refresh Token7 daysUser must log in again

Using Access Tokens​

After login, include the access token in all authenticated requests:

curl https://api.callcov.com/api/v1/users/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Frontend Integration​

Typical login form handling:

async function handleLogin(email, password) {
try {
const response = await fetch('https://api.callcov.com/api/v1/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.detail);
}

const { access_token, refresh_token } = await response.json();

// Store tokens securely
localStorage.setItem('access_token', access_token);
localStorage.setItem('refresh_token', refresh_token);

// Redirect to dashboard
window.location.href = '/dashboard';
} catch (error) {
console.error('Login failed:', error.message);
alert(error.message);
}
}

Troubleshooting​

"Please verify your email address before logging in"​

Solution: User must verify their email first. They can:

  1. Check their email for the verification link
  2. Click the link to verify
  3. Or use resend verification if the email was not received

"User account is inactive"​

Solution: Contact support - the account has been deactivated.

"Incorrect email or password"​

Solution:

  • Check email spelling
  • Check password (case-sensitive)
  • Use password reset if forgotten