LeadLeapData
Getting started

Response format

Two response shapes across the API. Search endpoints return the body directly. The validate endpoint wraps in {data, meta, error} so it can carry batch aggregates. Both follow the same conventions: every documented field is always present, missing values are null not omitted, and warnings show up inline rather than in headers.

Search envelope (find · sources · schema)

{
  "results":          [ { ...row... } ],
  "total":            142,
  "returned":         5,
  "limit":            5,
  "offset":           0,
  "type":             "contacts",
  "sources_searched": ["leadleap_contacts","fec_political_committees"],
  "coverage_note":    "Contact coverage is approximately 80% on US companies, ...",
  "warnings":         [],
  "errors":           []
}
  • results - array of normalized rows. Empty array on no matches, never null.
  • total - pre-pagination row count after dedupe. Use this to drive UI pagination.
  • returned - number of rows in this page (≤ limit).
  • sources_searched - public dataset aliases that contributed (or were probed).
  • coverage_note - an honest one-liner about what we know about coverage for this query.
  • warnings - soft issues: query truncation, country auto-coercion, partial source results.
  • errors - per-source errors, sanitized of internal node names and URLs.

Wrapped envelope (email/validate)

{
  "data": {
    "email":      "[email protected]",
    "is_valid":   true,
    "confidence": "high",
    "checks":     { "syntax": true, "domain": true, "smtp": true, "mx_records": true },
    "details":    { ... },
    "flags":      []
  },
  "meta": {
    "request_id": "req_9895064e4d4a406795c77c86f212ebd5",
    "timestamp":  "2026-04-25T09:54:04.317565Z",
    "cached":     false,
    "elapsed_ms": 319,
    "backend":    "v2_fleet"
  },
  "error": null
}

On error, data is null and error is an object with code, message, and the HTTP status. The envelope is the same for single-email and bulk requests; bulk just puts an array under data and aggregate counts under meta.

Field rules

  • Every documented field is always present. If we don't know a value, you get null - not a missing key.
  • Empty strings become null. No "" in data fields; you can null-check uniformly.
  • No underscore-prefixed keys. Internal annotations (_source, _norm_*, etc.) are stripped before the response leaves the gateway.
  • No source identity. Raw provider names, internal table names, ingest timestamps - none of those leak. The only source-shaped value you ever see is a public alias in sources_searched.
  • Canonical fields override dataset-specific ones. FMCSA email_address, NSF poc_email, Form 5500 sponsor_phone all surface under canonical email and phone so client code doesn't branch on source.

Headers on every response

X-RateLimit-Burst:                60
X-RateLimit-Refill-Per-Sec:        1
X-RateLimit-Tokens-Remaining:     59
X-RateLimit-Daily-Units-Limit: 10000
X-RateLimit-Daily-Units-Used:     22
X-RateLimit-Concurrent-Limit:      8
X-RateLimit-Concurrent-Now:        1
X-Endpoint-Cost-Units:             2

The header set describes the three real limits - token bucket, daily units, concurrency. X-Endpoint-Cost-Units tells you what THIS specific call cost. See Rate limits for what each header means and the 429 reasons.

For the full set of error codes and HTTP statuses, see Errors.