# Facebook Profile Scraper - Public Profiles & Pages, No Login (`benthepythondev/facebook-profile-scraper`) Actor

Returns the public record of Facebook profiles and Pages as a logged-out visitor sees it: name, id, username, verified badge, category, bio, exact follower count, work, education, city, website and social links, published email and phone, pictures and the date of the latest post. No login.

- **URL**: https://apify.com/benthepythondev/facebook-profile-scraper.md
- **Developed by:** [Ben](https://apify.com/benthepythondev) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.20 / 1,000 profiles

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 👤 Facebook Profile Scraper

Returns what a logged-out visitor is shown of public Facebook profiles and Pages, without a login, a cookie or a browser. Enter profile links, names or ids and get one row per profile: name, id, username, verified badge, category, bio, the exact follower count, the lines of the Intro card (work, education, city, websites, other accounts, a business's email, phone and address), profile and cover picture, and the date of the latest post.

**Price:** $4.00 per 1,000 profiles on the Apify Free plan, down to $3.20 from the Gold plan up, and no fee per run. A profile that is not shown to visitors, a profile that does not exist and a profile named twice cost nothing. Export to JSON, CSV or Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

| What users report on the most used Facebook profile Actors | What this Actor does |
|---|---|
| ""intro" field is null" | The Intro card is read line by line into `work`, `education`, `currentCity`, `hometown`, `externalLinks`, `email`, `phone`, `address` and, in Facebook's order, `intro`. A page that arrives without its Intro card is not saved; it is asked for again |
| "Actor does not return follower count for search profile by ID" | An id is followed to the profile's own link and gives the same row as the name, with `followers` as the exact number Facebook states (121,434,313, not 121M) |
| "A profile run charges 2 results — is the \_summary row billed?" | One row per profile and nothing else in the dataset. The run summary is a separate record and is not charged |
| "Rate Limits, Concurrency & Throughput", "Profiles per Run, Rate Limits & Concurrency" | The limit is measured and stated below: Facebook shows one address seven to nine different profiles and then sends it to the login page for four to five minutes. The Actor asks through its addresses in turn, leaves each after six profiles, reads five profiles side by side and has no maximum per run |
| A fee for every run on top of the price per profile (stated in one Actor's pricing) | No fee per run beyond Apify's standard start event of $0.00005 |

### 🔎 What is the Facebook Profile Scraper?

Facebook serves a profile's page to visitors who are not logged in, together with the data the page is drawn from: the header, the Intro card and the newest post. This Actor loads that page with a plain HTTP request and reads the data. It opens no browser (the test runs below used 85 to 115 MB of memory), and your own Facebook account is never involved.

It works for profiles in professional mode (public figures, creators, people who turned it on) and for Pages (businesses, organisations, brands), which Facebook serves in the same form. A personal profile without professional mode shows a visitor its name and pictures at most; see the limits.

#### What data does it extract?

- **Identity:** name, profile id, Page id, username, the profile's own link, whether it is a profile or a Page, the verified badge
- **Category and bio:** the category line as shown ("Profile · Public figure", "Page · Coffee shop"), the category alone, and the bio
- **Audience:** followers (exact), following, "talking about this", and check-ins for places
- **Intro card of a person:** work, education, current city, hometown, the month they joined Facebook
- **Links:** websites and accounts on other platforms, as the profile wrote them
- **Contacts a profile publishes:** email, phone and address from the Intro card, mostly on business Pages
- **Activity:** whether posts are visible, and the date and link of the newest post
- **Pictures:** profile picture and cover photo

### ⬇️ Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `profiles` | array | | Links of profiles or Pages, their names (`zuck`) or numeric ids. An empty input reads two sample profiles |
| `maxItems` | integer | all | Stops the run after this many saved profiles |

Links of the forms `facebook.com/zuck`, `facebook.com/profile.php?id=4` and `facebook.com/people/Name/100063663337621` are understood, with or without `/about` or another tab at the end. A link of a single post, video or photo, of a group or of an event is skipped with a note in the log.

#### Example input

```json
{
  "profiles": [
    "https://www.facebook.com/zuck",
    "https://www.facebook.com/profile.php?id=100055273847808",
    "NASA"
  ]
}
```

#### Coming from another Facebook profile Actor?

The input names `startUrls` (a list of `{"url": …}`), `profileUrls` and `maxItems` are read as well, so an input written for the two most used profile Actors runs here unchanged. The row names `sourceUrl`, `url`, `username`, `profileId`, `name`, `accountType`, `bio`, `work`, `education`, `currentCity`, `hometown`, `followers`, `following`, `talkingAbout`, `verified`, `profilePictureUrl`, `externalLinks` and `scrapedAt` mean the same here. The differences are in the FAQ.

### ⬆️ Output

One row per profile. A person's profile in professional mode (picture links shortened):

```json
{
  "profileId": "1681",
  "pageId": "106670742178515",
  "url": "https://www.facebook.com/boz",
  "sourceUrl": "https://www.facebook.com/boz",
  "username": "boz",
  "name": "Andrew Bosworth (Boz)",
  "profileType": "profile",
  "accountType": "Profile · Digital creator",
  "category": "Digital creator",
  "verified": true,
  "bio": null,
  "followers": 130000,
  "following": 462,
  "talkingAbout": 365,
  "wereHere": null,
  "work": [
    "CTO at Meta",
    "Worked at Facebook",
    "Former Software Design Engineer at Microsoft",
    "Former senior field sales manager at Vector"
  ],
  "education": [
    "Went to Saratoga High School",
    "Studied Computer science at Harvard University"
  ],
  "currentCity": null,
  "hometown": "Saratoga, California",
  "joined": "February 2004",
  "email": null,
  "phone": null,
  "address": null,
  "externalLinks": [
    "http://boz.com/"
  ],
  "intro": [
    {"type": "category", "text": "Profile · Digital creator", "url": null},
    {"type": "work", "text": "CTO at Meta", "url": "https://www.facebook.com/Meta"},
    {"type": "work", "text": "Worked at Facebook", "url": "https://www.facebook.com/facebook"},
    {"type": "work", "text": "Former Software Design Engineer at Microsoft", "url": "https://www.facebook.com/Microsoft"},
    {"type": "work", "text": "Former senior field sales manager at Vector", "url": "https://www.facebook.com/Vector-109854672372285/"},
    {"type": "education", "text": "Went to Saratoga High School", "url": "https://www.facebook.com/Saratoga-High-School-439556269441200/"},
    {"type": "education", "text": "Studied Computer science at Harvard University", "url": "https://www.facebook.com/Harvard"},
    {"type": "hometown", "text": "From Saratoga, California", "url": "https://www.facebook.com/Saratoga-California-108482895842493/"},
    {"type": "joined", "text": "Joined February 2004", "url": null},
    {"type": "website", "text": "boz.com", "url": "http://boz.com/"}
  ],
  "profilePictureUrl": "https://scontent-fra3-1.xx.fbcdn.net/v/t39.30808-1/471319719_10116246266668….jpg?…",
  "coverPhotoUrl": "https://scontent-fra5-1.xx.fbcdn.net/v/t39.30808-6/471050387_10116246258215….jpg?…",
  "postsVisible": true,
  "latestPostAt": "2026-09-29T17:24:03+00:00",
  "latestPostUrl": "https://www.facebook.com/boz/posts/pfbid0gEazRah3L2A7STrRf4UPs1ZVNCNrDnpPc8tcb7hRyZpxKp5MBY8BawLEQ39tui2pl",
  "scrapedAt": "2026-10-07T06:58:37.412630+00:00"
}
```

A business Page (shortened to the fields that differ):

```json
{
  "profileId": "100055273847808",
  "pageId": "1768888423385232",
  "url": "https://www.facebook.com/Millyscommunitycafe",
  "sourceUrl": "https://www.facebook.com/profile.php?id=100055273847808",
  "username": "Millyscommunitycafe",
  "name": "Milly's",
  "profileType": "page",
  "accountType": "Page · Coffee shop",
  "category": "Coffee shop",
  "verified": false,
  "bio": "Aurora coffee shop offering locally roasted coffee, fresh house made coffee syrups and food options.",
  "followers": 1885,
  "following": 29,
  "talkingAbout": 1,
  "wereHere": 865,
  "email": "smiller@millyscommunitycafe.com",
  "phone": "+1 720-830-5166",
  "address": "15600 E. Alameda Parkway, Aurora, CO, United States, Colorado",
  "externalLinks": [
    "http://www.millyscommunitycafe.com/"
  ],
  "intro": [
    {"type": "category", "text": "Page · Coffee shop", "url": null},
    {"type": "address", "text": "15600 E. Alameda Parkway, Aurora, CO, United States, Colorado", "url": "https://maps.google.com/maps?q=15600+E.+Alameda+Parkway…"},
    {"type": "phone", "text": "+1 720-830-5166", "url": null},
    {"type": "email", "text": "smiller@millyscommunitycafe.com", "url": null},
    {"type": "website", "text": "millyscommunitycafe.com", "url": "http://www.millyscommunitycafe.com/"},
    {"type": "hours", "text": "Closed now", "url": null},
    {"type": "services", "text": "Dine-in · Outdoor seating · In-store pickup", "url": null},
    {"type": "price_range", "text": "Price Range · $", "url": null},
    {"type": "rating", "text": "100% recommend (43 reviews)", "url": "https://www.facebook.com/Millyscommunitycafe/reviews"}
  ]
}
```

`followers` is the number in the page's description, which Facebook states to the last digit for most profiles and rounds itself for some smaller ones (130,000 in the example). `following` is exact below 1,000 and rounded by Facebook above. `intro` holds the returned lines of the Intro card in Facebook's order, each with its `type`, its `text` as shown and the link it carries; the columns before it are the same lines sorted by kind, without the words Facebook puts in front ("Lives in", "From", "Joined"). The run also writes a `SUMMARY` record that names the profiles without a row and the reason a run stopped.

### 💰 What a run costs

| Apify plan | Per 1,000 profiles |
|---|---|
| Free | $4.00 |
| Bronze | $3.70 |
| Silver | $3.40 |
| Gold, Platinum, Diamond | $3.20 |

Apify's standard start event ($0.00005) is the only other charge; proxies are included. Not charged: a profile that is not shown to visitors (it does not exist, it is not public, or it is limited to logged-in users by age or country), a profile that two entries of your input name (it is saved once), and entries that are no profile links. Set the run's maximum charge and the Actor stops at it with the rows it has saved.

### ⏱️ Measured

These numbers are from October 7, 2026, on a test server outside Apify. Times on Apify can differ, and which share of a run is served by free addresses has to be measured there.

| Run | Saved | Time |
|---|---|---|
| 12 inputs of every kind (profiles, Pages, ids, a `people` link, four that are not shown), own address and datacenter proxy | 7 | 14 s |
| 13 inputs read through residential addresses, two runs | 12 | 7 s and 8 s |
| 16 names of which 8 are not shown to visitors, each confirmed through a residential address | 8 | 60 s |
| 124 names through the server's own address and the datacenter proxy only | 113 | 90 in the first four minutes, then waits: 14.5 minutes in all |

A profile page is 0.95 to 1.9 MB of HTML, 0.16 to 0.18 MB on the wire, and arrives in 0.6 to 3 seconds. No run used more than 115 MB of memory. Of the 113 rows of the last run, 112 had followers and a category, 111 the "talking about" count, 110 the date of the latest post, 108 a cover photo, 104 a bio and at least one outside link, 86 a following count, 17 an address and 10 each an email and a phone number; four of the five personal profiles in it had work and education lines. A run that was killed after its first five rows and started again ended with eight rows for eight profiles, none of them twice.

The limit per address was measured on twelve datacenter addresses: seven to nine different profiles were shown (once eleven), the next one and every profile after it was sent to the login page, and an address that was left alone was served again after four to five minutes. Asking more slowly (one profile every twelve seconds) changed nothing.

### 🤖 For AI agents

Smallest useful call:

```json
{"profiles": ["https://www.facebook.com/zuck"]}
```

Each row is one profile with `name`, `profileId`, `username`, `profileType`, `category`, `verified`, `bio`, `followers`, `work`, `education`, `currentCity`, `externalLinks`, `email`, `phone` and `latestPostAt`. `profiles` takes links, names and numeric ids, several at once. A field the profile does not publish is `null` or an empty list, never a guess. A profile that is not shown to visitors gives no row and costs nothing; the status message and the `SUMMARY` record name it. No credentials are needed.

### 💡 Use cases

- 🎯 **Lead enrichment:** add category, website, published email and phone, follower count and last activity to a list of business Pages you already have.
- 📈 **Audience tracking:** read the exact follower counts of your own and your competitors' Pages on a schedule and keep the rows by `profileId`.
- 🧑‍💼 **Creator and partner research:** role, employer, education and links of public figures and creators before an outreach.
- 🧹 **List cleaning:** find the entries of a link list that no longer exist or are not public, and the current name and link of the others.

### ⚠️ Limits, stated plainly

- **Profiles in professional mode and Pages.** Those are served with the record described above. A personal profile without professional mode gives a visitor less. In the tests eight such profiles of well-known people were sent to the login page (seven were asked from a datacenter address only), and one personal profile was shown with its name, username and pictures and nothing else, under an anonymous id that starts with `pfbid` instead of the numeric one. Such a row is saved and charged like any other.
- **"Not shown to visitors" is three cases in one.** A profile that does not exist, one that is not public and one limited by age or country get the same answer from Facebook. The Actor reports a profile as not shown when two addresses that were being served at that moment did not get it, the second one a US residential address.
- **Datacenter addresses are shown less than residential ones.** In a test with 16 names, datacenter addresses were sent to the login page for seven that a US residential address was shown: six old names that Facebook forwards to the current one (`/Oprah` to `/oprahwinfrey`) for residential visitors only, and one Page. A profile that an address is not shown is therefore asked for once more through a US residential address. Residential requests that bring no row are bounded per run: 50, and one more for every profile saved. Past the bound only free addresses are asked, and a profile can then be reported as not shown although a residential visitor would be shown it.
- **Seven to nine profiles per address, then four to five minutes of login page.** That is Facebook's limit for visitors, and asking during those minutes prolongs them. The Actor leaves an address after six profiles and uses it again five minutes later. Apify's datacenter proxy had 27 addresses in the tests, which is room for about 160 profiles in five minutes. While none of them can be asked, the Actor reads through US residential addresses, a new one every six profiles, so a run does not wait; only a run that cannot use residential addresses waits, up to five minutes at a time, and says so in its log. An address that is asked again while it is turned away stays turned away for longer each time (more than 15 minutes in the tests), so the Actor leaves such an address alone twice as long after every refusal.
- **Lines that name other people are left out.** The relationship line of an Intro card ("Married to …") is not returned, and neither is the gender Facebook's data carries. No friends lists, no followers lists, and no email or phone number that the profile does not publish itself.
- **`followers` is as exact as Facebook states it,** and `following` is rounded by Facebook above 999.
- **Intro texts are in English,** as Facebook words them for an English-speaking visitor ("Founder and CEO at Meta", "Studied … at …"). `currentCity`, `hometown` and `joined` come without the leading words.
- **The `hours` line is the status at the time of the run** ("Closed now"), not the weekly opening hours.
- **The latest post only.** `latestPostAt` and `latestPostUrl` describe the newest post that is not pinned. The [Facebook Posts Scraper](https://apify.com/benthepythondev/facebook-posts-scraper) reads the timeline.
- **No search by name or keyword.** Facebook's search needs a login. This Actor reads profiles you name.
- **Picture links are Facebook's own and expire.** Download the pictures soon after the run if you need the files.

### ❓ FAQ

**Do I need a Facebook account or cookies?** No. The Actor reads what a visitor without an account gets.

**Does it work for personal profiles?** For those in professional mode, which is what public figures and creators use; their category line starts with "Profile ·". A personal profile without it gives a visitor the login page or its name and pictures only: open its link in a private browser window to see the same.

**Does it work for Pages?** Yes. A Page is served in the same form and gives the same row, with `profileType` `page` and, where the Page publishes them, `email`, `phone`, `address` and the lines for opening status, services, price range and rating in `intro`.

**Why is a profile reported as "Not shown to visitors"?** Two visitors that Facebook was serving at that moment, the second one from a US residential address, were both sent to the login page or to "This content isn't available" for it. The profile does not exist, is not public, or is limited to logged-in users by age or country. Facebook gives a visitor no way to tell these apart.

**Why is `work` or `currentCity` empty?** The profile does not publish that line to everyone. Nothing is filled in from other sources.

**How exact is the follower count?** It is the number in the page's description: 121,434,313 for a large profile where the visible line says "121M". Facebook rounds it itself for some smaller profiles.

**What is different from the most used profile Actor's rows?** There are no diagnostic rows: a profile without data is named in the status message and the `SUMMARY` record instead, so `recordType`, `status`, `routeUsed`, `attempts`, `errorCode` and `errorMessage` do not exist here. `relationship` is not returned. `followers` is exact instead of the rounded "121M" turned into a number. Added here: `pageId`, `profileType`, `category`, `wereHere`, `joined`, `email`, `phone`, `address`, `intro`, `coverPhotoUrl`, `postsVisible`, `latestPostAt` and `latestPostUrl`.

**Can the same profile appear twice?** No. A name and its numeric id given together are saved once, and a run that is started again saves nothing a second time.

**How do I call it from code?** With the Apify API or the Python and JavaScript clients; every run returns a dataset you can fetch as JSON or CSV. It also works as a tool through Apify's MCP server.

**Is it legal?** The Actor reads what Facebook shows to everyone without a login and returns what a profile itself publishes there: name, category, bio, work, education, places, links and, mostly for businesses, contact details. It does not collect friends or follower lists, relationship or family lines, gender, private profiles or anything behind a login, and it guesses no email addresses or phone numbers. Much of this is personal data all the same: GDPR, CCPA and similar rules apply to how you store and use it, CAN-SPAM and its European counterparts apply before you write to an address, and Facebook's terms apply to you as well. Collect only what you need and have a lawful purpose for it.

### 🔗 You might also like

- [Facebook Posts Scraper](https://apify.com/benthepythondev/facebook-posts-scraper): all posts of public Pages and profiles, with a date range
- [Facebook Comments Scraper](https://apify.com/benthepythondev/facebook-comments-scraper): the comments and replies under a post or reel
- [Facebook Groups Scraper](https://apify.com/benthepythondev/facebook-groups-scraper): posts of public Facebook groups
- [Meta Ad Library Scraper](https://apify.com/benthepythondev/meta-ad-library-scraper): the ads a Page runs on Facebook and Instagram
- [Instagram Profile Scraper](https://apify.com/benthepythondev/instagram-profile-scraper): public Instagram accounts with followers, bio and links

**Keywords:** facebook profile scraper, facebook profile api, scrape facebook profiles, facebook public profile data, facebook page scraper, facebook follower count, facebook profile to csv, facebook profile by id, facebook bio scraper, facebook intro scraper, facebook page email, facebook page phone, facebook lead enrichment, facebook creator data, facebook verified badge, no login facebook scraper, social media profile data

# Actor input Schema

## `profiles` (type: `array`):

Profiles to read, one row each: links (https://www.facebook.com/zuck, https://www.facebook.com/profile.php?id=4, https://www.facebook.com/people/Name/100063663337621/), names (zuck) or numeric ids. Profiles in professional mode and Pages give the full record. A profile that is not shown to visitors (it does not exist, is not public, or is limited by age or country) is named in the run's status and costs nothing. A name and its id given together are read once.

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

Stops the run after this many saved profiles. Leave it empty to read every entry of the list. Profiles that are not shown to visitors are not counted.

## Actor input object example

```json
{
  "profiles": [
    "https://www.facebook.com/zuck",
    "https://www.facebook.com/NASA"
  ]
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "profiles": [
        "https://www.facebook.com/zuck",
        "https://www.facebook.com/NASA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/facebook-profile-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 = { "profiles": [
        "https://www.facebook.com/zuck",
        "https://www.facebook.com/NASA",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("benthepythondev/facebook-profile-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 '{
  "profiles": [
    "https://www.facebook.com/zuck",
    "https://www.facebook.com/NASA"
  ]
}' |
apify call benthepythondev/facebook-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,benthepythondev/facebook-profile-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/19ZzY3r1jOD4w2Wa0/builds/B1RfphJEY9mTq462I/openapi.json
