Checks: choosing what a lookup runs

The checks object decides what one lookup runs and what it costs. The footprint runs by default; email, phone and IP intelligence run when you ask for them; riskSignals adds the reasons behind the scores. Every key and option is on this page.

The keys

KeyValuesDefaultWhat it runs
footprinttrue | false | { early, hits, maxWaitMs, email, phone }onThe platform sweep for each identity sent (email, phone, username), plus breach history and web mentions. An options object switches it on, configures the early answer, and controls each identity: email: false skips the email/username sweep, phone: false skips the phone sweep, phone: { platforms: [...] } picks the phone platforms.
emailtrue | falseoffEmail intelligence for the email sent: deliverability, disposable, webmail, role address, catch-all, the domain (age, registrar, mail servers, SPF, DMARC) the breaches the address appears in (count, first and last seen, and each breach by name), and how old the address itself is - the earliest dated evidence it existed.
breachesfalseonSend false to skip the breach lookup entirely: nothing is looked up, and footprint.breaches and email.breaches come back null (not checked). Never billed on its own.
phonetrue | falseoffPhone intelligence for the phone sent: validity, E.164 and national format, carrier, line type, VOIP class; SIM swap and call forwarding on higher plans.
iptrue | falseoffIP intelligence for the ip sent: VPN, proxy, Tor, residential proxy, datacenter, compromised, network owner and location.
riskSignalstrue | falseoffAdds the named reasons (signals) behind every risk score. Not a module and never billed. Scores are returned either way.

Off means not run and not billed. Sending an ip without "ip": true does not run the IP module. An unknown key is ignored rather than rejected, so check that the field you expected is filled. Sending checks at all makes the request answer synchronously, as with ?wait=true.

POST /v2/lookup?wait=true
{
  "email": "someone@example.com",
  "phone": "+14155552671",
  "ip": "8.8.8.8",
  "checks": {
    "footprint": { "early": true, "hits": 3, "maxWaitMs": 2500 },
    "email": true,
    "phone": true,
    "ip": true,
    "breaches": true,
    "riskSignals": true
  }
}

footprint

Runs once per identity you send - an email and a phone together are two sweeps and two footprint units, each result naming its identity. It also brings breach history and web mentions, and powers the rules that read online presence (such as “no accounts anywhere”). "footprint": false skips all of that, which is how a modules-only check answers in about a second.

Early answer (v2): pass an options object instead of true.

OptionValuesDefaultMeaning
earlytrue-Answer as soon as the first real profiles are in, then finish the search in the background on the same lookup.
hits1 - 103How many real profiles each identity needs before the answer goes out. A number - not the footprint.hits list in the response.
maxWaitMs500 - 150002500Hard ceiling on the first answer. At this point it goes out with whatever is in.
emailfalseonSkip the email/username sweep even when an email or username was sent. Its other modules (email check, breaches) still run. No footprint charge for it.
phonefalse | { platforms }default platformsfalse skips the phone sweep. { "platforms": ["whatsapp", "telegram", "facebook"] } runs exactly those - an unknown key is a 400. Omit it for the default set (WhatsApp and Telegram).

The early answer waits for every module you asked for, and for each identity to reach hits real profiles (accounts that say something about the person - not a mailbox provider’s own account, not a guess from the handle) or finish its sweep, capped by maxWaitMs. It comes back with "status": "processing" and meta.footprintComplete: false; the search completes the same lookup in the background, then GET /v2/lookup/:id returns completed, every profile and a re-scored risk, and the lookup.completed webhook fires once. Early answer is ignored with ?instant=true, which has its own ceiling. See running a lookup.

email, phone, ip

Each runs on the matching input and returns its own object - email, phone, ip - each with its own risk. Asking for a module without its input does nothing and costs nothing. The same data is available on its own from POST /v2/email, /v2/phone and /v2/ip, which skip the footprint.

riskSignals

Scores come back on every plan; "riskSignals": true adds the named reasons - id, label, points and severity - at the top level and on each module. Named signals are included on pay as you go and every subscription; on the free plan the flag is accepted and the scores still come back, without the signals. How scores and rules work: risk scores.

Billing and plan limits

Each module that runs is billed: an email/username footprint per identity swept, one email, phone or IP check each, and a phone footprint per platform that actually runs - with early, the phone platforms run one at a time and stop once the answer is in, so a platform that never ran is never billed. When a request runs every part of a bundle (email identity, phone identity, full check), it pays the parts less the plan's bundle discount. Every rate is on the rate card. The free plan's caps are lifetime, and it does not include the phone footprint.

On a stream

GET /v2/lookup/stream cannot carry an object, so checks are a comma list, with a - prefix to switch one off, and the early answer is two plain parameters:

GET /v2/lookup/stream
/v2/lookup/stream?email=someone@example.com&ip=8.8.8.8&checks=email,ip,riskSignals&early=true&hits=3
/v2/lookup/stream?email=someone@example.com&checks=-footprint,email
/v2/lookup/stream?phone=%2B2348031234567&checks=footprint.phone=whatsapp|telegram|facebook
/v2/lookup/stream?email=someone@example.com&phone=%2B2348031234567&checks=-footprint.email,phone

With early=true the stream sends one footprint.early event when the condition is met and carries on to done. See streaming.

Common recipes

Sign-up screening in about 2 seconds
{ "email": "…", "ip": "…", "checks": { "footprint": { "early": true }, "email": true, "ip": true, "riskSignals": true } }
IP only, sub-second (no footprint)
{ "ip": "…", "checks": { "footprint": false, "ip": true } }
Footprint without the breach lookup
{ "email": "…", "checks": { "breaches": false } }
Full profile of a person, both identities
{ "email": "…", "phone": "…", "checks": { "email": true, "phone": true, "riskSignals": true } }