LeadLeapData
Getting started

Errors

We aim for actionable errors. Validation failures always include an example request that would have worked. Rate-limit responses always carry Retry-After. Per-source partial failures show up inline in warnings and errors arrays, not as a hard 5xx.

HTTP status reference

StatusMeaningWhen you see it
200OKRequest succeeded. Inspect warnings array for partial-data conditions.
400Bad RequestInvalid input - missing type, unknown filter, query without narrowing filter, malformed JSON. Body always includes a worked example.
401UnauthorizedMissing or unrecognized bearer key.
403ForbiddenKey lacks scope for this endpoint. External keys cannot hit /admin/*.
413Payload Too LargeRequest body over 1 MB. Trim the request and retry.
429Too Many RequestsBurst, daily, or concurrency cap exceeded. Inspect Retry-After.
500Internal Server ErrorGateway crashed. Reach out with the X-Request-Id header from the response.
502Bad GatewayA downstream component (lake coordinator, validator backend) was unreachable. Often transient - retry with backoff.

Validation error

400 responses always include the original failing condition plus a worked example. We try to never leave you guessing what shape would have worked.

HTTP 400
{
  "error": "Free-text 'query' requires at least one narrowing filter.",
  "detail": "Presence filters (has_email, has_phone, has_linkedin) don't count - they filter AFTER the scan, not before it.",
  "example": {
    "type": "contacts",
    "query": "investment officer",
    "filters": {"country": ["US"]}
  },
  "tip": "Use GET /v1/sources to discover which filters apply to which datasets."
}

Rate limit error

HTTP 429 Too Many Requests
Retry-After: 37

{
  "error": "rate_limited",
  "detail": "30 requests/minute exceeded. Retry in 37 seconds.",
  "retry_after": 37
}

Three different things produce a 429: minute-window burst, daily unit budget, and umbrella concurrency cap. The detail string tells you which one tripped and how to back off. See Rate limits for the full picture.

Partial source failure (HTTP 200)

When one shard times out or one source is unreachable, the gateway returns the rows it did get with a warning. You don't lose the whole call to a single flaky dataset.

HTTP 200
{
  "results": [ ... ],
  "total":   42,
  "warnings": [
    "source 'leadleap_contacts' returned partial data - one or more lake nodes failed to respond. Results may be incomplete."
  ],
  "errors": [
    "leadleap_intent_signals: data-node timeout"
  ],
  ...
}

Validate-endpoint error envelope

The validate endpoint wraps every response in {data, meta, error} and uses a structured error object on failure.

HTTP 400
{
  "data": null,
  "meta": {},
  "error": {
    "code":    "INVALID_JSON",
    "message": "Request body must be valid JSON. Send {\"email\": \"[email protected]\"} for single validation or {\"emails\": [...]} for bulk.",
    "status":  400
  }
}

Always grab X-Request-Id off the response headers when you log a failed call. That one identifier lets us pull the exact gateway log entry for your request.

Errors are sanitized. We strip internal node hostnames, file paths, and raw provider names from error strings before they leave the gateway. You won't see internal data-node URLs in your logs.