Base URL
All endpoints live under a versioned base path. In local development:
http://localhost:4000/api/v1Response envelope
Every response uses the same envelope. A single resource:
{ "success": true, "data": { /* ... */ } }A list adds pagination:
{
"success": true,
"data": [ /* ... */ ],
"pagination": { "page": 1, "limit": 20, "total": 137, "totalPages": 7 }
}And errors:
{ "success": false, "error": { "message": "Invalid email or password" } }IDs are strings
Database ids are 64-bit integers serialised as strings. Always treat an id as a string — never compare or store it as a number.
Authentication
Auth is a JWT bearer token. Register or sign in, then send the token on authenticated calls:
POST /auth/registerorPOST /auth/login→{ token, user }- Send
Authorization: Bearer <token>with each authenticated request GET /auth/mereturns the current user;POST /auth/logout-allrevokes every session (changing your password does the same for other devices)
curl -X POST http://localhost:4000/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"your-password"}'Pagination
List endpoints accept ?page and ?limit; the pagination block reports totals so you can page through results.
Errors & status codes
400— validation failed / bad request401— missing or invalid token403— authenticated but not allowed (admin only)404— not found ·409— conflict429— rate limited (back off and retry)
Branch on the HTTP status and error.message — never string-match beyond that.
Rate limits
Credential endpoints (login, register) are rate-limited per IP + email. Handle 429 gracefully.
Try it out
The interactive reference below targets a local/sandboxserver — never production — so you can send real requests and experiment safely. Authenticated endpoints have a token field.

