Error response format
Most error responses use this shape:Treat errors as text
Treat error as a human-readable reason, not a stable enum.
Stay forward-compatible
Ignore unknown response fields for forward compatibility.
Protect secrets in logs
Never log secrets, especially the
Authorization header.Status codes and retry actions
| Status code | Meaning | Retry strategy | Recommended action |
|---|---|---|---|
400 Bad Request | Missing or invalid parameters/JSON body | No | Fix request shape or required inputs |
401 Unauthorized | Missing, invalid, or revoked API key | No | Validate credentials and replace/re-enable key |
403 Forbidden | Authenticated but blocked by enterprise access policy | No | Verify enterprise scope/eligibility and enterprise billing state |
409 Conflict | Workspace quota reached on write operations | No | Reduce usage or increase workspace quotas, then retry |
404 Not Found | Unknown endpoint or resource | No | Confirm endpoint path, method, and resource identifiers |
429 Too Many Requests | Rate limit exceeded | Yes | Retry with exponential backoff + jitter |
500/502/503/504 | Transient server-side failure | Conditional | Retry safe requests (GET) with backoff |
Common examples
| Scenario | HTTP status | Example error body |
|---|---|---|
| Missing API key | 401 Unauthorized | { "error": "Missing API key" } |
| Out-of-scope request | 403 Forbidden | { "error": "You don't have permission to view this" } |
| Enterprise billing access denied | 403 Forbidden | { "error": "Enterprise billing access denied", "reason": "payment_unpaid", "status": "unpaid" } |
| Watchlist quota reached | 409 Conflict | { "error": "quota_domains_reached", "metric": "domains", "used": 10, "limit": 10, "requestedIncrement": 1 } |
| Rate limit exceeded | 429 Too Many Requests | { "error": "Rate limit exceeded" } |
Backoff snippet
JavaScript backoff snippet
Python backoff snippet