text Base URL: http://localhost:5000/api/v1 (API_PREFIX default)
// success
{ "success": true, "message": "...", "data": { ... } }
// success with paging (admin users list)
{ "success": true, "message": "...", "data": { ... }, "pagination": { ... } }
// error
{ "success": false, "message": "...", "code": "ERROR_CODE", "details": ... }Two ways to authenticate Browsers rely on the httpOnly cookies automatically. Server-to-server calls pass Authorization: Bearer <accessToken> instead — the protect middleware accepts both.
/api/v1/auth /api/v1/users /api/v1/admin Verified health endpoint (under the API prefix) curl http://localhost:5000/api/v1/health
# → {"success":true,"message":"Server is healthy","timestamp":"…"}
# (non-production also returns "uptime")Error semantics: 400 validation (Joi error details), 401 missing/expired token, 403 wrong role, 404 route/user not found, 409 duplicate email, 429 rate limit (with RateLimit headers), 500 fallback — codes are uppercase snake_case in the code field.
Tip Frontend calls these via RTK Query slices under frontend/src/store/api/ — add new endpoint types there, never inline fetch calls (see Frontend Configuration).