Skip to content

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"