# Facebook People Search Scraper (`automation-lab/facebook-people-search-scraper`) Actor

Search Facebook by keyword and export public people result cards with profile IDs, names, URLs, verification signals, profile-picture metadata, ranks, and query provenance. No Facebook account or cookies required.

- **URL**: https://apify.com/automation-lab/facebook-people-search-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Facebook People Search Scraper

Search Facebook's anonymous public people directory by keyword and export clean profile result cards. **Facebook People Search Scraper** returns public names, profile IDs, URLs, profile-picture metadata, visible context, verification signals, ranks, and source-query provenance without asking for a Facebook login or user cookies.

Use role, company, specialty, or location phrases to create review-ready recruiting and prospect research lists. Results are stored in the default Apify dataset for download as JSON, CSV, Excel, XML, or RSS and for delivery to your own pipeline.

### What does Facebook People Search Scraper do?

The Actor opens Facebook's public people directory in one anonymous browser session and searches each supplied keyword phrase.

For every visible people result card, it:

- extracts the public profile name and canonical URL;
- captures a numeric ID when Facebook exposes one;
- falls back to the public `pfbid` or username as `profileId`;
- keeps the query and one-based result rank;
- records visible profile-picture metadata and card context;
- marks verification only when a visible badge is present;
- deduplicates duplicate desktop/mobile renderings within each query;
- saves typed records to the run's default dataset.

It does not log in, enrich private fields, or open every profile page.

### Who is it for?

This Actor is designed for workflows that start with public profile discovery:

- **Recruiters** finding people associated with public role or skill phrases.
- **Sales researchers** assembling candidate profiles for manual qualification.
- **Agency teams** exploring public specialist and location combinations.
- **OSINT analysts** collecting query-attributed public identity leads.
- **Data teams** scheduling recurring searches and comparing exported datasets.
- **Developers** feeding public result cards into review, enrichment, or CRM queues.

Choose a supplied-URL profile scraper instead when you already know the Facebook profile URLs and need deeper public profile details.

### Why use this Actor?

- **No account required:** no Facebook email, password, token, or cookie input.
- **Keyword discovery:** start from roles, names, locations, companies, or combined phrases.
- **Stable provenance:** every record includes its source query and rank.
- **Useful identity fallback:** `profileId` uses numeric ID, `pfbid`, or username in that order.
- **Low-transfer browser route:** media, font, and image downloads are blocked while image URLs remain available as metadata.
- **Fail-closed behavior:** challenge, login-only, HTTP error, and unknown pages fail instead of silently returning an empty dataset.
- **Apify-native output:** schedule runs and export results through datasets, webhooks, API clients, or integrations.

### What Facebook people data is extracted?

| Field | Type | Description |
| --- | --- | --- |
| `query` | string | Keyword phrase that produced the card. |
| `rank` | integer | One-based position within that query's visible results. |
| `profileId` | string | Numeric ID, `pfbid`, or username fallback. |
| `numericId` | string or null | Numeric Facebook profile ID when exposed. |
| `name` | string | Public name shown on the result card. |
| `profileUrl` | string | Canonical public Facebook profile URL. |
| `isVerified` | boolean or null | `true` for a visible verification badge; otherwise `null`. |
| `profilePictureUrl` | string or null | Public result-card image URL without downloading the image. |
| `context` | string or null | Visible alternate label or parenthetical role/context. |
| `scrapedAt` | ISO timestamp | Time the card was extracted. |

Nullable fields are honest: Facebook does not show numeric IDs, badges, pictures, or context on every public card.

### How to search Facebook people by keyword

1. Open the Actor input page.
2. Add one or more phrases to **Search queries**.
3. Set **Maximum results** for the whole run.
4. Optionally reduce **Results per query** to spread the limit across more phrases.
5. Click **Start**.
6. Open **People results** in the run output.
7. Export the dataset or connect it to your next workflow.

A specific phrase such as `recruiter Austin Texas` usually produces more reviewable results than a broad word such as `recruiter`.

### Input parameters

#### `searchQueries`

Required array of 1–50 keyword strings. Whitespace is normalized and duplicate phrases are removed. Each string can contain up to 200 characters.

```json
{
  "searchQueries": [
    "cybersecurity consultant",
    "cloud architect",
    "data engineer"
  ]
}
```

#### `maxItems`

Maximum records saved across all queries. The default is 25 and the accepted range is 1–500. This limit never causes the Actor to invent or expand results.

#### `resultsPerQuery`

Maximum cards saved per query, from 1 to 12. The default is 12. Facebook's anonymous directory currently exposes about 12 unique visible cards per phrase.

### Example input

This multi-query input creates a role-based prospect research dataset while preserving the query behind each result:

