Errors & rate limits
Error format
Errors use NestJS's default shape — an HTTP status code, a machine-readable error name, and a human-readable message:
401 Unauthorized
{
"statusCode": 401,
"message": "Invalid credentials",
"error": "Unauthorized"
}| Status | Meaning |
|---|---|
| 400 | Validation failed — check the request body against the DTO fields |
| 401 | Missing/invalid/expired access token, or wrong login credentials |
| 403 | Authenticated, but not allowed to perform this action (wrong role) |
| 404 | Resource not found |
| 409 | Conflict — e.g. phone/email already registered |
| 429 | Rate limit exceeded |
Rate limits
A global limit applies to every request, with tighter limits on sensitive authentication endpoints:
| Scope | Limit |
|---|---|
| All requests | 100 requests / 15 minutes per IP |
| POST /auth/login | 5 requests / 15 minutes per IP |
| POST /auth/register/send-otp | 3 requests / 5 minutes per IP |
| POST /auth/login/send-otp | 3 requests / 5 minutes per IP |
Exceeding a limit returns 429 Too Many Requests.
