Updated 2026-08-30
An OSINT lookup API should give an investigator the same thing a careful analyst would produce by hand, faster and with provenance attached. One request runs an OSINT email lookup or username search across hundreds of platforms and returns which accounts exist, breach history and public web mentions, each with a method and timestamp - verified or omitted, never guessed.
Most investigations start with a screen name rather than an email address: the handle on a scam listing, the author of a threatening post, the persona behind a phishing domain. A username lookup reports on which of the 887+ platforms that handle is registered. The example below is a developer-flavoured footprint: the handle exists on GitHub, GitLab, Reddit, Twitch and Keybase, and is confirmed absent from Instagram.
curl -X POST "https://api.digifootprint.dev/v1/lookup?wait=true" \
-H "Authorization: Bearer dfp_your_key" \
-H "Content-Type: application/json" \
-d '{"query": "nightowl_dev"}'{
"lookupId": "e2c58a91-...",
"query": "nightowl_dev",
"platformsChecked": 887,
"matches": 7,
"socialMatches": 7,
"servedFromCache": false,
"results": [
{ "platform": "github", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.081Z" },
{ "platform": "gitlab", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.144Z" },
{ "platform": "reddit", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.207Z" },
{ "platform": "twitch", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.263Z" },
{ "platform": "keybase", "registered": true, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.310Z" },
{ "platform": "instagram", "registered": false, "method": "public_api", "checkedAt": "2026-08-30T15:04:22.398Z" }
],
"breaches": null,
"webMentions": [
{
"title": "nightowl_dev - Profile",
"url": "https://example.org/u/nightowl_dev",
"snippet": "...maintained by nightowl_dev since 2017...",
"matchConfidence": "confirmed"
}
],
"phoneDetails": null
}Two details are load-bearing. breaches is null, not [], because breach data is keyed on email addresses and was not consulted for a handle; an empty list would falsely claim a clean record. And the single web mention is marked confirmed, meaning the exact string appears on the page; an unconfirmed mention is one a search engine returned without the page containing the identifier, and should not go into a report as an association.
Send an email address instead and the same endpoint reports the accounts registered to it, plus the two sources that are only meaningful for email: breaches, a list of named breaches and the date each occurred, and any mailbox-provider account that came with the address, flagged mailboxProvider: true and counted in matches but not socialMatches. Breach dates are the fastest way to bound the age of an address: an identifier in a 2013 breach has existed since at least 2013, whatever its owner now claims. The type of input is detected automatically, so an investigator’s tooling sends whatever it has and gets one shape of answer; see running a lookup for the field-by-field reference.
Phone numbers are a third input, currently in beta. Coverage is limited to the smaller set of platforms that register by number, and phoneDetails adds validity, carrier and line type where those could be established. Treat a phone footprint as a lead to corroborate rather than a result to cite.
A finding without provenance is an anecdote. Every result carries method, which says how the existence of the account was established, and checkedAt, the exact moment it was. servedFromCache tells you whether the response reflects a fresh check or a recent one of the same input, and every checkedAt remains the real time the fact was established even when the response as a whole was cached. The lookupId identifies the lookup for the case file, and past lookups are listable from the API, scoped to your account, so a finding can be retrieved months later exactly as it was at the time.
The omission rule is the other half of provenance. A platform that could not be confirmed, because it blocked the check, timed out or gave an ambiguous answer, is left out of results rather than filled in with a guess. That is why platformsChecked is larger than the array: the difference is the set of unknowns, and an unknown in a report is written as an unknown.
Investigative tooling benefits from results arriving as they land. The streaming endpoint emits each platform result as a server-sent event, the first in well under a second, followed by breach and web-mention events and a closing summary, so a case screen fills in progressively instead of waiting for the slowest platform. For batch work, queue lookups without ?wait=true and poll by id, within the per-key limits described on the rate limits page. Every platform has its own page stating which inputs it accepts, grouped into hubs such as developer, gaming and finance; the full list is the authoritative statement of coverage.
The API reports that an account exists. It does not fetch the account: no display name, photo, bio, post, follower list or location is collected from any platform, which keeps an investigation to the question of association rather than content. Our terms permit business purposes such as fraud investigation, threat intelligence, due diligence and security research, and prohibit stalking, harassment, doxxing, locating or monitoring a person against their wishes, and building a dossier on someone in a personal capacity. The lawful basis for each query is yours to establish. Related patterns for operational teams are on the fraud prevention and trust and safety pages. There are free lookups to start; pricing is on the pricing section.