Errors
All v2 endpoints use conventional HTTP status codes and a consistent JSON envelope.
| Status | Meaning |
|---|---|
200 | Success |
400 | Bad request - validation failed; the response body lists the offending fields |
401 | Unauthorized - missing or invalid x-api-key header |
402 | Payment required - not enough credits for the requested operation |
408 | Request timeout - the lookup took too long; safe to retry |
429 | Too many requests - demo account only; back off and retry later |
5xx | Server error - safe to retry with exponential backoff |
Error responses share one envelope shape: success is false and errors is an array of
{ name, message } objects (validation errors also carry a payload with the offending field).
data is usually null, with one exception noted below.
"Not found" results are HTTP
200, not404People Enrich, Company Enrich, and Email Finder return a well-formed
200response withsuccess: falseanderrors: [{ "name": "NOT_FOUND", ... }]when a valid, well-formed request simply finds no match - there is no dedicated404for this case. Email Finder's not-found response also keeps a non-nulldataobject (email: nullplus whatever domain information was resolved). Checksuccessanderrors, not the HTTP status, to detect a miss.
400 - Bad request
Two request shapes fail validation on People Search, shown together below: page: 0 (must be
>= 1) and an unrecognized top-level field (the endpoint rejects unknown fields instead of
silently ignoring them). Each failing field gets its own entry in errors, with the offending
field name in payload.field.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-07-25T14:02:31.000Z"
},
"errors": [
{
"name": "VALIDATION_ERROR",
"message": "page must not be less than 1",
"payload": {
"field": "page",
"received_value": 0,
"received_type": "number",
"constraints": {
"min": "page must not be less than 1"
}
}
},
{
"name": "VALIDATION_ERROR",
"message": "property unexpected_field should not exist",
"payload": {
"field": "unexpected_field",
"received_value": "test",
"received_type": "string",
"constraints": {
"whitelistValidation": "property unexpected_field should not exist"
}
}
}
]
}Filter-level rules surface as a plainer
400A handful of rules aren't expressed as per-field decorators - for example "at least one include filter is required" on People Search. Those still return
400/VALIDATION_ERROR, but as a single{ name, message }entry with nopayload.
401 - Unauthorized
Returned when the x-api-key header is missing or invalid.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-06-18T09:12:44.000Z"
},
"errors": [
{
"name": "UNAUTHORIZED",
"message": "Unauthorized"
}
]
}402 - Payment required
Returned once your workspace's credit balance reaches zero, before the request is even processed.
The response also sets two headers: X-Limit-Reached: true and X-Limit-Type: credits.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-07-25T14:02:31.000Z"
},
"errors": [
{
"name": "PAYMENT_REQUIRED",
"message": "Workspace has reached its credit limit"
}
]
}Some endpoints also run a narrower pre-flight check against the specific credit type a request
would spend (for example People Search only checks email credits when you pass
enrich_email: true), which fails the same way with a more specific message such as
"Insufficient email credits: have 0, need 3".
408 - Request timeout
Email Finder and Email Verifier return 408 when the underlying lookup takes too long. Retry
after a short delay.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-07-25T14:02:31.000Z"
},
"errors": [
{
"name": "TIMEOUT",
"message": "Email search is taking longer than expected. Please retry your request in a few minutes."
}
]
}429 - Too many requests
Only applies to the shared demo account, capped at 1500 requests per hour per requesting IP address. Regular workspace API keys are not rate-limited.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-07-25T14:02:31.000Z"
},
"errors": [
{
"name": "RATE_LIMIT",
"message": "Demo user requests limit"
}
]
}5xx - Server error
Returned when a downstream dependency is unavailable - for example, People Search and Company
Search return 500 with this message when the search backend can't be reached. Safe to retry
with exponential backoff.
{
"success": false,
"data": null,
"metadata": {
"timestamp": "2026-07-25T14:02:31.000Z"
},
"errors": [
{
"name": "INTERNAL_ERROR",
"message": "Search backend unavailable"
}
]
}An unexpected, unhandled error (rather than one the API explicitly detected and reported) returns
the same 500 / INTERNAL_ERROR shape with a generic "Internal server error" message instead,
so as not to leak internal details.