```json
{
  "searchQueries": [
    "cybersecurity consultant",
    "cloud architect",
    "data engineer"
  ],
  "maxItems": 30,
  "resultsPerQuery": 10
}
```

The Actor processes queries in input order and stops as soon as `maxItems` is reached.

### Example output

The following record shape comes from current public-directory behavior; identifying values are redacted:

```json
{
  "query": "recruiter Austin Texas",
  "rank": 1,
  "profileId": "pfbid0SamplePublicIdentifier",
  "numericId": null,
  "name": "Sample Recruiter",
  "profileUrl": "https://www.facebook.com/people/Sample-Recruiter/pfbid0SamplePublicIdentifier",
  "isVerified": null,
  "profilePictureUrl": "https://scontent.example.fbcdn.net/sample-profile-picture.jpg",
  "context": "Sample Recruiter (Technical recruiter)",
  "scrapedAt": "2025-01-15T12:00:00.000Z"
}
```

Records from the same profile can appear for different queries intentionally, because query provenance is part of the product. Deduplicate across queries by `profileId` downstream when your workflow needs one row per person.

### How much does it cost to search Facebook people?

The Actor uses pay-per-event pricing:

- a one-time **Run started** event costs **$0.005** per run;
- each **Person extracted** event is charged at the active account tier;
- the BRONZE price is **$0.001736 per result**, with lower unit prices at higher tiers.

At the BRONZE tier, 10 results cost about **$0.02236**, 25 results about **$0.04840**, and 100 results across multiple queries about **$0.17860**, including one start event. Empty searches incur only the start event. Apify Console shows the exact active tier and charge before and after a run.

The six result tiers are FREE $0.0019964, BRONZE $0.001736, SILVER $0.0013541, GOLD $0.0010416, PLATINUM $0.0006944, and DIAMOND $0.00048608 per result.

### Result quality tips

- Combine a role with a location, industry, or specialty.
- Use several focused phrases instead of one very broad word.
- Keep `resultsPerQuery` below the global limit when testing many phrases.
- Use `query` and `rank` to preserve search context during review.
- Use `profileId` rather than a mutable display name for downstream matching.
- Treat a name match as a lead for human review, not proof of employment or identity.
- Schedule the same input to observe visible directory changes over time.

### Limits and failure behavior

Facebook controls the anonymous public directory and can change its HTML, ranking, availability, and exposed fields.

Current practical limits:

- about 12 unique public cards are visible per query;
- results are ranked by Facebook and are not exhaustive;
- no exact location, employer, language, or verification filter is promised;
- profile pictures are returned as source URLs and are not downloaded;
- `isVerified` is null when no visible badge signal exists;
- some queries naturally return fewer or no public cards;
- private, restricted, deleted, and login-only profiles are outside scope.

A recognizable directory page with no cards completes successfully with zero results. An HTTP error, challenge, login-only shell, or unknown response is retried twice and then fails with a non-zero status so scheduled workflows can alert correctly.

### Recurring recruiting workflow

A practical scheduled workflow is:

1. Create focused role-and-location phrases.
2. Run the Actor daily or weekly with an Apify schedule.
3. Export `profileId`, `name`, `profileUrl`, `query`, and `rank`.
4. Compare IDs with the previous dataset.
5. Send only newly visible profiles to a human qualification queue.
6. Enrich approved public profile URLs with a separate profile-detail Actor.

The Actor itself does not maintain historical state or claim that a changed rank means a person's real-world status changed.

### Export and integration options

After a successful run you can:

- download JSON, JSONL, CSV, Excel, XML, or RSS;
- connect the dataset to Google Sheets or another Apify integration;
- trigger a webhook when the run succeeds or fails;
- read items through the dataset REST API;
- use the JavaScript or Python Apify client;
- schedule recurring searches in Apify Console;
- pass qualified profile URLs to another public-data workflow.

### Run with the Apify API

Replace `APIFY_TOKEN` with your token. Do not place tokens in source code.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~facebook-people-search-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["software engineer"],"maxItems":10,"resultsPerQuery":10}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/facebook-people-search-scraper').call({
  searchQueries: ['recruiter Austin Texas'],
  maxItems: 8,
  resultsPerQuery: 8,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/facebook-people-search-scraper').call(run_input={
    'searchQueries': ['cybersecurity consultant', 'cloud architect'],
    'maxItems': 20,
    'resultsPerQuery': 10,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with Apify MCP

Add this Actor as an HTTP MCP tool in Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/facebook-people-search-scraper"
```

#### Claude Desktop

Add this JSON to the Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/facebook-people-search-scraper"
    }
  }
}
```

#### Cursor

