Updated 2026-08-30
The same endpoint runs at three depths. Instant is a fast email lookup held to a 600 millisecond ceiling by default; standard is the full band of platforms checked on every lookup; deep adds the long tail and takes as long as it takes. This guide says what each returns and which one fits where.
Every depth is POST /v1/lookup with a different query string, and every depth returns the same shape. What changes is how many platforms are consulted and how long you wait. The three are nested: the instant set is the top of the standard band, and the standard band is the front of the deep one, so moving up a depth adds platforms without changing any answer already given. Below, the map from intent to call.
# Instant: 25 platforms for an email, ~600ms ceiling, always synchronous POST /v1/lookup?instant=true # Standard: the default band of 887, a few seconds POST /v1/lookup?wait=true GET /v1/lookup/stream?query=... # same band, one event per platform # Deep: 1,244 platforms including the long tail, unbounded POST /v1/lookup?wait=true&deep=true POST /v1/lookup # async job - already runs deep; poll by lookupId
?instant=true runs a high-signal subset - 25 platforms for an email address, 25 for a username, ranked separately per input so a slot is never spent on a platform that cannot answer for that kind of query - and holds the whole lookup to a wall-clock ceiling of 600 milliseconds by default. When the deadline fires it returns whatever has answered. Anything still in flight is omitted, never reported as negative, and platformsPending says how many were left. The response also carries instant: true and deadlineMs, so a consumer can tell an instant answer from a full one. It is always synchronous; wait is not needed.
curl -X POST "https://api.digifootprint.dev/v1/lookup?instant=true" \
-H "Authorization: Bearer dfp_your_key" \
-H "Content-Type: application/json" \
-d '{"query": "someone@example.com"}'{
"query": "someone@example.com",
"instant": true,
"deadlineMs": 600,
"platformsChecked": 25,
"platformsPending": 3,
"matches": 3,
"socialMatches": 2,
"derivedMatches": 0,
"servedFromCache": false,
"results": [
{ "platform": "google", "registered": true, "method": "domain_derived", "checkedAt": "2026-08-30T15:10:44.020Z", "mailboxProvider": true },
{ "platform": "github", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:10:44.151Z" },
{ "platform": "instagram", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:10:44.233Z" },
{ "platform": "spotify", "registered": false, "method": "public_api", "checkedAt": "2026-08-30T15:10:44.298Z" }
],
"breaches": [{ "name": "Canva", "date": "2019-05-24" }],
"webMentions": [],
"phoneDetails": null
}The subset is small on purpose. Below a certain count every check goes out at once and the wall clock is set by the slowest member, not the number; past it, requests queue and the cost becomes linear. A 600 millisecond ceiling over the whole band would return almost nothing, so the instant tier is sized to the point where it returns a lot. Use it when you are fanning out to several services per transaction and cannot absorb a slow one: signup, checkout, login risk. Platforms in the tier include GitHub, Instagram, Spotify and Google; each platform page says whether it is on the instant path.
A plain ?wait=true lookup runs the standard band - the 887 platforms checked on every lookup - and blocks until they have all answered or timed out, which takes a few seconds. This is the depth the social profile lookup and most of the docs describe, and it is the right default when the caller can wait: review queues, enrichment jobs, an analyst’s search box. The streaming endpoint runs the same band and emits one event per platform as it lands, so a UI shows the first matches within a fraction of a second and fills in the rest without a spinner. In practice, streaming standard is what makes the full band feel instant to a person watching it.
?deep=true extends the sweep past the standard band to the full registry of 1,244 platforms: the long tail of forums, niche communities and regional services that rarely matter for a signup score and often matter for an investigation. It is slower and unbounded - coverage over latency, by design. The async path already runs at this depth: a POST without wait returns a lookupId to poll and does the deep sweep in the background. Pair deep with streaming when a person is waiting, and with the async job when a pipeline is. It suits OSINT and trust and safety work where a hit on an obscure platform is the point.
Ask two questions. Is a person or a request waiting on the answer, and does a miss on a small platform change the decision? A request path with a latency budget - signup, checkout, a fraud model fanning out to several APIs - wants instant, and can queue a deeper lookup afterwards. A person waiting in a dashboard wants standard over the stream. An investigator or a moderator wants deep, and will happily wait or poll. Whatever the depth, the guarantees are the same: checkedAt is the real time each fact was established, servedFromCache flags reuse, an unknown is omitted rather than guessed, and nothing from inside an account is returned. The full parameter list is in the lookup reference. Free lookups to start - see pricing.