Back to Blog

OSINTsearch Deep Search: Recursive Username Pivoting From One Handle

7 exports, 1,453 profile rows, 139 rows carrying linked_socials, 2 bio_link hops and 1 email_prefix candidate. How OSINTsearch Deep Search pivots on usernames, and how to gate the pivots it makes.

Bob Adams

Threat Analyst at Revealer

One handle in, 547 profiles out is the coverage story. The pivoting story is smaller and more useful. Across seven OSINTsearch exports from 2026-09-05, 139 rows carry a linked_socials list, two rows arrived by a bio_link hop instead of the primary scan, one username variant came from a TikTok URL inside a link-in-bio page, one from an ENS name, one domain surfaced from a Stack Overflow profile field, and one email run produced exactly one email_prefix candidate. That is recursive username search as the file shows it. This post covers how OSINTsearch Deep Search works, where each discovered handle is recorded, how it compares to Maigret and to Revealer's AI Deep Search, and how to stop a dictionary handle like richard from pivoting you into a stranger's footprint.

Disclosure up front: we build Revealer.US, including AI Deep Search. Assume bias and check our work. Every count below is from a named, dated export.

What username pivoting is, and how analysts did it by hand

Username pivoting is the step after enumeration. Enumeration asks where srhoe exists. Pivoting takes each new handle, link, email prefix or domain those profiles reveal and runs it again. Done well it turns one handle into a footprint. Done badly it turns one handle into a case file about three unrelated people.

The manual version: run Sherlock (413 sites on 0.16.0, URLs only), then Maigret (509 sites by default, and it recurses on extracted IDs on its own), then open every profile with a bio, a website field or a link-in-bio page, copy the handles out by hand, decide which look like the same operator, run those, repeat. That last step is where the time goes and where the errors come from. Nothing in the loop records why you followed a handle, from which profile, at what depth. Six weeks later the case file says "also uses 5rh0e" and nobody can say where that came from.

How OSINTsearch Deep Search pivots

The site's wording is "Deep search follows usernames found in your results". On features and pricing, the Pro tier at $49.99 a month lists "deep search depths 1 to 4"; Starter at $20 and Free at $0 list no depth setting. Depth 1 takes the handles found inside your primary results and scans them once. Depth 4 repeats that four times, each round seeded by the last.

The export carries the trail in three places.

The source field on every row. We saw two values in use, primary scan and bio_link. The schema documents a third, cross_reference, which appeared on no row in these runs.

The seed columns in the CSV. The header carries source, source_kind, alias, seed_username, seed_depth, seed_kind and seed_evidence side by side, at positions 78 to 84 in the investigation CSV we opened on 2026-09-06. A row produced by a hop says which handle seeded it, at what depth, what kind of seed it was, and what evidence triggered the follow. That is the audit trail the manual loop never had. One caveat: the JSON rows we exported carried source but no seed fields. The schema 3 export from the 21:24 srhoe run instead carries a top-level deep_search block whose seeds list gives each swept handle its depth, kind and discovered count.

The identity block. identity.username_variants lists each discovered handle with a per-platform sources list. identity.websites lists each URL with the platform that exposed it. identity.probable_name carries a confidence, a sources list and alternatives. On the email run, cross_references holds discovered and candidates, each candidate with a username, a source and a type.

What we looked at

Seven OSINTsearch exports, all run on 2026-09-05: richard (09:20), meme (09:21), cia (09:31), srhoe (09:24, with reruns at 21:20 and 21:24), deadcatx3 (09:32), davidbombal (21:27) and the email corpus run on surfinup8 (09:36). Morning runs exported schema 2; evening runs exported schema 3, which adds a search block, a source_kind on every row, and profile_links and profile_pictures. We read every file with Python and counted the pivot-bearing fields directly. This post prints no personal values from any row, handles only, with davidbombal named as the public YouTube educator he is.

The pivot inventory, per subject

Subject Rows Rows with linked_socials Non-primary rows username_variants added websites[]
richard 547 52 0 4 (incl. richard.eth) 6
meme 446 40 0 5 6
cia 329 29 1 bio_link 7 (incl. cia.eth) 6
davidbombal 59 9 0 1 (davidbombal.eth) 2
srhoe (09:24) 37 7 1 bio_link 1 (5rh0e) 1 (srhoe.com)
deadcatx3 21 2 0 1 (nervequake) 0
surfinup8 (email) 14 0 0 1 (the address itself) 0

Three rows show three different kinds of hop.

srhoe to 5rh0e, a real bio_link hop. The hoo.be row for srhoe returned six linked_socials entries: twitch, instagram, twitter, tiktok, discord and a youtu.be link. The tiktok entry pointed at @5rh0e. OSINTsearch followed it and added a 37th row with platform: tiktok, username: 5rh0e, source: bio_link. This is what Deep Search is for: a handle no permutation generator would produce, reached only because a link page said so.

