People
Public-records aggregation - names, addresses, phones, relatives, emails. Uncensored on every plan, because the records are published filings.
POST /people/search
Search public records
Aggregated lookups against US public-records sources. Public records are published filings, so every plan receives whole records - addresses, phones, relatives, emails, and a profile_id to drill into. Nothing on this surface is censored on any plan, and the envelope's censored is always false.
The search is metered rather than gated: it spends one unit of the people allowance, which is the shared lookups pool under pooled metering and the separate people_searches counter under per_surface.
What you send.
JSON body, required.
type string required
One of name, phone, address, email
first_name string
last_name string
city string
state string
zip_code string
phone string
street string
email string
What comes back.
200 Search results, whole records on every plan.
success boolean required
data object
records array of object
Public records are published filings, so every plan receives the whole record. There is no censored variant and no per-record
censoredflag.source string
Which of our record sets this row was recovered from, as a stable ordinal (
source_1,source_2). Two rows carrying different values are separate filings that agree, which is the half of this field worth reading; a lookup always reaches every set that accepts the identifier, so there is nothing here to select or tune.name string
full_name string
age any
location string
profile_id string
aliases array of string
past_locations array of string
relatives array of any
phone_numbers array of any
current_address object
Open object, with no fixed keys.
past_addresses array of any
emails array of any
total_results integer
results_on_page integer
censored boolean
Always
falseon this surface. People search is not censored on any plan; the field is kept for envelope shape.plan_id string
Starter is a retired legacy id and is not a checkout target.
One of free, starter, professional, premium, team
400 The request was malformed or invalid.
success boolean required
error string required
code string
Machine-readable error tag. Omitted whenever it is empty, which is most generic errors, so branch on status too.
One of quota_exceeded, hourly_limit, file_access_limit, plan_upgrade_required, upgrade_required, feature_not_enabled, email_verification_required, monitor_limit, monitor_surface_not_allowed, monitor_first_seen_not_allowed, monitor_webhook_invalid, monitor_webhook_not_allowed, monitor_webhook_key_required
429 An allowance was exhausted, or a per-hour cap was hit. Which allowance depends on `metering`: a pooled plan drains one `lookups` pool, while the free tier can run out on one surface with the others still open. The same code covers counters that sit on different clocks, so read `resets_at` and `unlocks_reset_at` from `GET /search/stats` to learn when the allowance you hit comes back.
The same shape as 400.
503 This surface is disabled or unreachable.
The same shape as 400.
POST /people/profile
Drill into a profile
Resolve a profile_id (returned in search results) into the full profile document. Open on every plan: the drill-in is metered rather than plan-gated, spending one unit of the people allowance the same way the search itself does.
What you send.
JSON body, required.
profile_id string required
Opaque token from a People search result.
What comes back.
200 Full profile. Structure varies by record.
success boolean required
data object
Open object, with no fixed keys.
400 The request was malformed or invalid.
success boolean required
error string required
code string
Machine-readable error tag. Omitted whenever it is empty, which is most generic errors, so branch on status too.
One of quota_exceeded, hourly_limit, file_access_limit, plan_upgrade_required, upgrade_required, feature_not_enabled, email_verification_required, monitor_limit, monitor_surface_not_allowed, monitor_first_seen_not_allowed, monitor_webhook_invalid, monitor_webhook_not_allowed, monitor_webhook_key_required
403 The account does not hold the full-profile entitlement. Every declared plan carries it, free included, so this is reserved for a custom plan an admin has authored without it - read `people_full_profile` from `GET /search/stats` to know in advance. The code here is `upgrade_required`, not the longer `plan_upgrade_required` the device gates send.
The same shape as 400.
429 An allowance was exhausted, or a per-hour cap was hit. Which allowance depends on `metering`: a pooled plan drains one `lookups` pool, while the free tier can run out on one surface with the others still open. The same code covers counters that sit on different clocks, so read `resets_at` and `unlocks_reset_at` from `GET /search/stats` to learn when the allowance you hit comes back.
The same shape as 400.
POST /people/geocode
Geocode a US address
Resolves a structured US address to map coordinates - the lookup behind the profile map. US addresses only, so there is no country field. Unknown JSON fields are rejected and the body is capped at 8 KiB. Consumes no quota.
What you send.
JSON body, required.
street string
city string
state string
zip_code string
What comes back.
200 Coordinates for the address.
success boolean required
data object
lat number, double
lng number, double
400 The request was malformed or invalid.
success boolean required
error string required
code string
Machine-readable error tag. Omitted whenever it is empty, which is most generic errors, so branch on status too.
One of quota_exceeded, hourly_limit, file_access_limit, plan_upgrade_required, upgrade_required, feature_not_enabled, email_verification_required, monitor_limit, monitor_surface_not_allowed, monitor_first_seen_not_allowed, monitor_webhook_invalid, monitor_webhook_not_allowed, monitor_webhook_key_required
404 The address parsed but has no known coordinates.
The same shape as 400.
502 The upstream geocoder failed.
The same shape as 400.
503 The geocoder is not configured.
The same shape as 400.