# Socialscan Email & Username Account Discovery (`khadinakbar/socialscan-osint`) Actor

Check authorized email addresses and usernames against Socialscan's public registration-validation integrations and return structured TAKEN, AVAILABLE, INVALID, and ERROR evidence.

- **URL**: https://apify.com/khadinakbar/socialscan-osint.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, MCP servers, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 identifier scanneds

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

## Socialscan Email & Username OSINT Account Discovery

Socialscan Email & Username OSINT gives security, trust-and-safety, and brand-protection teams one validated dataset row per authorized email address or username. Each row contains per-platform account-status signals, counts, timing, and an optional public profile URL for username responses. The Actor uses public registration-validation responses; it does not need a caller login or account credentials.

### Use this Actor when

Choose this focused workflow when you need a bounded account-footprint check for identifiers you own or are authorized to assess: inventorying your organization’s public signup footprint, screening a brand handle for impersonation risk, or triaging an abuse report before a human review. The output is account-status evidence for follow-up, not an identity assertion.

For a broad username profile-URL inventory across hundreds of sites, use [Username OSINT Scraper](https://apify.com/khadinakbar/username-osint-scraper) after this focused registration-status check. That sibling Actor is designed for username-only public profile discovery; this Actor adds email input and keeps the upstream Socialscan capability map explicit.

### Scope and responsible boundaries

This Actor is designed for public, authorized, read-only account-status research. It does not log in, retrieve private account content, submit passwords, send messages, perform password recovery, use breach data, bypass CAPTCHAs, or infer an email-to-username mapping. A `TAKEN` response means that a target registration-validation endpoint reported the identifier as already in use; it does not establish account ownership, identity, activity, or access to a public profile. Review findings against applicable laws, platform terms, and your organization’s authorization record.

The input includes `authorizationConfirmed` as an explicit caller-side confirmation. Use your Apify project access controls for email inputs and resulting datasets. Run the Actor for identifiers you own or are authorized to assess, with a documented review purpose.

### Supported integrations

The Actor pins `socialscan==2.0.1`. Its paid contract is limited to the integrations that returned stable usable evidence in private cloud probes; upstream enum membership alone is not treated as a support promise. The supported keys and identifier types are:

| Platform key | Display name | Username | Email | Optional profile URL |
| --- | --- | ---: | ---: | --- |
| `gitlab` | GitLab | Yes | No | Yes |
| `twitter` | Twitter / X | Yes | Yes | Yes |
| `tumblr` | Tumblr | Yes | Yes | Yes |

Leave `platforms` empty to use all three supported integrations. The Actor skips GitLab for email addresses because Socialscan does not expose an email registration check there, and reports that choice in `platformsSkipped`. The runtime deliberately excludes upstream integrations whose current endpoints did not provide stable usable cloud evidence.

### Input and quick start

Pass full usernames or email addresses, select the authorization confirmation, and optionally narrow the platform set. Email addresses are normalized to lowercase; usernames are passed as entered. Up to 50 unique identifiers are accepted per run.

```json
{
  "queries": ["gvanrossum", "person@example.com"],
  "authorizationConfirmed": true,
  "platforms": ["gitlab", "twitter", "tumblr"],
  "includeAvailable": false,
  "cacheTokens": true,
  "concurrency": 6,
  "requestTimeoutSecs": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

`includeAvailable` defaults to `false`, so nested results focus on positive account-status signals plus invalid or inconclusive checks. Counts still report every compatible platform response. Set it to `true` when an audit needs the available responses in the nested array as well.

### Output data

The dataset contains one record per accepted identifier whose compatible integrations return at least one usable response. A record is persisted only after local Pydantic validation and is coupled to one `query-scanned` pay-per-event charge.

| Field | Meaning |
| --- | --- |
| `query`, `queryType` | The authorized normalized identifier and its inferred type (`email` or `username`). Treat `query` as sensitive. |
| `platformsRequested`, `platformsTargeted`, `platformsSkipped` | Resolved scope and type-incompatible selections. |
| `platformsChecked` | Compatible responses received, including errors. |
| `platformsFound` | Count of `TAKEN` account-status signals. |
| `platformsAvailable` | Count of `AVAILABLE` responses. |
| `platformsInvalid`, `platformsErrored` | Platform-specific validation and inconclusive-response counts. |
| `platformsReturned`, `results` | Nested rows after `includeAvailable` filtering; `profileUrl` is present only for a username response when upstream supplies a safe `http(s)` URL. |
| `scanIncomplete`, `stopReason` | Whether the run stopped early and the bounded reason when it did. |
| `scanStartedAt`, `scanFinishedAt`, `scanDurationMs` | UTC timing and elapsed milliseconds. |
| `_note` | Interpretation guidance that accompanies every persisted row. |

Example dataset item:

```json
{
  "query": "gvanrossum",
  "queryType": "username",
  "source": "socialscan",
  "socialscanVersion": "2.0.1",
  "scanStartedAt": "<RFC 3339 timestamp>",
  "scanFinishedAt": "<RFC 3339 timestamp>",
  "scanDurationMs": 3000,
  "platformsRequested": ["gitlab", "twitter", "tumblr"],
  "platformsTargeted": 3,
  "platformsSkipped": [],
  "platformsChecked": 3,
  "platformsFound": 2,
  "platformsAvailable": 1,
  "platformsInvalid": 0,
  "platformsErrored": 0,
  "platformsReturned": 1,
  "scanIncomplete": false,
  "stopReason": "",
  "results": [
    {
      "platformKey": "twitter",
      "platform": "Twitter / X",
      "queryType": "username",
      "status": "TAKEN",
      "valid": true,
      "success": true,
      "available": false,
      "message": "Username is already taken.",
      "profileUrl": "https://twitter.com/gvanrossum",
      "source": "socialscan",
      "checkedAt": "<RFC 3339 timestamp>"
    }
  ],
  "_note": "TAKEN is a registration-validation signal, not proof of identity, ownership, or public profile access."
}
```

The terminal key-value store also contains `OUTPUT`, `RUN_SUMMARY`, `SUMMARY`, and checkpointed `STATE`. Terminal outcomes are `COMPLETE`, `VALID_EMPTY`, `PARTIAL`, `INVALID_INPUT`, `UPSTREAM_FAILED`, or `CONFIG_ERROR`. Source diagnostics remain explicit rather than being represented as an available or not-found result.

When an integration needs a fresh connection, the Actor may retire its residential proxy session and retry only that route, up to three bounded rotations per run. `RUN_SUMMARY` records bounded route diagnostics with identifier, proxy-URL, and credential values redacted.

### Pricing

This is a Pay per event (PPE) Actor. The primary event is `$0.05` per accepted identifier scan, whether the identifier is an email or username; the row is charged only after the validated row write is coupled to the event. Actor start is configured at `$0.00005` and Apify platform usage is charged separately according to the allocation shown in the live Pricing tab.

Worked examples before platform usage:

- One accepted identifier: `1 × $0.05 = $0.05`, plus the configured actor-start event.
- Ten accepted identifiers: `10 × $0.05 = $0.50` for up to 10 result rows, plus the configured actor-start event.

The live Pricing tab is the source of truth for current event prices and platform usage. The `ACTOR_MAX_PAID_DATASET_ITEMS` and `ACTOR_MAX_TOTAL_CHARGE_USD` runtime guards provide additional bounded-cost protection when configured by the deployment.

### API example

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("khadinakbar/socialscan-osint").call(
    run_input={
        "queries": ["gvanrossum"],
        "authorizationConfirmed": True,
        "platforms": ["gitlab", "twitter", "tumblr"],
    }
)

items = list(client.dataset(run.default_dataset_id).iterate_items())
for item in items:
    print(item["query"], item["platformsFound"], item["results"])
```

For a lightweight HTTP integration, call the Apify Actor API with the same JSON input and read the default dataset after the run. Treat the dataset and `RUN_SUMMARY` readback as the completion signal; a run status alone does not prove that useful rows were persisted.

### AI-agent and MCP workflow

The Actor can be called through the Apify MCP server at `https://mcp.apify.com`. Give an agent a scoped, authorized task such as:

> Check these two organization-controlled handles on GitLab, X, and Tumblr, return the dataset readback with `TAKEN` versus `AVAILABLE`, preserve inconclusive source responses, report the requested scope, provenance, outcome, and cost, and stop before any login or private-data action.

Agents should pass `authorizationConfirmed: true` only when the caller has supplied the required authorization, keep the platform scope small when the question is narrow, and read back both the dataset and terminal summary. `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, and `UPSTREAM_FAILED` are meaningful outcomes, not interchangeable success states.

### Workflow scenario

A trust-and-safety analyst starts with a brand-owned handle and a controlled test mailbox. The Actor checks the selected public registration endpoints, then returns a row with the platform statuses and any profile URL supplied by the upstream integration. The analyst next reviews each `TAKEN` signal against internal ownership records and platform evidence, compares the timestamp and scope, and exports only the findings needed for the case file. Broader username profile discovery continues with the linked username-only workflow, while inconclusive source responses are routed to a later retry or manual review.

### Builder's note

I designed this Actor as a compact registration-signal workflow rather than a broad identity finder. My goal was to keep the source, the supported routes, the account-status vocabulary, and the billable dataset row aligned so a human reviewer can understand exactly what each result means.

### Evidence and freshness

The implementation records the Socialscan version in every dataset row so later source behavior can be compared with the result provenance. The paid contract intentionally covers GitLab, Twitter / X, and Tumblr: these routes provide the focused public registration-validation signals represented by this Actor. Upstream references: [Socialscan source and README](https://github.com/iojw/socialscan) and [Socialscan on PyPI](https://pypi.org/project/socialscan/).

Re-check the supported integrations and the live Pricing tab after an upstream or Actor build change. Keep release evidence separate from user-facing output, and use dataset plus key-value-store readback to validate an operational change.

### Coverage and recovery

Public registration endpoints can change, throttle, return unexpected content, or require platform-side tokens. The Actor uses one bounded request timeout per check, optional cached token warm-up, a sticky Apify proxy session by default, and per-platform diagnostic rows for inconclusive responses. It keeps retries measured and retains the Socialscan source provenance for each signal.

When a run is partial, inspect `RUN_SUMMARY` for the platform scope, diagnostic counts, warnings, and stopping reason. Reduce concurrency or narrow `platforms`, retry after a platform cooldown, and compare delayed dataset readback before drawing a conclusion. Empty results are a source-level observation for the selected checks and should be reviewed with the requested scope.

### License and attribution

The Actor uses the upstream Socialscan package under its published Mozilla Public License 2.0 terms. Review the [Socialscan license](https://github.com/iojw/socialscan/blob/master/LICENSE) and the relevant platform terms before operating a scan. This Actor is a technical signal collection tool; the caller remains responsible for authorization, privacy, retention, and lawful use of any supplied identifier or resulting dataset.

# Actor input Schema

## `queries` (type: `array`):

One or more full email addresses or usernames to check. Up to 50 unique identifiers are accepted per run. Emails are normalized to lowercase; usernames are passed to Socialscan as entered. Supply only authorized identifiers and use non-personal examples in any saved public task. The runtime keeps identifier values out of Actor logs; use your Apify project access controls for run input and result storage.

## `authorizationConfirmed` (type: `boolean`):

Required safety confirmation. Set true only when you own the supplied identifiers or have documented authorization to perform this public account-status assessment. The Actor is not a tool for unauthorized enumeration, stalking, harassment, or privacy intrusion.

## `platforms` (type: `array`):

Optional cloud-verified Socialscan keys: gitlab, twitter, or tumblr. Leave \[] to use all three. Email checks skip GitLab because its upstream implementation does not expose an email-availability check. Skipped integrations are reported per query and do not create a false negative.

## `includeAvailable` (type: `boolean`):

When false (default), dataset result arrays focus on TAKEN, INVALID, and ERROR responses while counts still include AVAILABLE checks. Set true when you need an auditable row for every successful platform response. This does not change which platforms are checked or billed.

## `cacheTokens` (type: `boolean`):

Warm and reuse Socialscan's supported CSRF/API tokens once per platform for this run. Defaults to true to reduce duplicate setup requests. Disable only when you need to avoid token prewarm requests; this may increase request volume for tokenized integrations.

## `concurrency` (type: `integer`):

Maximum number of platform checks running at once for each identifier. Values from 1 to 16 are accepted; the default 6 is a cautious balance for public registration endpoints. This Actor processes identifiers sequentially to keep the overall request rate bounded.

## `requestTimeoutSecs` (type: `integer`):

Maximum wait for one public platform check. Values from 5 to 60 seconds are accepted and the default is 15. Timed-out checks are returned as ERROR rather than being reported as AVAILABLE or NOT\_FOUND.

## `proxyConfiguration` (type: `object`):

Apify proxy settings for public platform requests. The default uses an Apify Residential sticky session and can replace it after an inconclusive route check. Supply only an Apify-supported configuration and never place proxy credentials in Actor input. Pass {} only when direct routing is explicitly allowed by your policy.

## Actor input object example

```json
{
  "queries": [
    "gvanrossum",
    "person@example.com"
  ],
  "authorizationConfirmed": false,
  "platforms": [],
  "includeAvailable": false,
  "cacheTokens": true,
  "concurrency": 6,
  "requestTimeoutSecs": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Dataset containing one validated row per accepted identifier when its platform scan returns usable evidence.

## `summary` (type: `string`):

Structured terminal outcome and bounded diagnostics.

## `terminal` (type: `string`):

Compact terminal outcome and counts for agent readback.

# 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 = {
    "queries": [
        "gvanrossum"
    ],
    "authorizationConfirmed": false,
    "platforms": [],
    "includeAvailable": false,
    "cacheTokens": true,
    "concurrency": 6,
    "requestTimeoutSecs": 15,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/socialscan-osint").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 = {
    "queries": ["gvanrossum"],
    "authorizationConfirmed": False,
    "platforms": [],
    "includeAvailable": False,
    "cacheTokens": True,
    "concurrency": 6,
    "requestTimeoutSecs": 15,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/socialscan-osint").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 '{
  "queries": [
    "gvanrossum"
  ],
  "authorizationConfirmed": false,
  "platforms": [],
  "includeAvailable": false,
  "cacheTokens": true,
  "concurrency": 6,
  "requestTimeoutSecs": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call khadinakbar/socialscan-osint --silent --output-dataset

```

## MCP server setup

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

```

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/1mBxkXgYlBcPVe9ZB/builds/p0EjCchX8kv46bzaO/openapi.json