deadcatx3 to nervequake, a variant without a hop. The row for archive.org/details/@deadcatx3 came back with username: nervequake and source: primary scan. Nothing was followed. The engine noticed the page reports a different current handle and put nervequake into username_variants with sources: ["archiveorg"]. That is "Former handles where supported", and it exists only because archive.org exposes it. The former-handle column set is covered in /blog/former-usernames-osint-investigations.

davidbombal to davidbombal.eth, a namespace pivot. The ens row is a primary-scan hit carrying the export's only wallets entry, and .eth lands in username_variants with sources: ["ens"]. The same module produced richard.eth and cia.eth. An ENS hit is not evidence of the same operator, and the identity block does not claim it is.

The cia bio_link row is the cautionary one. The hoo.be page for cia listed instagram, twitch and cia.gov. The Twitch handle is not cia; OSINTsearch scanned it and added row 329 with source: bio_link. Whether that account relates to any of the other 328 rows is unknowable from the export.

The surfinup8 email run is the cleanest. cross_references.discovered is empty and candidates holds one object: {"username": "surfinup8", "source": "email_prefix", "type": "email_prefix"}. The engine proposed the local part of the address as a username and recorded it as a proposal, not a finding. websites[] works the same way: srhoe.com is listed with sources: ["stackoverflow"] and nowhere else, davidbombal.com with twitter and tap_bio.

What linked_socials actually look like

Every linked_socials value is a list of objects with two keys, platform and url. Across the 139 rows the labels, case-folded, were twitter (76 entries), internetarchive_item (72), instagram (36), facebook (29), youtube (19), github (16), discord (12) and tiktok (12), then a long tail of free-text labels lifted from link-in-bio pages, such as "Amazon Wish List", "Cash App" and "main tiktok account", and 19 entries with an empty label.

The internetarchive_item count is a warning. Those are Wayback links, not accounts. The deadcatx3 periscope row shows the same problem: six entries labelled twitter, among them x.com/sitemap.xml, x.com/tos and x.com/privacy. A link scraper picked up boilerplate and called it a social link. Followed unfiltered at depth 4, a dictionary handle would fan out into thousands of irrelevant rows. In our runs it did not: the two bio_link rows are the only follows. The morning exports do not state which depth was set. The 21:24 srhoe rerun does: its deep_search block records requested_depth: 3, depth_label: "Deep", four swept seeds (5rh0e among them, read from the same hoo.be links), total_discovered: 0 and max_depth_reached: 1. Both evening reruns produced 31 rows with no bio_link row and no 5rh0e variant: the seeds were swept and yielded nothing. The hop fires when a source page provides a clean link; it is not a guarantee on every run.

The false-positive risk on dictionary handles

richard returned 547 profiles. Those are a few hundred people who share a common first name, not one person. The identity block says so quietly: probable_name on richard carries confidence: 0.01, backed by three sources out of 547, with four alternatives each backed by two. meme is 0.02 across seven sources. cia is 0.01, the value is "Central Intelligence Agency", and the alternatives include a neocities subdomain. Compare davidbombal at 0.31 across 18 sources, the closest thing to a single-owner handle in the set, and srhoe at 0.11 in the morning and 0.13 in the evening.

Read that number before you turn on Deep Search. At 0.01 the engine cannot find agreement on who the handle is, so any pivot from a bio on one of those 547 rows moves from one stranger to another. At depth 4 on richard you are four strangers removed from your subject. The site's own caution applies: "Shared details can suggest a connection; verify it before treating accounts as the same person." The fix is to gate every pivot and let the seed columns keep the books.

Signal on the seed row and the candidate row Verdict Action
Same avatar (avatar_url or the profile_pictures block) and same display name Strong Follow, keep, mark verified
Same avatar, different display name Moderate Follow, keep, mark for review
Candidate bio names the seed handle, or websites[] on both point at the same domain Strong Follow, keep, cite the bio in seed_evidence
created_at within a few weeks and the same location field Weak Follow, keep, do not chain further
Candidate appears only in linked_socials of a link-in-bio page, no other overlap Weak Follow once, do not chain, keep only if a second signal appears
Candidate reached from an internetarchive_item entry or site boilerplate None Do not follow
Seed handle has probable_name.confidence under 0.05 None Do not run Deep Search above depth 1
Candidate is an ENS or wallet variant None on its own Record the variant, do not treat as the same person

Sock puppet detection is the mirror image of the same table. A puppet operator reuses an avatar, a bio phrase or a link across handles that share no characters, so the avatar and bio rows are where puppets show up, and created_at is where a burst of same-week registrations does. The seed columns matter when you hand the case on: seed_username, seed_depth and seed_evidence let the next analyst reject a chain at the link where it went wrong instead of discarding the file. The osintsearch.org quota argues the same way: 15 searches a week on Free and 500 on Pro, reset Monday 00:00 UTC, and a depth-4 run on a wide handle spends a lot of that on strangers.

