# Email OSINT Checker, Account Finder, Reverse Lookup, 120+ Sites (`ntriqpro/email-osint-search`) Actor

Enter an email address and find out where it already has an account — 120+ platforms including LinkedIn, Twitter/X, Spotify, Pinterest, Adobe and Imgur. Nothing is sent to the address: no password-reset mail, no notification. Open-source holehe engine. Batch up to 500 addresses per run.

- **URL**: https://apify.com/ntriqpro/email-osint-search.md
- **Developed by:** [daehwan kim](https://apify.com/ntriqpro) (community)
- **Categories:** Lead generation, Social media, Developer tools
- **Stats:** 1,473 total users, 205 monthly users, 99.1% runs succeeded, 4 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Email OSINT Checker, Account Finder, Reverse Lookup, 120+ Sites

**Give it 1 email address and get 1 row per site it is registered on, out of 120+ sites checked — without any password-reset email reaching the target.** Find which accounts an email address has signed up for. This **email lookup / email OSINT** tool discovers **which 120+ sites an email is registered on** — LinkedIn, Twitter, Spotify, Pinterest, Imgur, Tumblr, and many more — without ever sending a password-reset notification to the target. A fast **reverse email search** powered by [holehe](https://github.com/megadose/holehe) (GPL-3.0, 5.6k+ stars), a widely used open-source email OSINT tool.

### What you get

| Capability | Detail |
|---|---|
| **Sites checked** | **120+** per email — LinkedIn, Twitter/X, Spotify, Pinterest, Imgur, Tumblr, Adobe, Atlassian, and more |
| **Silent lookups** | No password-reset emails sent to the target — passive account-existence signals only |
| **Flat, table-ready rows** | One row per account found, with platform, domain and detection method |
| **Bulk mode** | Up to **500 emails** per run |
| **Extra identity hints** | Masked recovery email and masked partial phone, when the platform exposes them |
| **Ready to export** | Download the dataset as JSON, HTML, CSV or Excel |
| **No setup** | No subscription, no scraping config — just an API call |

### Sample result

One dataset item per registered account found — **not** one per email. An address registered on 17 sites produces 17 rows.

```json
{
  "email": "test@gmail.com",
  "platform": "codepen",
  "exists": true,
  "domain": "codepen.io",
  "method": "register",
  "emailRecovery": null,
  "phoneNumber": null,
  "rateLimit": false,
  "charged": true,
  "sitesChecked": 121
}
```

| email | platform | domain | exists | method | rateLimit |
|---|---|---|---|---|---|
| test@gmail.com | codepen | codepen.io | true | register | false |
| test@gmail.com | anydo | any.do | true | login | true |

A live test of `test@gmail.com` returned **17 confirmed accounts across 121 sites checked**.

### Use Cases

- **Security incident response** — given a breached email, map exposure across SaaS
- **Fraud investigation** — confirm an email is a real online identity, not a throwaway
- **Recruiter verification** — confirm candidate email is registered on professional platforms
- **KYC enhancement** — supplement identity verification with online-account footprint
- **OSINT pentesting** — reconnaissance phase for authorized engagements
- **Data-broker compliance** — auditing your own organization's email exposure

Built for **security researchers, fraud investigators, OSINT analysts, KYC teams, and recruiters** who need to verify online presence of a given email address with zero footprint.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `emails` | array of string | ✅ | Up to 500 email addresses to investigate |
| `email` | string | — | Legacy single-email input (use `emails` for batch) |
| `timeout` | integer | — | Per-site timeout in seconds (default 30) |
| `maxEmails` | integer | — | How many emails this run processes; hard cap 500 |

```json
{
  "emails": ["alice@example.com", "bob@example.org"],
  "timeout": 30,
  "maxEmails": 10
}
```

### Output

| Field | Type | Description |
|---|---|---|
| `email` | string | The address checked |
| `platform` | string | Platform short name, e.g. `codepen` |
| `domain` | string | Platform domain, e.g. `codepen.io` |
| `exists` | boolean | `true` when an account was detected on that platform |
| `method` | string | How existence was detected: `register`, `login` or `other` |
| `rateLimit` | boolean | `true` when holehe flags this site as one that **throttles frequent lookups** (a static property of the site, not a failure of this lookup) — the account is still confirmed, so the row **is charged**; the flag simply tells you the site is worth re-verifying |
| `charged` | boolean | `true` when this row was billed as an `account-found` event |
| `emailRecovery` | string | Masked recovery-email hint, when the platform exposes one (else `null`) |
| `phoneNumber` | string | Masked partial phone, when the platform exposes one (else `null`) |
| `sitesChecked` | integer | Total platforms probed for this email |
| `disclaimer` | string | Legal-use notice, repeated on every row |

A confirmed account on a site holehe flags as frequently rate-limiting — still billed, with `rateLimit: true` telling you the site is worth re-verifying:

```json
{
  "email": "test@gmail.com",
  "platform": "anydo",
  "exists": true,
  "domain": "any.do",
  "method": "login",
  "emailRecovery": null,
  "phoneNumber": null,
  "rateLimit": true,
  "charged": true,
  "sitesChecked": 121
}
```

When an address is registered nowhere, you get a single summary row instead
(`platform: null`, `exists: false`, `foundCount: 0`, plus a `note`), so a
succeeded-but-empty run is never confused with a failure. A per-email failure returns
one row carrying an `error` field.

You can download the dataset as JSON, HTML, CSV or Excel.

### Pricing

**Run start fee — from 10 September 2026:** $0.005 is charged once per run, when the run starts and performs the investigation. Existing per-result prices are unchanged.

**$0.02 per registered account found** (event: `account-found`).

**Free plan:** each run returns up to 25 results (the first 3 inputs). Paid Apify plans
receive the full result set. A free-plan run that reaches the sample limit finishes
successfully with a `free-plan-cap` notice row — it is a plan limit, not an error.

| What you run | Accounts found | Cost |
|---|---|---|
| 1 typical personal address | 10–30 | **$0.20 – $0.60** |
| 25-address batch | 250–750 | **$5 – $15** |
| 1,000 confirmed accounts | 1,000 | **$20.00** |

A live test of `test@gmail.com` returned **17 confirmed accounts, all 17 billable — $0.34**.

Only confirmed accounts are billable — summary and notice rows are not. Every row tells
you whether it was billed: `charged: true` means the account counted toward your bill,
`charged: false` means it did not. Apify platform compute is included —
there is no separate compute charge. Set the run's **maximum cost** in Run options before
a large batch.

#### Large batches and the run charge limit

Every Apify run has a maximum cost, which you set per run (or per schedule) in the Actor's **Run options**. This Actor accepts up to **500 email addresses in a single run**, and a big batch can easily find more accounts than the default limit covers.

When a run reaches its charge limit, this Actor **stops checking and finishes successfully** with everything it found up to that point, plus a final `Charging limit reached` record explaining what happened. You are never charged past your limit, and the run is not reported as a failure.

To get the full batch, do one of the following:

- **Raise the run's maximum cost** in Run options before starting, or
- **Split the email addresses across several runs** — for example 25 emails per run instead of 500.

### Quick Start

#### curl

```bash
curl -X POST "https://api.apify.com/v2/acts/ntriqpro~email-osint-search/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["alice@example.com"]}'
```

#### Python (Apify Client)

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("ntriqpro/email-osint-search").call(run_input={
    "emails": ["alice@example.com", "bob@example.org"]
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
for item in items:
    if not item.get("exists"):
        continue
    flag = " (site frequently rate-limits — re-verify)" if item.get("rateLimit") else ""
    print(f"{item['email']} -> {item['platform']} ({item['domain']}){flag}")
```

### Technology

- **[holehe](https://github.com/megadose/holehe)** (GPL-3.0) — Email-based account existence checker, 5.6k+ stars
- **[Apify SDK for Python](https://docs.apify.com/sdk/python)** (Apache 2.0) — Actor runtime
- **[httpx](https://www.python-httpx.org/)** (BSD) — Async HTTP client

### Limitations

| Limitation | Detail |
|---|---|
| Sites that frequently rate-limit | holehe flags ~10-15% of sites as ones that throttle frequent lookups. Confirmed accounts on those sites are flagged `rateLimit: true` so you can re-verify |
| False positives | Existence signals can be ambiguous; treat as leads, not proof |
| New site discovery | holehe upstream adds sites quarterly; we update with library releases |
| Rate limiting | Recommended: batch <10 emails per run to avoid IP-based throttling |

### Disclaimer

> **Legal Disclaimer:** This Actor is an unofficial integration of holehe (megadose) and is not affiliated with or endorsed by the original project. Use only on email addresses you own or have explicit authorization to investigate. Comply with PIPA (KR), GDPR (EU), CCPA (US), and applicable privacy laws.

This Actor is an **unofficial** open-source wrapper around megadose/holehe. It is not affiliated with, sponsored by, or endorsed by the holehe project, its maintainers, or any of the platforms being probed. OSINT results are based on publicly observable account-existence signals and may produce false positives.

**You are solely responsible** for ensuring you have legal authorization to investigate any email address. Misuse may violate privacy laws (PIPA, GDPR, CCPA, etc.) and the terms of service of target platforms. This tool is intended for security research, fraud prevention, and authorized investigation use only.

#### Privacy & data responsibility

**You are the data controller** for every search you run with this Actor; ntriqpro is a **data processor** acting solely on your instructions. You are responsible for having a lawful basis and a legitimate, purpose-limited reason for each lookup, and for complying with GDPR, PIPA, CCPA, and other applicable privacy laws. **We do not store your results** — output is written only to your own run's dataset and is never retained on our side. Use this Actor only for lawful purposes and only on email addresses you own or are authorized to investigate.

***

### 🔗 Related Actors by ntriqpro

**Running several of these by hand?** [**OSINT Recon Suite**](https://apify.com/ntriqpro/osint-recon-suite) takes one target — email, username, domain or phone — runs Maigret, Sherlock, holehe, theHarvester, WHOIS and dnstwist against it, then correlates everything into a single risk-scored report. One input, one report, instead of six separate runs to stitch together yourself.

Build your full OSINT stack:

- [**maigret-actor**](https://apify.com/ntriqpro/maigret-actor) — Username OSINT across 3000+ sites (5.0★ rated)
- [**phoneinfoga-osint**](https://apify.com/ntriqpro/phoneinfoga-osint) — Phone number OSINT — carrier, country & footprint
- [**dnstwist-osint**](https://apify.com/ntriqpro/dnstwist-osint) — Typosquatting & phishing domain detector
- [**subfinder-osint**](https://apify.com/ntriqpro/subfinder-osint) — Subdomain finder for attack-surface mapping
- [**gitleaks-secret-scanner**](https://apify.com/ntriqpro/gitleaks-secret-scanner) — Find leaked secrets in public repos

### ⭐ Rate this Actor

If this saves you investigation time, please [leave a review](https://apify.com/ntriqpro/email-osint-search/reviews) — it helps other security researchers discover it.

# Actor input Schema

## `emails` (type: `array`):

List of email addresses to investigate (max 500). Use only addresses you own or have authorization to investigate. Free plan: each run returns up to 25 results (the first 3 inputs). Paid Apify plans receive the full result set.

## `email` (type: `string`):

Alternative single-email input. Use 'emails' for batch.

## `timeout` (type: `integer`):

Maximum time to wait for each site check. Default: 30 seconds.

## `maxEmails` (type: `integer`):

How many emails this run may process (hard cap 500). Each email is checked against 120+ sites in turn, so a large batch is a long run — the Actor automatically trims the batch to what the remaining run time can carry. Free plan: each run returns up to 25 results (the first 3 inputs). Paid Apify plans receive the full result set.

## Actor input object example

```json
{
  "emails": [
    "test@gmail.com"
  ],
  "timeout": 30,
  "maxEmails": 5
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "emails": [
        "test@gmail.com"
    ],
    "timeout": 30,
    "maxEmails": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("ntriqpro/email-osint-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "emails": ["test@gmail.com"],
    "timeout": 30,
    "maxEmails": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("ntriqpro/email-osint-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "emails": [
    "test@gmail.com"
  ],
  "timeout": 30,
  "maxEmails": 5
}' |
apify call ntriqpro/email-osint-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ntriqpro/email-osint-search"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dNJ28LaGMyaihcFND/builds/XhnsbajvUyem92ZQA/openapi.json
