Errors
All errors return a consistent JSON envelope with a machine-readable code, human-readable message, and a unique request ID for debugging.
What does error code X mean?
Error code X means the request failed for the machine-readable reason returned in error.code; replace X with codes such as VALIDATION_ERROR, UNAUTHORIZED, or RATE_LIMITED and use the table below for the required action. Include the response request ID when contacting support, and retry only errors marked retryable.
Error format
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid value for employee_bands: 'Huge'.",
"details": [
{
"field": "employee_bands",
"issue": "invalid_enum_value",
"received": "Huge",
"expected": ["Small Employers", "SMB Accounts", "..."]
}
],
"request_id": "req_8f3a2b1c4d5e6f7a"
}
}The request_id is also returned in the X-Request-Id response header on every request (including successes). Include it in support requests.
Status codes
| Status | Code | Retryable? | What to do |
|---|---|---|---|
| 400 | VALIDATION_ERROR, FILTER_REQUIRED, QUERY_TOO_COMPLEX, TOO_MANY_COLUMN_FILTERS | No | Fix the request parameters |
| 400 | PRODUCTION_KEY_REQUIRED | No | Use an ss_live_ key for tags, data flags, credits, API-key management, reports, and usage |
| 401 | UNAUTHORIZED | No | Check your API key |
| 402 | CREDITS_EXHAUSTED | No | Insufficient credits — contact your account rep |
| 403 | FORBIDDEN | No | Check key scopes, field tier, or plan level |
| 404 | NOT_FOUND | No | Check the entity ID or URL path |
| 429 | RATE_LIMITED, DAILY_ROW_LIMIT, DAILY_QUERY_LIMIT, CRAWL_DETECTED | Yes | Wait for Retry-After header |
| 500 | INTERNAL_ERROR | Yes | Retry with exponential backoff |
| 503 | CREDIT_DEDUCTION_FAILED | Yes | Idempotent retry — no credits were deducted. Backoff 1s, 2s, 4s. |
| 504 | GATEWAY_TIMEOUT | Yes | Simplify your query or reduce page_size |
Retry strategy
| Error | Strategy |
|---|---|
| 429 per-minute rate limit | Wait Retry-After seconds, then retry |
| 429 daily row/query limit | Wait until midnight UTC |
| 429 CRAWL_DETECTED | Don't blindly retry — add filter diversity, then resume |
| 500 server error | Retry up to 3 times: wait 1s, 2s, 4s |
| 503 CREDIT_DEDUCTION_FAILED | Idempotent retry (no credits deducted). Backoff 1s, 2s, 4s. If it persists after 3 attempts, contact support. |
| 504 timeout | Add more filters, reduce page_size, drop expensive signal enrichments, then retry |
Error detail fields
| Field | Type | When present | Description |
|---|---|---|---|
field | string | Validation errors | Parameter that caused the error |
issue | string | Always | Machine-readable issue code |
received | string | Validation errors | The invalid value submitted |
expected | string | string[] | Validation errors | Valid values or format |
limit | number | Quota/rate errors | The limit that was exceeded |
retry_after_seconds | number | 429 errors | Seconds to wait before retrying |
Issue types
Every error includes a machine-readable issue field. Use it to branch in client code instead of pattern-matching on message.
| Issue | When |
|---|---|
invalid_enum_value | Filter value not in the allowlist |
invalid_type | Wrong data type (e.g. string where boolean expected) |
missing_required | Required parameter not provided (e.g. personnel without lead_type) |
invalid_range | Numeric range syntax error (e.g. cf[x]=gte:abc) |
unknown_param | Query string contains an unrecognized parameter |
page_size_too_large | page_size > 500 |
not_sortable | sort_by references a non-allowlisted column |
too_many_filters | More than 15 distinct filters |
too_many_column_filters | More than 10 cf[] filters |
filter_required | page_size > 25 with no filters |
insufficient_scope | API key lacks the required scope |
insufficient_field_tier | Basic key requested an advanced field (via mode=full or fields=) |
insufficient_plan | Feature not available on the org's plan |
credits_exhausted | Org credit balance is 0 |
credit_deduction_failed | Credit deduction failed after query — data not returned |
rate_limited | Per-key per-minute rate limit exceeded |
daily_row_limit | Org daily row cap exceeded |
daily_query_limit | Plan daily query cap exceeded |
crawl_detected | Sequential pagination beyond 20 pages without filter changes |
query_timeout | Query exceeded 30s execution time |
not_found | Entity ID or resource path not found |
key_inactive | API key has been revoked or expired |
internal_error | Unexpected server error |
Keys are issued by our team, not a signup form. Book a 25-minute walkthrough and you'll leave with sandbox and live credentials.