API error codes
Complete catalog of error codes returned by the HOWLOPS REST API.
All error responses share this shape:
{
"error": "Human-readable message",
"code": "MACHINE_READABLE_CODE",
"details": {}
}
code and details are optional but present on all documented errors below.
Error code catalog
| Code | HTTP status | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing, expired, or invalid authentication credential. |
FORBIDDEN | 403 | Authenticated but lacking the required role or permission for this action. |
CSRF_TOKEN_INVALID | 403 | The X-CSRF-Token header is missing or incorrect on a session-authenticated unsafe request (POST/PUT/PATCH/DELETE). |
NOT_FOUND | 404 | Resource does not exist, or you do not have permission to see it (IDOR returns 404, not 403). |
CONFLICT | 409 | Duplicate resource or conflicting state transition. |
MFA_ALREADY_ENABLED | 409 | MFA setup was attempted while MFA is already active on the account. |
LAST_AUTH_METHOD | 409 | Attempting to unlink the last remaining sign-in method is not allowed. |
VALIDATION_FAILED | 422 | Request body failed field validation. details contains per-field errors. |
MFA_CODE_INVALID | 422 | Provided TOTP or backup code is incorrect or already used. |
RATE_LIMITED | 429 | Too many requests. See X-RateLimit-Reset header for the window reset time. |
TIER_LIMIT_EXCEEDED | 403 | The action would exceed a numerical limit (e.g. monitor count) for the workspace tier. details includes current_count, tier_limit, tier. |
TIER_FEATURE_NOT_AVAILABLE | 403 | The feature is not available on the current tier. details includes required_tier. |
EMAIL_NOT_VERIFIED | 403 | Account email address has not been verified. Check inbox or request a new verification email. |
MFA_REQUIRED | 200 | Login succeeded for the first factor but a TOTP or backup code is still required. Response body carries mfa_required: true and a session token for the second step. |
invalid_grant | 400 | OAuth token/refresh endpoint: the authorization code is invalid, expired, or already used (RFC 6749 format). |
INTERNAL_ERROR | 500 | Unexpected server error. Include the X-Request-Id header value when reporting. |
Auth-specific error details
VALIDATION_FAILED
{
"error": "Validation failed",
"code": "VALIDATION_FAILED",
"details": {
"fields": {
"email": ["must be a valid email address"],
"password": ["minimum 8 characters required"]
}
}
}
TIER_LIMIT_EXCEEDED
{
"error": "Maximum 3 monitors allowed on free tier",
"code": "TIER_LIMIT_EXCEEDED",
"details": {
"current_count": 3,
"tier_limit": 3,
"tier": "free"
}
}
RATE_LIMITED
{
"error": "Rate limit exceeded. Try again in 42 seconds.",
"code": "RATE_LIMITED",
"details": {
"retry_after_seconds": 42
}
}
Rate limit endpoints
| Endpoint group | Limit | Window |
|---|---|---|
/api/v1/auth/* (login, register, reset, verify) | 10 requests | 1 minute / IP |
/api/v1/setup | 5 requests | 1 minute / IP |
/api/v1/oauth/token | 5 requests | 1 minute / IP |
/api/v1/hb/* (heartbeat pings) | Configurable per tenant | — |
| Default (authenticated) | 600 requests | 1 minute / user |
Public reads (/api/v1/public/*) | 60 requests | 1 minute / IP |
See also
Was this page helpful?