Authentication
Sanctum personal-access tokens for every client (web, mobile, third-party).
Login
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "hr@acme.com",
"password": "secret",
"device_name": "chrome-desktop",
"device_fingerprint": "optional-for-mobile"
}
Response:
{
"token": "1|abcd...",
"token_type": "Bearer",
"user": {
"id": 42,
"name": "HR Admin",
"email": "hr@acme.com",
"roles": ["hr"],
"scopes": [{ "type": "organization", "organization_id": 1 }]
},
"expires_at": "2026-05-23T09:00:00Z"
}
Using the Token
Authorization: Bearer 1|abcd...
Mobile Device Binding
Mobile clients send X-Device-Fingerprint on every request. The server validates that the fingerprint matches a device row with status = approved for the authenticated employee; otherwise the request is rejected with 423 Locked.
Refresh / Logout
POST /api/v1/auth/logout— revokes the current token.POST /api/v1/auth/logout-all— revokes every token for the user.- Tokens auto-expire after 30 days for web, 180 days for mobile (configurable).
Rate Limits
- Login: 5 requests per minute per IP.
- Ingestion: 30 requests per minute per employee (generous — offline buffers flush after reconnect).
- Exports: 10 per hour per user.
Example: Curl
# Login
TOKEN=$(curl -sX POST https://api.example.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"hr@acme.com","password":"secret","device_name":"curl"}' \
| jq -r .token)
# Authenticated call
curl -H "Authorization: Bearer $TOKEN" \
https://api.example.com/api/v1/me