Error Codes
All errors follow the envelope format with a SCREAMING_SNAKE_CASE code field.
| Code | HTTP Status | Meaning |
|---|---|---|
| AUTH_REQUIRED | 401 | Valid session cookie or API key required |
| FORBIDDEN | 403 | Authenticated but not authorized, including tier upgrades required (detail carries error: upgrade_required) |
| viewer_role | 403 | Read-only (viewer) member attempted a write operation |
| TIER_GATE | 402 | Returned by a small number of endpoints (audit log export, SAGE chat). Most tier gating returns 403 FORBIDDEN |
| NOT_FOUND | 404 | Resource does not exist |
| METHOD_NOT_ALLOWED | 405 | HTTP method not supported on this endpoint |
| VALIDATION_ERROR | 422 | Request parameters failed validation |
| RATE_LIMITED | 429 | Too many requests - back off and retry |
| INTERNAL_ERROR | 500 | Server error - our team has been notified |
Tier Upgrade Response
When a feature is gated by tier, most endpoints return HTTP 403 with code FORBIDDEN and an upgrade_required detail block. For example, generating an API key on Free or Standard returns:
{
"api": { "version": "1.0.0", "request_id": "bs-req-..." },
"error": {
"code": "FORBIDDEN",
"message": "API access is available on the Professional tier and above.",
"detail": {
"error": "upgrade_required",
"permission": "api_access",
"current_tier": "standard",
"upgrade_url": "/account/upgrade",
"message": "API access is available on the Professional tier and above."
}
}
}
A small number of endpoints (audit log export, SAGE chat) instead return HTTP 402 with code TIER_GATE. Handle both 402 and 403 as "upgrade required."
VALIDATION_ERROR Response
Validation errors include per-field detail:
{
"api": { "version": "1.0.0", "request_id": "bs-req-..." },
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"detail": [
{
"field": "query.severity",
"message": "String should match pattern '^(CRITICAL|HIGH|MEDIUM|LOW)$'",
"type": "string_pattern_mismatch"
}
]
}
}
Rate Limiting
When rate limited, back off exponentially and retry. The Retry-After header indicates seconds to wait.
# Check your current rate limit status
curl -I -H "Authorization: Bearer bs_live_..." \
"https://breachspider.com/api/v1/health"