Implementation-aligned contract reference for the current API.
For generated OpenAPI, use:
GET /openapi.jsonGET /docs
Supported auth methods:
- JWT bearer token:
Authorization: Bearer <token>
- API key (for allowed scopes only):
X-API-Key: <key>
Identity claims used by the API:
suborganization_idrole(ADMINorEMPLOYEE)
Success:
{
"success": true,
"data": {}
}Error:
{
"success": false,
"error": "Human readable message",
"requestId": "uuid"
}Common HTTP status codes:
200success201created202accepted / queued204no content400validation/business rule error401unauthenticated403forbidden404not found409conflict410removed/deprecated endpoint429rate limited500internal error
Example typed error codes used in responses include values such as VALIDATION_ERROR, INVALID_CREDENTIALS, and route-specific domain codes.
GET /service identityGET /healthlivenessGET /readydependency readinessGET /metricsPrometheus/OpenMetricsGET /openapi.jsonOpenAPI specGET /docsSwagger UI
Body:
{
"email": "user@example.com",
"password": "password"
}Response:
{
"success": true,
"data": {
"access_token": "...",
"refresh_token": "...",
"token_type": "bearer",
"expires_in": 3600,
"expires_at": 1741686400
}
}Auth required.
Response:
{
"success": true,
"data": {
"id": "uuid-or-api-key-sub",
"email": "user@example.com",
"role": "ADMIN",
"orgId": "organization-uuid"
}
}POST /attendance/check-in(EMPLOYEE)POST /attendance/check-out(EMPLOYEE)POST /attendance/:sessionId/recalculate(authenticated, rate-limited)GET /attendance/my-sessions?page&limit&statusGET /attendance/org-sessionsis removed and returns410; use admin sessions endpoint.
Session status filter values:
allactiverecentinactive
Example response item:
{
"id": "session-uuid",
"employee_id": "employee-uuid",
"organization_id": "org-uuid",
"checkin_at": "2026-04-01T09:00:00.000Z",
"checkout_at": null,
"total_distance_km": null,
"total_duration_seconds": null,
"distance_recalculation_status": null,
"created_at": "...",
"updated_at": "..."
}POST /locations(EMPLOYEE)POST /locations/batch(EMPLOYEE)GET /locations/my-route?sessionId=<uuid>
/locations/my-route accepts sessionId and legacy-compatible session_id query params.
Single-point request example:
{
"session_id": "session-uuid",
"latitude": 28.6139,
"longitude": 77.209,
"accuracy": 12.5,
"recorded_at": "2026-04-01T09:30:00.000Z"
}POST /expenses/receipt-upload-url(EMPLOYEE)POST /expenses(EMPLOYEE)GET /expenses/my?page&limit&status
Employee expense status values:
allPENDINGAPPROVEDREJECTEDprocessed
GET /dashboard/my-summaryGET /profile/meGET /leaderboard
POST /expensesGET /expenses/my
GET /admin/expensesPATCH /admin/expenses/:idGET /admin/expenses/summaryGET /admin/expenses/export
Review body example:
{
"status": "APPROVED"
}All endpoints below require ADMIN role unless noted.
GET /admin/sessionsGET /admin/sessions/:id/locationsPOST /admin/force-checkoutGET /admin/employeesPOST /admin/employeesGET /admin/employees/:idPATCH /admin/employees/:idPATCH /admin/employees/:id/statusGET /admin/employees/:employeeId/profileGET /admin/search
GET /admin/dashboardGET /admin/org-summaryGET /admin/user-summaryGET /admin/top-performersGET /admin/session-trendGET /admin/leaderboardGET /admin/monitoring/map
Date range query params use from and to ISO datetime values.
POST /admin/start-monitoringPOST /admin/stop-monitoringGET /admin/monitoring-historyGET /admin/events(SSE stream)GET /admin/queuesPOST /admin/queues/replay-distance-dlqGET /admin/retry-intentsGET /admin/system-healthGET /admin/audit-log
POST /admin/api-keysGET /admin/api-keysPATCH /admin/api-keys/:idDELETE /admin/api-keys/:id
API key routes require JWT auth and cannot be managed with API key auth itself.
GET /admin/webhooksPOST /admin/webhooksPATCH /admin/webhooks/:idDELETE /admin/webhooks/:idGET /admin/webhook-deliveriesGET /admin/webhooks/logsPOST /admin/webhook-deliveries/:id/retryPOST /admin/webhooks/logs/:id/retryPOST /admin/webhooks/:id/testGET /admin/webhook-dlqPOST /admin/webhook-dlq/:id/retry
Legacy aliases under /webhooks* exist for backward compatibility and are hidden from OpenAPI.
GET /internal/metricsGET /internal/queues/statusGET /internal/snapshot-healthGET /internal/ready-deep
Route-level limits include:
POST /locationsandPOST /locations/batch: 10 requests / 10 seconds per user keyPOST /expenses: 10 requests / 60 seconds per user keyPOST /attendance/:sessionId/recalculate: 5 requests / 60 seconds per user key
Additional global and security middleware limits are enforced by Fastify plugins.