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, NSFpoc_email, Form 5500sponsor_phoneall surface under canonicalemailandphoneso 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: 2The 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.