View as Markdown

Errors

All v2 endpoints use conventional HTTP status codes and a consistent JSON envelope.

StatusMeaning
200Success
400Bad request - validation failed; the response body lists the offending fields
401Unauthorized - missing or invalid x-api-key header
402Payment required - not enough credits for the requested operation
408Request timeout - the lookup took too long; safe to retry
429Too many requests - demo account only; back off and retry later
5xxServer 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, not 404

People Enrich, Company Enrich, and Email Finder return a well-formed 200 response with success: false and errors: [{ "name": "NOT_FOUND", ... }] when a valid, well-formed request simply finds no match - there is no dedicated 404 for this case. Email Finder's not-found response also keeps a non-null data object (email: null plus whatever domain information was resolved). Check success and errors, 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.

Response
{
  "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 400

A 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 no payload.

401 - Unauthorized

Returned when the x-api-key header is missing or invalid.

Response
{
  "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.

Response
{
  "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.

Response
{
  "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.

Response
{
  "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.

Response
{
  "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.