Add the same `apify` server object to Cursor's MCP settings and keep the Actor-specific URL unchanged.

#### VS Code

Add the same HTTP server URL through your VS Code MCP extension's server configuration. No local command or Facebook credential is required.

Example prompts:

- “Search Facebook people for `cloud architect` and return 10 public cards.”
- “Run three specialist-role queries, then group the result links by source query.”
- “Export the latest people-search dataset as CSV for manual recruiting review.”

### Responsible use and legality

This Actor accesses public result cards without authentication. Public availability does not remove your legal and ethical responsibilities.

- Use data only for a lawful purpose.
- Follow Facebook's terms and applicable privacy, employment, anti-discrimination, and marketing laws.
- Do not infer sensitive attributes from names, images, or profile context.
- Do not use output for harassment, surveillance, spam, or automated high-impact decisions.
- Verify identity and relevance before contacting or evaluating a person.
- Honor deletion, objection, and retention requirements that apply to your organization.
- Collect only the fields needed for your stated workflow.

You are responsible for deciding whether your use is permitted in your jurisdiction and context.

### Troubleshooting

#### The run returned fewer than `maxItems`

`maxItems` is a ceiling, not a guaranteed count. Facebook currently exposes at most about 12 unique anonymous cards per phrase, and specific phrases can return fewer. Add more focused queries if that matches your research goal.

#### `numericId` or `isVerified` is null

Facebook does not expose those signals on every card. Use `profileId` as the normalized identifier and treat null verification as “not exposed,” not as “not verified.”

#### The run failed after retries

Review the run log for the affected query. Facebook may have returned an HTTP error, challenge, login-only shell, timeout, or changed page shape. Retry later rather than treating a failed run as an empty result set.

#### Why are images not downloaded?

The Actor blocks image transfer to reduce bandwidth while retaining the public `profilePictureUrl` attribute. Fetching or storing those images is outside this product's scope.

### Related Automation Lab Actors

- [Facebook Public Profile Scraper](https://apify.com/automation-lab/facebook-public-profile-scraper) — enrich already known public profile URLs with deeper visible profile details.
- [Facebook URL to ID Resolver](https://apify.com/automation-lab/facebook-url-to-id-resolver) — normalize supplied Facebook URLs into IDs and object types.
- [Facebook Video Search Scraper](https://apify.com/automation-lab/facebook-video-search-scraper) — discover public Facebook Watch and Reel videos by keyword.

Use this Actor for keyword-to-profile discovery; use the related Actors only when their separate input and output contracts fit the next step.

### FAQ

#### Does it require Facebook login or cookies?

No. The Actor uses Facebook's anonymous public people directory and manages its own temporary browser session.

#### Can it search by phone number or email?

No. The input is a keyword phrase, and only Facebook's visible public people cards are returned.

#### Does it scrape complete Facebook profiles?

No. It extracts result-card metadata. Use the related public profile Actor for supplied URLs when you need deeper publicly visible details.

#### Are results exhaustive?

No. Facebook decides what its anonymous directory shows and currently limits each phrase to about 12 unique cards.

#### Can I schedule monitoring?

Yes. Schedule the same input in Apify and compare datasets by `profileId`. The Actor does not make identity or employment-change claims on your behalf.

#### Are duplicate people possible?

Duplicate renderings within one query are removed. The same profile can remain in separate query results so you can see every matched query; deduplicate by `profileId` downstream if needed.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search in Facebook's public people directory. Use specific combinations such as a role and location. Duplicates and surrounding whitespace are removed. Maximum 50 queries.

## `maxItems` (type: `integer`):

Maximum number of people records saved across all queries. Facebook currently exposes up to 12 unique anonymous directory cards per query.

## `resultsPerQuery` (type: `integer`):

Maximum number of public people cards saved for each query. Use a lower number to distribute a run across more keywords.

## Actor input object example

```json
{
  "searchQueries": [
    "software engineer"
  ],
  "maxItems": 10,
  "resultsPerQuery": 12
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open the default dataset in the people-results overview view.

# 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 = {
    "searchQueries": [
        "software engineer"
    ],
    "maxItems": 10,
    "resultsPerQuery": 12
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/facebook-people-search-scraper").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 = {
    "searchQueries": ["software engineer"],
    "maxItems": 10,
    "resultsPerQuery": 12,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/facebook-people-search-scraper").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 '{
  "searchQueries": [
    "software engineer"
  ],
  "maxItems": 10,
  "resultsPerQuery": 12
}' |
apify call automation-lab/facebook-people-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/facebook-people-search-scraper"
        }
    }
}

```

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/pM46FodUFQeYr4xbg/builds/5KdLLv014cVjgOas5/openapi.json