Honest comparison: OSINTsearch, Maigret, fingerprint.to, Revealer

Tool Recursive username search Where the trail is recorded Depth control Cost
OSINTsearch Deep Search Follows handles found in results; bio_link and cross_reference sources source and seed columns; a deep_search block in schema 3; username_variants with per-platform sources; cross_references.candidates Depths 1 to 4 on Pro ($49.99/mo) Free tier 15 searches/week, no depth listed
Maigret 0.6.5 On by default; recurses on extracted IDs and usernames Console output and report On or off, no depth number Free, CLI
fingerprint.to Deep search toggle; export carries discovered_usernames extras.social_links and extras.links per row On or off Paid
Revealer.US username search None on the sweep itself crossReferences array, empty on all three runs we opened None Paid
Revealer.US AI Deep Search Hop-by-hop correlation with a confidence per link, Gemini-driven One sourced report per run Model-driven, no depth setting Basic plan and above

Maigret did the recursion first and does it for free. What it lacks is a normalized export where each row says which seed produced it. The discovery is in the console; the provenance is yours to write down.

fingerprint.to has the same idea under a different name. Every fingerprint export we opened carries a "Deep search" summary field, off on our runs, and an empty discovered_usernames array. Its per-row extras.links on srhoe are richer than OSINTsearch's linked_socials: one row returned a keyed object with discord, facebook, instagram, tiktok, twitter and youtube handles side by side. We did not run its deep mode. On the primary sweep it beat OSINTsearch on srhoe (46 rows to 37) and davidbombal (69 to 59), and sat within one on deadcatx3 (22 to 21).

Revealer's username sweep does not pivot, and its AI Deep Search is a different product. Our srhoe report from 2026-09-05 lists 35 profiles from 813 sources and an empty crossReferences array; davidbombal lists 57 from 813, also empty; the deadcatx3 advanced export from 2026-09-04 lists 28 platforms, also empty. That is a loss against OSINTsearch on the pivot question. AI Deep Search is where Revealer correlates: it takes a username, email or phone, runs the hops itself, and attaches a source and a confidence to each link in a generated report. It is not a depth-controlled recursive scan and it emits no seed_depth column. A workflow that needs a mechanical trail in a CSV is closer to OSINTsearch's schema; one that needs the breach and stealer-log corpus in the same run still lives on Revealer's data breach lookup and stealer logs.

Where OSINTsearch is unusual, anchored on the exports: none of the other exports we opened carries a per-row source value separating a primary hit from a followed link, seed columns, or a username_variants block with per-platform sources. Our broader read is in /blog/osintsearch-review-2026; the OSINT search benchmark this series extends is /blog/username-search-tools-benchmark-2026, where OSINTsearch was not yet a participant.

Frequently asked questions

What does OSINTsearch Deep Search actually do? It follows usernames found in your primary results and scans them as new seeds, to a depth of 1 to 4 on Pro. In our 2026-09-05 exports the follows appear as rows with source: bio_link, discovered handles sit in identity.username_variants with their source platform, and the CSV carries seed_username, seed_depth, seed_kind and seed_evidence.

How many pivots did it make on our runs? Two rows arrived by bio_link, one on cia and one on srhoe, both from hoo.be pages. 5rh0e, nervequake and davidbombal.eth came from source pages rather than hops. The surfinup8 email run produced one email_prefix candidate. 139 rows across the seven exports carry a linked_socials list a deeper run could have followed.

Is Deep Search safe on a common handle like richard? Not above depth 1. richard returned 547 profiles with a probable_name confidence of 0.01. Gate on avatar, bio, shared domain and join date before chaining, and skip it when the confidence is that low.

How does it compare to Maigret's recursive mode? Maigret recurses by default, for free, with no depth number and no per-row provenance in a normalized export. OSINTsearch charges for depth control and records the chain in seed columns. If you need the behaviour, Maigret; if you need the audit trail, OSINTsearch.

Is this the same as Revealer's AI Deep Search? No. Revealer's AI Deep Search is a model-driven correlation that produces one sourced report with a confidence per link, not a depth-controlled recursive scan, and Revealer's plain username sweep exported an empty crossReferences array on all three subjects we checked.

Can I use any of this for a background check? Not Revealer. It is not a consumer reporting agency, and its data may not be used for employment, tenant, credit, or insurance eligibility decisions. OSINTsearch's own caution, that a shared identifier "is an investigative lead" and "does not establish that records belong to the same person", applies to every hop described here.

Get started

Ready to check your exposure?

Create a free account. Every result is pulled live, in real time, from public sources and endpoints we do not own. We do not retain your search data. Items you choose to save, publish, or monitor are kept until you delete them.

Create account