# 📘 Facebook Pages Scraper - Details, Ratings & Ad Status (`unseenuser/fb-pages`) Actor

Scrape Facebook pages for website, address, business hours, ratings, follower counts and whether the page is running ads right now. Bulk export. No login.

- **URL**: https://apify.com/unseenuser/fb-pages.md
- **Developed by:** [Unseen User](https://apify.com/unseenuser) (community)
- **Categories:** Lead generation, Social media, Automation
- **Stats:** 31 total users, 11 monthly users, 100.0% runs succeeded, 4 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $5.00 / 1,000 results

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?

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 Pages Scraper - Details, Posts, Reels - from $5 / 1k

> **Website, address, hours, ratings and ad-running status in one call.** Public Facebook page data for B2B lead generation, CRM enrichment and competitor research. No login. No cookies.

> ⚠️ **SCOPE - read this first.** This Actor **enriches known Facebook page URLs**. It does **NOT** search or discover pages by keyword. Paste the URLs you already have. (There is no public Facebook page-search API; any tool claiming "search Facebook by keyword" is doing something else under the hood.)

> 🛡️ **Compliance.** Returns public, logged-off page data only. **You are the data controller** for any personal data in the output and own the lawful basis for any outreach. See the Terms of Service section below.

### 🎯 The Outbound Hook: Ad-Activity Signal

The response includes `adStatus` - whether the page is currently running ads via Facebook's Ad Library. **Pages with budget are warmer outbound prospects.** Most Facebook page scrapers in this category do not surface this field; if you sell to advertisers, agencies or brands, ad-running status is a first-class qualification signal you can filter on before the first email.

### 💰 Pricing

| Scraper | Price | Contact Fields | Business Hours | Ad-Running Status | Ratings |
|---|---|---|---|---|---|
| **📘 This Actor** | **$8 / 1k** (from $5) | ✅ website + address + category | ✅ | ✅ `adStatus` | ✅ |
| Category flagship | ~$12-13 / 1k | ✅ | ✅ | ✅ | ✅ |
| Commodity tier | $1-4 / 1k | partial | usually no | ❌ | sometimes |

**$8 per 1,000 results at base rate, dropping to $5 on higher Apify subscription tiers.**

| Subscription level | Per 1,000 results |
|---|---|
| No discount | $8.00 |
| Bronze | $7.00 |
| Silver | $6.00 |
| Gold | $5.00 |

That is a third under the category flagship at $12-13 per 1,000, for a wider field set including the ad-running signal none of them return. Every returned item is one billed result - see the cost model under Inputs before enabling add-ons.

**Failed URLs cost nothing.** A malformed or unreachable URL goes to a separate `fb-pages-errors` dataset and is not billed.

### 📦 What You Get - Sample Output (Real Schema)

Every row starts with the same six columns - `type`, `pageUrl`, `pageName`, `id`, `url`, `scrapedAt` - so pages, posts, photos and reels line up in one spreadsheet instead of stair-stepping across it. Empty fields are omitted rather than returned as `null`.

**A page row:**

```json
{
  "type": "page",
  "pageUrl": "https://www.facebook.com/mantraindianfolsom",
  "pageName": "Mantraindian",
  "id": "100088017857524",
  "url": "https://www.facebook.com/mantraindianfolsom",
  "scrapedAt": "2026-08-10T16:53:13.754Z",
  "name": "Mantraindian",
  "category": "Restaurant",
  "pageIntro": "Indian Vegan & Vegetarian Restaurant",
  "website": "https://www.mantraindian.com/",
  "address": "1870 Prairie City Rd, Suite 500, Folsom, CA, United States, California",
  "creationDate": "November 25, 2022",
  "likeCount": 3224,
  "followerCount": 3200,
  "talkingAboutCount": 118,
  "rating": "Not yet rated (1 review)",
  "ratingCount": 1,
  "adStatus": "This Page is currently running ads.",
  "adLibraryPageId": "104359362513119",
  "priceRange": "$",
  "services": "Delivery, Takeaway, Dine in",
  "isBusinessPageActive": false,
  "businessHoursText": "monday 11:00-21:00; tuesday CLOSED",
  "businessHours": [{ "monday": { "open": "11:00", "close": "21:00" } }],
  "links": ["https://www.instagram.com/mantraindian"],
  "profilePicUrl": "https://scontent-....jpg/",
  "coverPhotoUrl": "https://scontent-....jpg/"
}
```

**A post row** (same six leading columns, then content fields):

```json
{
  "type": "post",
  "pageUrl": "https://www.facebook.com/mantraindianfolsom",
  "pageName": "Mantraindian",
  "id": "1059127143294059",
  "url": "https://www.facebook.com/mantraindianfolsom/posts/pfbid02...",
  "scrapedAt": "2026-08-10T16:53:13.754Z",
  "text": "Weekend thali is back.",
  "publishedAt": "2026-08-03T13:15:15.000Z",
  "reactionCount": 47,
  "commentCount": 6,
  "shareCount": 2,
  "viewCount": 374,
  "reactions": { "like": 41, "love": 6, "care": 0, "haha": 0, "wow": 0, "sad": 0, "anger": 0 },
  "authorName": "Mantraindian",
  "authorId": "100088017857524",
  "authorUrl": "https://www.facebook.com/mantraindianfolsom",
  "authorVerified": true,
  "mediaType": "video",
  "imageUrl": "https://scontent-....jpg/",
  "videoUrl": "https://video-....mp4/",
  "thumbnailUrl": "https://scontent-....jpg/",
  "musicTitle": "Mantraindian · Original audio",
  "enriched": true,
  "transcript": "1\n00:00:00,000 --> 00:00:03,761\n..."
}
```

`adStatus` is the conversion event - no other scraper in this category tells you whether the page is spending money right now.

**Need the raw upstream payload instead?** Set **Output style** to `raw` and every row is returned exactly as the source API sends it, including the duplicate snake\_case copies of each value. Use it only if you already have an integration reading those exact keys.

### 🎯 Use Cases

- **B2B lead generation** - pull website, address and category for a list of known business pages
- **CRM enrichment** - fill in website, category, hours and rating fields for accounts you already track
- **Local-business prospecting** - build outreach lists for restaurants, clinics or shops in a vertical
- **Competitor research** - check ratings, follower counts and whether a rival is currently advertising
- **Ad-activity monitoring** - filter prospects to only pages currently running ads (warmer leads, real budget)
- **Market mapping** - profile categories and engagement across a defined set of pages
- **Bulk website URL extraction** - pull the official business website from every Facebook page in a list in one call, then export to CSV for outbound, CRM enrichment, or lead scoring

### 🔄 Worked example - input to output

**Input.** Two pages, posts on with a cap of 2, everything else default:

```json
{
  "startUrls": [
    "https://www.facebook.com/mantraindianfolsom",
    "https://www.facebook.com/innoutburger"
  ],
  "includePosts": true,
  "maxPosts": 2
}
```

**Output.** 6 rows, in this order. The page row comes first, then its content, then the next page:

| # | `type` | `pageUrl` | Key fields |
|---|---|---|---|
| 1 | `page` | `.../mantraindianfolsom` | `name`, `category`, `website`, `address`, `rating`, `adStatus` |
| 2 | `post` | `.../mantraindianfolsom` | `text`, `publishedAt`, `reactionCount`, `mediaType` |
| 3 | `post` | `.../mantraindianfolsom` | `text`, `publishedAt`, `reactionCount`, `mediaType` |
| 4 | `page` | `.../innoutburger` | `name`, `category`, `website`, `address`, `rating`, `adStatus` |
| 5 | `post` | `.../innoutburger` | `text`, `publishedAt`, `reactionCount`, `mediaType` |
| 6 | `post` | `.../innoutburger` | `text`, `publishedAt`, `reactionCount`, `mediaType` |

**That is 6 billed results** - 2 pages plus 4 posts. Raising `maxPosts` to 50 would bill 102.

**Getting just the pages back:**

```js
const pages = items.filter((r) => r.type === 'page');
```

**Getting one page's posts:**

```js
const posts = items.filter(
  (r) => r.type === 'post' && r.pageUrl === 'https://www.facebook.com/innoutburger',
);
```

**As CSV,** the six leading columns are the same on every row and the rest are shared where they mean the same thing. But a page row and a photo row have almost nothing else in common, so a single flat export is mostly empty cells whichever way you slice it. For a clean rectangular CSV, export the `fb-pages-pages` / `fb-pages-posts` / `fb-pages-photos` / `fb-pages-reels` dataset from the run's **Storage** tab instead - each holds one row type and nothing is blank.

### 🚀 Quick Start

1. Click **Try for free** on this Actor's page
2. Paste one or more public Facebook page URLs into `startUrls`
3. Run the Actor
4. Download results as JSON, CSV or XLSX, or pull via Apify API

### ⚙️ Inputs

**Pages to scrape**

| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| `startUrls` | array of strings | ✅ | - | Public Facebook page URLs (e.g. `https://www.facebook.com/mantraindianfolsom`) |
| `getBusinessHours` | boolean | ❌ | `true` | Include the page's opening hours. No extra cost. |
| `cacheMaxAge` | string | ❌ | `""` | Reuse a recent cached result instead of scraping fresh: `1d`, `3d`, `7d`, `14d`, `30d`. Cached rows are marked `cached: true` with a `cached_at` timestamp. Leave empty for live data. |
| `includeGatedProfile` | boolean | ❌ | `false` | For age-restricted or private pages, return the limited public fields Facebook still exposes instead of an empty result. |

**Content add-ons** - each returned item is its own billed row

| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| `includePosts` | boolean | ❌ | `false` | Pull recent posts (3 per upstream call) |
| `maxPosts` | integer | ❌ | `0` | Max posts per page (0 = all) |
| `includePhotos` | boolean | ❌ | `false` | Pull page photos |
| `maxPhotos` | integer | ❌ | `0` | Max photos per page (0 = all) |
| `includeReels` | boolean | ❌ | `false` | Pull page reels (10 per upstream call) |
| `maxReels` | integer | ❌ | `0` | Max reels per page (0 = all) |
| `includeEvents` | boolean | ❌ | `false` | Pull page events (about 3 per upstream call, paginated) |
| `maxEvents` | integer | ❌ | `0` | Max events per page (0 = all) |

**Post and reel enrichment** - one extra upstream call per item

| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| `enrichPosts` | boolean | ❌ | `false` | Fetch full detail for each post and reel: share count, accurate view count, and optionally comments and transcript |
| `maxEnrichedItems` | integer | ❌ | `10` | Cap on how many items per page get the extra call (0 = all). Items past the cap are still returned, just unenriched. |
| `getComments` | boolean | ❌ | `false` | Include the full comment thread on enriched items |
| `getTranscript` | boolean | ❌ | `false` | Include a video transcript on enriched items |

**Output**

| Input | Type | Required | Default | Description |
|---|---|---|---|---|
| `outputStyle` | string | ❌ | `clean` | `clean` maps every row onto a small, stable, camelCase column set. `raw` returns each item exactly as the source API sends it, duplicate keys and all. Does not change what is scraped or billed. |

**Cost model.** Every returned item is one billed row. The `max*` fields default to `0 = all`, so a page with 3,000 photos and no cap produces 3,000 billed rows - the run log prints a `NO CAP SET` warning when this applies. Enrichment is the most expensive option here: it adds one upstream call per item on top of the row itself, which is why `maxEnrichedItems` defaults to 10 rather than all.

**Cache tip.** For recurring monitoring, set `cacheMaxAge` to `7d` or `30d`. Cache hits are faster and cost nothing upstream, and each affected row tells you it was cached and when.

### 📤 Output Behavior

- **One row per scraped item**, written to the dataset **as it is scraped** - not buffered to the end of the run. The page row appears as soon as the page itself is fetched, then content rows follow in batches as each upstream page of results arrives. Order per page: page, then posts, photos, reels, events, then the next page.
- **Six identical leading columns on every row** - `type`, `pageUrl`, `pageName`, `id`, `url`, `scrapedAt` - so a mixed export lines up instead of stair-stepping. Filter on `type` to separate pages from content, and join content back to its page on `pageUrl`.
- **Consistent field names across row types.** A post and a reel both use `text`, `publishedAt`, `viewCount`, `videoUrl` and `thumbnailUrl`, so they stack in one table.
- **Empty fields are omitted**, not returned as `null`. A sparse page produces a short row rather than a wide one full of blanks.
- **No duplicate columns.** The source API returns several values twice under different spellings (`commentCount` and `comment_count`, `text` and `description`); each is mapped to one canonical camelCase column.
- **No double billing across add-ons.** On video-first pages the posts feed is mostly reels, so the same item can come back from both the posts and reels add-ons. It is emitted once and billed once; the run log says how many duplicates were dropped.
- **Migrating from another Facebook page scraper?** Set **Output style** to `raw` - page rows then also carry `title`, `likes`, `info`, `categories` and `followers` as aliases of `name`, `likeCount`, `pageIntro`, `category` and `followerCount`, so an existing integration keeps working without a field remap.
- **Per-URL error isolation:** a bad URL is written to a separate `fb-pages-errors` dataset and the run keeps going - one bad input never crashes the batch. **Failed URLs are not billed**, because a failure row contains no scraped data. Find them in the run's Storage tab under the `fb-pages-errors` dataset.
- Each row is one billed result. Add-ons default to `0 = all`, so set `maxPosts` / `maxPhotos` / `maxReels` if you want a ceiling
- Formats: JSON, CSV, XLSX or via Apify API
- **Per-type copies for a blank-free CSV.** The default dataset must hold every scraped item, because that is what billing counts - and a page row and a photo row share almost no columns, so the Console renders the union of all of them and a photo row shows mostly empty cells. Every row is therefore *also* written to a named dataset per type - `fb-pages-pages`, `fb-pages-posts`, `fb-pages-photos`, `fb-pages-reels`, `fb-pages-events` - in the run's Storage tab. Each one is a single row type, so every column is populated. On a typical mixed run the default dataset is ~68% blank cells; the `fb-pages-photos` and `fb-pages-reels` copies are 0%. **These are copies of the same rows and are not billed again.**
- The dataset ships with curated views: **Overview**, **Page details**, **Contact fields**, **Ad activity**, **Posts & reels**, **Photo links** and **Events**. Note that Apify views select *columns*, not rows - rows of other types still appear with those columns empty. For a table with no blanks, use the per-type datasets above.
- A `OUTPUT_SUMMARY` record is written to the key-value store at the end of every run with totals and timings
- A live-view status API is exposed during the run (`/health`, `/status`, `/summary`) - see the Actor's OpenAPI schema

### ⚠️ Limitations - read before you buy

**No keyword or category search.** This Actor enriches Facebook page URLs you already have. It cannot find pages by keyword, industry or location. If you need discovery, you need a search actor, not this one. There is no public Facebook page-search API.

**No email addresses or phone numbers.** Both are removed before anything is written to the dataset, by design. If contact details are what you need, this is not the right Actor.

**Only what the page makes public.** Pages that hide a field return it empty. Business pages are the most complete; creator and community pages often have no address or hours; personal profiles return very little. A sparse page is the page's choice, not a failure.

**Ad status is a point-in-time read.** `adStatus` reflects Facebook's Ad Library at the moment of the call. It is a qualification signal, not a guarantee that a specific ad is serving in a specific country right now.

**Add-ons bill per item and default to unlimited.** Posts arrive 3 per upstream call, reels 10, events about 3. With `maxPosts` / `maxPhotos` / `maxReels` / `maxEvents` left at `0`, a large page can produce thousands of billed rows. The run log prints a `NO CAP SET` warning, but set a number if you want a ceiling.

**Enrichment is the expensive option.** `enrichPosts` costs one extra upstream call for every item it enriches, on top of the row. `maxEnrichedItems` defaults to 10 for that reason.

**Cached rows are not live.** With `cacheMaxAge` set, some rows come from a cache and are marked `cached: true` with a `cached_at` timestamp. Do not use caching when you need current ad status.

**Personal profiles are not business pages.** The endpoint resolves them too. They return fewer fields and are personal data - treat them accordingly.

### ❓ FAQ

**Q: Does it search or discover pages by keyword?**
A: **No.** This Actor enriches **known page URLs**. There is no public Facebook page-search API. If you need page discovery, source URLs from Google search, a CRM export or a directory first, then run this Actor over the URL list.

**Q: What if a page hides its website or address?**
A: Those fields come back empty (`null` or omitted). Many pages publish a website but no address, or a category but no hours. That is expected and is not a bug - the Actor returns whatever Facebook makes public. Note that email and phone are **not** returned by this Actor at all, by design.

**Q: Coverage by page type?**
A: Business pages have the highest completeness (website, address, hours, category, ratings). Creator and community pages return identity, intro, ratings and engagement but often no location fields. Personal profiles return identity and limited metadata - treat them as personal data, not business contacts.

**Q: Is `adStatus` real-time?**
A: It reflects Facebook's Ad Library status at the time of the call, refreshed by Meta on their schedule. Good signal for outbound qualification; not a guarantee a specific ad is live in a specific country in the next minute.

**Q: Rate limits?**
A: No published hard limit. The Actor handles transient `429/502/503/504` responses automatically with 3 retries and exponential backoff (1s, 2s, 4s).

**Q: Is the data live or cached?**
A: Each run is a live fetch. UnseenUser does not cache or retain the data.

**Q: Is this legal?**
A: The Actor accesses public, logged-off page data only. Your downstream use of the data is your responsibility - see the Terms of Service section below.

**Q: What about Facebook's anti-scraping enforcement?**
A: Meta's Terms restrict automated extraction. Your downstream use must comply with Meta's Terms.

**Q: What if Meta sends a cease-and-desist?**
A: Notify UnseenUser within 48 hours via the Apify profile contact form (https://apify.com/UnseenUser) and cease using this Actor immediately.

**Q: Can I use this data to train AI?**
A: **No.** Meta's Terms prohibit AI training on Facebook data, and page posts and photos are copyrighted by their creators.

**Q: What about minors?**
A: Facebook has many under-18 users and some "pages" are personal profiles. This Actor's Terms strictly prohibit using data of users you know or suspect are minors.

**Q: Are the add-ons billed separately?**
A: Yes. Each enabled add-on (posts/events/photos/reels) is a separate billed event.

**Q: Does this Actor return email addresses or phone numbers?**
A: No. Both are stripped before anything is written to the dataset, by design. If you build outreach on the fields it does return (website, address), you still need a documented lawful basis and full anti-spam compliance - GDPR, CAN-SPAM, CASL, Israeli Anti-Spam Law. See the Addendum, Section G.

**Q: Is there a Facebook Page API for this?**
A: Meta's Graph API for Pages returns very little without a business verification and hits rate limits fast; several of the fields most useful for lead-gen (public rating, address, business hours, ad-running status) either need special access or are missing entirely. This Actor is the no-login shortcut for that gap - you paste page URLs, you get clean JSON.

**Q: How do I get data from a Facebook page in bulk?**
A: Paste one or many public page URLs into `startUrls`, run the Actor once, and download the dataset as CSV, JSON or XLSX. Each URL becomes one row with page details, category, website, address, ratings, follower counts, business hours and ad-running status.

**Q: How do I scrape a Facebook page without writing code?**
A: You do not need to write any code. Click **Try for free** on the Apify page, paste your URLs into the input form, click **Start**, and download the results. No Python, no proxies, no login.

**Q: How do I compare my Facebook Page with competitors?**
A: Pull the competitor pages' `followerCount`, `likeCount`, `rating`, `ratingCount`, `category` and `priceRange` in one run, then diff against your own page's values in a spreadsheet or BI tool. The pre-built **Audit Competitor Facebook Followers and Ratings** example task takes a list of URLs and returns exactly this shape.

**Q: What metrics should I track in a Facebook competitor analysis?**
A: For each competitor: `followerCount` (audience size), `likeCount` (loose engagement), `rating` + `ratingCount` (satisfaction), `category` (positioning), and `adStatus` (whether they are spending on paid). Track them monthly; the delta on `followerCount` and `ratingCount` shows momentum, and a flip on `adStatus` reveals when a rival starts or stops advertising.

**Q: Can I use Facebook Insights to monitor competitor pages?**
A: No. Facebook Insights only shows analytics for pages you own or admin. To benchmark competitor pages you need the public data those pages publish externally, which is exactly what this Actor returns for any list of URLs.

**Q: How can I tell if a Facebook page is currently running ads?**
A: The Actor returns `adStatus` on every row, sourced from Facebook's public Ad Library. If the value reads "This Page is currently running ads", the page has at least one active ad in the library right now. Pair with `adLibraryPageId` to hand off to the Meta Ad Library directly for the actual ad creatives.

**Q: How can I fetch Facebook Page details without a Page access token?**
A: You do not need a Page access token, a Graph API app, or App Review. Paste the page URL into the Actor, run it, get JSON back. No Facebook developer account, no `pages_read_engagement` scope, no Page Public Content Access approval.

**Q: How do I scrape public Facebook pages without getting blocked?**
A: Blocking is handled for you - the underlying data collection uses residential proxies, session management and rate control. Your job is to paste URLs and download the dataset. If a specific page returns an error, that single row emits an `error` field and the run continues on the next URL (per-URL error isolation).

### 🔧 Technical Details

- **Output:** streamed via Apify dataset; JSON, CSV, XLSX or via Apify API
- **Retries:** 3 with exponential backoff (1s, 2s, 4s) on `429/502/503/504`
- **Default path:** one Actor call per page, no pagination
- **Add-on pagination** is handled internally when toggles are enabled
- **Per-URL error isolation:** one bad URL does not crash the run
- **Live-view API** (OpenAPI 3 schema bound to the Actor): `/health`, `/status`, `/summary`

### Demo video

New to Apify? Two short videos cover the two things every recurring user of this Actor sets up.

**Schedule your Apify Actors** - run this Actor on a daily or weekly cron so your CRM and prospect lists stay fresh without you clicking Start:

[Watch: Schedule your Apify Actors](https://www.youtube.com/watch?v=GRFW_Loo2dk)

**Apify integrations** - pipe results straight into Google Sheets, Zapier, Slack, HTTP webhooks, or your own storage the moment the Actor finishes:

[Watch: Apify integrations](https://www.youtube.com/watch?v=bNACk1_S_6w)

### Related scrapers

Build a complete Facebook business-intelligence stack:

- [Facebook Page Posts Scraper](https://apify.com/unseenuser/fb-posts) - the same pages, but their recent posts and reels
- [Facebook Marketplace Scraper](https://apify.com/unseenuser/fb-marketplace) - commerce listings for the same local vertical
- [Meta Ad Library Scraper](https://apify.com/unseenuser/meta-ads) - the page runs ads? See exactly which ones
- [Instagram Profile Scraper](https://apify.com/unseenuser/igscraping) - the same business on Instagram
- [Google Ads Transparency Scraper](https://apify.com/unseenuser/Google-ads) - their Google ad spend

[See all 18 scrapers by unseenuser →](https://apify.com/unseenuser)

***

### Example tasks

Pre-built, paste-and-run example tasks for the most common workflows. Each links to its public page on Apify Store and to the same input you can copy into a fresh run.

- [Find Facebook Pages Currently Running Ads (Warm Leads)](https://apify.com/unseenuser/fb-pages/examples/fbpages-find-pages-running-ads) - Filter a prospect list to pages currently advertising via Facebook's Ad Library signal. Warm outbound targets with budget today.
- [Enrich CRM Contacts From a List of Facebook Pages](https://apify.com/unseenuser/fb-pages/examples/fbpages-crm-enrichment-from-url-list) - Bulk enrich your CRM with category, website, address, ratings, follower counts, and hours from a list of known Facebook page URLs.
- [Audit Competitor Facebook Followers and Ratings](https://apify.com/unseenuser/fb-pages/examples/fbpages-competitor-followers-ratings-audit) - Benchmark a list of competitor Facebook pages in one pull: follower count, like count, rating, rating count, category, and price range.
- [Pull Business Hours and Address From Facebook Pages](https://apify.com/unseenuser/fb-pages/examples/fbpages-local-business-hours-address) - Get opening hours, postal address, category, and ratings for a list of local business Facebook pages. Built for restaurant, clinic, and retail directories.
- [Extract Business Websites from Facebook Pages (Bulk)](https://apify.com/unseenuser/fb-pages/examples/fbpages-extract-business-websites-bulk) - Pull the official website URL from a list of Facebook business pages in one call. Export to CSV for cold outbound, CRM enrichment or lead scoring.

***

### Changelog

#### 2.1 - clean, consistent output

- **Events are properly mapped.** The events endpoint returns a GraphQL-shaped payload, and the field names had been written from documentation rather than an observed response - so an event row carried three mapped columns and dropped everything else into `raw`. Events now map `startsAt` (from `start_timestamp`), `dateText`, `locationName`, `locationCity`, `eventKind`, `isCanceled`, `isPast`, `isHappeningNow`, and the host onto the same `author*` columns posts and reels use. A real event row went from 3 populated columns to 18, with nothing left over. New **Events** dataset view.
- **Fixed: a failed storage write could kill a scrape.** The per-type copies and the error log are conveniences, but a failure writing either one propagated into the scrape and ended the add-on that was running. Both are now best-effort: if a storage cannot be opened or written, the reason is logged once and the run carries on. The default dataset - what gets billed and what the API serves - is never affected.
- **Named datasets are now prefixed** (`fb-pages-posts`, `fb-pages-errors`, and so on). Plain names like `posts` collide with storages an account may already hold from another Actor, and a run token scoped to one run cannot open a storage it did not create.
- **Fixed: an unbounded pagination loop.** All four add-ons decide when to stop by following a cursor the source API hands back. If that API ever returned the same cursor twice, the loop had no way out - with the `max*` fields at their `0 = unlimited` default, nothing capped it, so the run would fetch and bill forever. Any pagination position seen twice now ends that add-on and says so in the log.
- **Fixed: enrichment delivered fewer items than requested.** The per-page budget was charged for every item in a batch, including items with no URL that cannot be enriched at all, so a run asking for 10 enriched items could get 8. The budget is now charged only for items actually enriched.
- **Fixed: a run could hang after the scrape finished.** The live-view status server was closed with `server.close()`, which waits for every open connection to end - one keep-alive client would hold the run open indefinitely. Sockets are now dropped explicitly and the wait is bounded.
- **Fixed: one malformed item no longer drops the rest of a page.** An out-of-range timestamp made the date mapper throw `RangeError` instead of returning empty, which aborted the whole add-on mid-page - rows already streamed were kept, everything after was lost. Timestamps outside the range JavaScript dates support now map to empty, and any item that still fails to map is emitted as an identifiable row carrying `normalizeError` and its raw payload rather than taking the page down with it.
- **Internal errors are now named in the run log.** Failures from the source API stay generic on purpose, but an error thrown by the Actor itself now reports its type and message instead of a bare "Request failed", which was undebuggable.
- **Per-type datasets.** Every row is now also written to a named dataset for its type - `fb-pages-pages`, `fb-pages-posts`, `fb-pages-photos`, `fb-pages-reels`, `fb-pages-events` - alongside the default dataset. The default dataset has to carry every row type for billing, so the Console renders the union of all their columns and a photo row shows mostly blanks; the per-type copies are single-shape and rectangular. Measured on a mixed 81-row run: default 68.5% blank cells, `fb-pages-photos` and `fb-pages-reels` 0%. The copies are the same rows filed a second way and are **not billed again**.
- **Every dataset view now keeps `type`.** Apify views select columns, not rows, so a view built for page columns still lists post and photo rows. Previously the Ad activity and Contact views omitted `type`, which rendered those rows as a bare page URL with no way to tell what they were. Views renamed to describe their columns rather than imply filtering.
- **New default output shape.** Every row now starts with the same six columns - `type`, `pageUrl`, `pageName`, `id`, `url`, `scrapedAt` - and posts, reels, photos and events share field names wherever they mean the same thing. A mixed export lines up in one table instead of stair-stepping across 71 columns.
- **Duplicate columns removed.** The source API returned several values twice under different spellings (`commentCount` / `comment_count`, `text` / `description`, `url` / `permalink`, `publishTime` / `creation_time`). Each is now one canonical camelCase column. Timestamps are always ISO 8601.
- **Dead columns removed.** `videoViewCount` was never populated on any row; view counts now come through `viewCount`. `immersive_photo_encodings`, `photo_cix_screen`, `link_attachment` and `videos` were empty on every row and are gone.
- **Nested objects flattened.** `adLibrary.adStatus` and `adLibrary.pageId` are now the top-level columns `adStatus` and `adLibraryPageId`. `author` becomes `authorName` / `authorId` / `authorUrl` / `authorVerified`. `coverPhoto` and the three `profilePic*` sizes collapse to `coverPhotoUrl` and `profilePicUrl`. Page rows are roughly 57% smaller and content rows about 52% smaller, so the output tab renders faster.
- **Empty fields are omitted** instead of being written as `null`.
- **New `businessHoursText`** renders the weekly hours as one spreadsheet-friendly line alongside the structured `businessHours` array.
- **New `mediaType`** on content rows: `video`, `photo` or `text`.
- **Fixed: the same item is no longer billed twice.** On video-first pages the posts endpoint returns reels, so enabling both the posts and reels add-ons returned - and billed for - the same content twice. Items seen by more than one add-on are now emitted once per page, and the run log reports how many duplicates were dropped.
- **New `outputStyle` input.** Set it to `raw` for the previous passthrough shape, including the `title` / `likes` / `info` / `categories` / `followers` compatibility aliases. Default is `clean`.
- **Dataset views rebuilt:** Overview, Pages only, Contact list, Ad activity, Posts & reels, Photos.

#### 2.0 additions - caching, events fix, gated pages, enrichment

**Rows stream as they are scraped.** Previously every add-on for a page was fetched before anything was written, so on a page with hundreds of photos nothing appeared in the dataset for minutes. The page row now goes out the moment the page is fetched, and content rows follow batch by batch as pagination proceeds.

**Add-on failures no longer block the page.** If posts fail but photos succeed, you still get the page row and the photos. The failure is recorded in the unbilled `errors` dataset with an `addon` field naming which one failed.

**Failed URLs are no longer billed.** Error rows previously went to the default dataset, which meant a run where you pasted 20 malformed URLs charged you for 20 rows containing nothing but an error message. Failures now go to a separate `fb-pages-errors` dataset - still fully available in the run's Storage tab and over the API, just not billed. The `Errors` dataset view was removed since the default dataset no longer contains error rows.

**`cacheMaxAge` (new).** Reuse a recent cached result for page details instead of scraping fresh: `1d` / `3d` / `7d` / `14d` / `30d`. Cache hits are faster and cost nothing upstream. Affected rows carry `cached: true` and `cached_at` so you always know whether a row is live. Best paired with scheduled monitoring runs.

**Events pagination fixed.** `includeEvents` previously made a single upstream call and stopped, returning roughly the first 3 events regardless of how many the page listed. It now paginates until the page is exhausted or `maxEvents` is reached. If you relied on events, you will now get materially more of them - set `maxEvents` if you want the old bounded behaviour.

**`maxEvents` (new).** Same `0 = all` convention as the other `max*` fields.

**`includeGatedProfile` (new).** Age-restricted and private pages return the limited public fields Facebook still exposes rather than nothing.

**Page status fields surfaced.** `isPrivate`, `account_status`, `accountDoesNotExist`, `gender` and `links` are now documented in the dataset schema. You can finally tell "page is private" from "page does not exist" from "the scrape failed" - previously all three looked alike.

**Post and reel enrichment (new).** `enrichPosts` fetches full detail per post/reel: `share_count`, an accurate `view_count`, plus optional `getComments` and `getTranscript`. Costs one extra upstream call per item, so it is bounded by `maxEnrichedItems` (default 10). Items that fail enrichment keep their original shape and gain an `enrichmentError` rather than failing the page.

**Account metadata stripped from output.** The upstream API wraps responses with `success`, `credits_charged` and `credits_remaining`. These were previously being written into page rows. They are now removed at the client boundary and never reach the dataset.

#### 2.0 - BREAKING: one row per scraped item

**What changed.** Previously the Actor returned **one row per page**, with add-on content nested inside it as arrays (`posts`, `photos`, `reels`, `events`). Now every scraped item is **its own row**, emitted in this order:

```
page  -> posts -> photos -> reels -> events -> (next page)
```

**Why.** Nested arrays meant a run returning 1 page plus 300 posts and 1,000 photos counted as a single billed result. Content you asked for was not being counted. Each item is now a row, so what you receive and what you are billed for match.

**Every row now carries:**

| Field | Meaning |
|---|---|
| `type` | `page`, `post`, `photo`, `reel`, `event` or `error` |
| `pageUrl` | The page the row belongs to - join key for content rows |
| `pageName` | Name of the parent page (content rows only) |

**Migration.** If you read `row.posts`, `row.photos`, `row.reels` or `row.events` as nested arrays, that code returns nothing after this build. Filter on `type` instead:

```js
// before
const posts = row.posts ?? [];

// after
const posts = items.filter((r) => r.type === 'post' && r.pageUrl === myPageUrl);
```

To get the old page-only shape, filter to `type === 'page'`.

**Billing.** Each row is one billed result. A page with 500 posts and no cap produces 501 billed rows. `maxPosts`, `maxPhotos` and `maxReels` still default to `0 = all`, so **set a number if you want a ceiling** - the run log now prints a `NO CAP SET` warning when an add-on runs uncapped.

**Also in this build:**

- Error rows are tagged `type: "error"` so they filter out cleanly.
- The run summary and `OUTPUT_SUMMARY` gain `row_counts` (per-type breakdown) and `total_rows`.
- Add-on failures no longer lose their error - they land on that page's row as `postsError` / `photosError` / `reelsError` / `eventsError`, and the run continues.
- Input schema descriptions corrected: they previously implied per-item billing that was not happening.

#### Earlier build

**Numeric limit convention: `0 = fetch every available item (no cap)`.** Applied to `maxPosts`, `maxPhotos`, and `maxReels`. Motivation: standardize the convention so users can opt into unlimited pulls explicitly and accept the full bill, without a hidden schema ceiling that only appears at API-call time.

- **`maxPosts` default changed from `9` to `0`.** After this build, a run with `includePosts: true` and no explicit `maxPosts` will fetch every post the page publishes, not the previous 9. If you want the old behavior, set `maxPosts: 9` explicitly on your task or API call.
- **`maxReels` default changed from `10` to `0`.** Same shape. Set `maxReels: 10` explicitly for the old behavior.
- **`maxPhotos` semantics changed.** The default stays `0`, but `0` no longer means "single page of photos" - it now means "every photo the page has". If you want a single page, set an explicit `maxPhotos` value (for example `12`).
- Schema `maximum` removed from all three fields (schema caps are bypassable via API). No hard cap in code either: `0` means unlimited and you accept the full bill for whatever the page has.
- Invalid values (negative, non-integer, or below the upstream page size when non-zero) now fail the run with a clear error in the run status, instead of silently rounding.

**Input form restructure.** Collapsible sections: **Facebook pages to scrape**, **Posts**, **Photos**, **Reels**. `Include events` moved to the top section (one-shot with no `max`). Billing is disclosed once per section in the section description ("every returned row is billed") rather than repeated in every header and toggle label.

**Repositioning as all-in-one.** Actor short description now reads: *"Facebook Page Scraper: details, contact, ratings, ad-status, plus optional posts, events, photos and reels. One URL in, all page data out. No login."* README H1 signals the same breadth. Keywords refreshed for the new positioning.

**Documentation.** Added Demo video section (Schedule + Integrations videos), 6 GEO-derived FAQ entries, and extended the Related scrapers cross-links.

**Tasks.** 5 example tasks in the bootstrapper; added `Extract Business Websites from Facebook Pages (Bulk)` chasing the 880/mo `facebook website scraper` keyword.

***

## 🛡️ Apify Actor - Terms of Service

**Version:** 4.0
**Effective Date:** May 5, 2026

***

### 0. ACCEPTANCE BY USE - IMPORTANT

**Read this section first.**

These Terms of Service ("Terms") form a binding legal agreement between you ("User," "you," "your") and UnseenUser, the Publisher of this Apify actor ("UnseenUser," "the Publisher," "we," "us," "our").

#### 0.1 How You Accept These Terms

You accept these Terms by **any of the following actions**, each of which constitutes a clear, affirmative act of acceptance:

- (a) **Running the Actor** - Initiating any execution of the Actor on the Apify platform
- (b) **Using any output** returned by the Actor for any purpose
- (c) **Continuing to access** the Actor's listing or documentation after these Terms are visible

#### 0.2 Continuing Acceptance

Each time you run the Actor or use its outputs, you reaffirm your acceptance of the then-current Terms. If you do not agree to these Terms or any subsequent update, you must stop using the Actor immediately.

#### 0.3 No Anonymous Acceptance

You cannot disclaim acceptance by:

- Failing to read these Terms before running the Actor
- Running the Actor through automated systems
- Sharing your Apify account with others who may not have read these Terms

By the act of running the Actor on Apify, you bind yourself, your organization (if applicable), and any individuals or systems acting on your behalf or under your authority.

#### 0.4 If You Do Not Accept

**If you do not agree to these Terms, you must not run the Actor.** No use is authorized without acceptance.

***

### PREAMBLE - UNDERSTANDING THE ARCHITECTURE

Before using the Actor, please understand the technical architecture of the service:

#### The Data Flow

You (User) -> Apify Platform -> Actor (software) -> Third-Party API -> Source Platform

You (User) <- Apify Platform <- Actor (software) <- Third-Party API

#### What Each Party Does

- **You (the User):** Run the Actor on the Apify platform with input parameters you choose
- **Apify:** Operates the cloud infrastructure that hosts and executes Actors. Apify is a Czech-incorporated company (Apify Technologies s.r.o.) governed by its own Terms of Service.
- **The Publisher (us):** Publishes software code (the Actor) on Apify's platform. The Actor is a thin wrapper that translates your input into requests to a third-party API and returns the API's responses to you. **The Publisher does not operate scraping infrastructure. The Publisher does not store or retain data returned by the Actor. The Publisher does not see, log, or process the personal data of any individuals returned in the Actor's outputs beyond what is incidental to passing the data through.**
- **Third-Party API Provider:** HarvestAPI (https://harvest-api.com) or Scrape Creators (https://scrapecreators.com). These are independent third-party companies that operate scraping infrastructure and return data from source platforms.
- **Source Platform:** LinkedIn, TikTok, YouTube, Reddit, Linktree, etc. These are the platforms whose publicly visible data is accessed by the Third-Party API Providers.

#### Why This Matters

Your relationship with the Publisher is that of a **software user** to a **software vendor**. The Publisher has the responsibilities of a software vendor (functional code, accurate documentation) and the limits of one (the Publisher is not responsible for how you use the data you obtain).

***

These Terms operate alongside but do not replace:

- Apify's Terms of Service and Acceptable Use Policy (governing your relationship with Apify)
- HarvestAPI Terms of Service and Scrape Creators Terms of Service (governing the underlying data infrastructure)
- Source Platform terms (LinkedIn, TikTok, etc.) governing the public data accessed
- Applicable law in your jurisdiction and the jurisdictions of data subjects

These Terms incorporate the actor-specific addendum published in each Actor's individual listing ("Addendum"). In the event of a conflict, the more restrictive provision applies.

***

### 1. NATURE OF THE SERVICE

#### 1.1 What the Actor Is

The Actor is a software program published on the Apify platform. Each Actor:

- (a) Accepts structured input from you on the Apify platform
- (b) Translates that input into HTTP requests to a third-party API operated by HarvestAPI or Scrape Creators
- (c) Receives HTTP responses from that third-party API
- (d) Returns the response data to you in a structured format on the Apify platform

The Actor's source code is hosted on Apify's infrastructure. The Actor runs in Apify's cloud, not on the Publisher's servers. The Publisher operates no servers running the Actor.

#### 1.2 What the Actor Is Not

The Actor is **not**:

- (a) A scraping tool - the Publisher does not operate scraping infrastructure, proxies, headless browsers, or fake accounts
- (b) A direct connection to any source platform - connections to source platforms are made by HarvestAPI / Scrape Creators
- (c) A data storage or data retention service - the Publisher does not maintain a database of any data the Actor returns
- (d) A licensed access channel to LinkedIn, TikTok, YouTube, Reddit, X (Twitter), Meta, Linktree, or any other source platform
- (e) Affiliated with, endorsed by, sponsored by, or authorized by any source platform

#### 1.3 The Publisher's Limited Role

The Publisher's role is limited to:

- (a) Designing and writing the Actor's source code
- (b) Publishing the Actor on the Apify Store
- (c) Maintaining the Actor (updating it when API providers change schemas)
- (d) Providing documentation and customer support via Apify's contact mechanism

The Publisher is a software vendor, similar to a developer who publishes an app on the Apple App Store or Google Play Store. The Publisher is not a data provider, data broker, data processor, or data controller for purposes of GDPR, CCPA, Israel's Privacy Protection Law, or equivalent.

#### 1.4 The Third-Party API Providers' Role

HarvestAPI (https://harvest-api.com) and Scrape Creators (https://scrapecreators.com) are independent third-party companies. They:

- (a) Operate the actual data scraping infrastructure
- (b) Maintain relationships with source platforms (or accept the operational risk of accessing public data without such relationships)
- (c) Are themselves Apify publishers (HarvestAPI publishes 9+ actors directly; Scrape Creators publishes 10+)
- (d) Provide their own Terms of Service governing their operations
- (e) Are responsible for compliance obligations relating to the data collection itself

The Publisher is a customer of these providers. The Publisher is not their agent, partner, or representative.

***

### 2. WHO MAY USE THE ACTOR

#### 2.1 Eligibility

You may use the Actor only if:

- (a) You are at least 18 years old or the age of majority in your jurisdiction
- (b) You have legal capacity to enter into binding contracts
- (c) You are not located in or resident of a country subject to comprehensive sanctions by the United States, European Union, United Kingdom, or Israel
- (d) You are not on any prohibited persons list

#### 2.2 User Representations

By using any Actor, you represent and warrant that:

- (a) **Truthful identity:** Information you provide about your identity and intended use is accurate
- (b) **Lawful intent:** Your intended use complies with applicable law in your jurisdiction
- (c) **Source platform compliance:** You will independently comply with the Terms of Service of any source platform whose data you obtain through the Actor
- (d) **Data subject rights:** Where Actor outputs include personal data, you will respect data subject rights under applicable law
- (e) **No prohibited use:** You will not use the Actor for any of the purposes prohibited in Section 4

These representations are continuous - they must remain true throughout your use.

***

### 3. PERMITTED USES

The Actor may be used for any lawful purpose, including:

- Market research and competitive analysis
- Academic research
- Journalism and investigative reporting
- Internal business intelligence
- Brand monitoring
- Recruitment research where consistent with applicable employment law
- Building products that further process publicly available information lawfully

Specific permitted uses for each Actor are described in that Actor's individual listing and Addendum.

***

### 4. PROHIBITED USES

You may not use the Actor for any of the following:

#### 4.1 Illegal Activity

Activity illegal under the law of your jurisdiction, the User's jurisdiction, or the jurisdiction of any data subjects.

#### 4.2 Harassment, Stalking, and Personal Targeting

- Compiling profiles for harassment, stalking, or doxxing
- Tracking individuals' movements or activities without their knowledge
- Building profiles of journalists, activists, dissidents, or vulnerable populations for retaliatory purposes

#### 4.3 Discrimination

- Using outputs for discriminatory employment, lending, housing, or insurance decisions based on protected characteristics
- Building lists for discriminatory purposes

#### 4.4 Spam and Unsolicited Commercial Communication

- Sending unsolicited marketing in violation of CAN-SPAM, CASL, GDPR, PECR, Israeli Anti-Spam Law (Section 30A of the Communications Law), or equivalent laws
- Building "lead lists" from scraped contacts without proper consent infrastructure
- Reselling contact data for spam purposes

#### 4.5 Fraud and Deception

- Identity theft or impersonation
- Generation of fake reviews, testimonials, or coordinated inauthentic behavior
- Election interference or political disinformation
- Securities fraud

#### 4.6 Source Platform Abuse

- Using outputs to circumvent technical protection measures of source platforms
- Creating fake accounts on source platforms based on Actor outputs
- Vote manipulation, engagement manipulation, or platform algorithm gaming
- Building services that competitively substitute for source platforms

#### 4.7 Reselling the Actor's Service

- Reselling raw Actor outputs as your own data product or scraping-as-a-service
- Sharing your Apify credentials to provide third parties indirect access
- Building competing API services using Actor outputs

#### 4.8 AI Training Without Authorization

- Using Actor outputs as training data for commercial AI/ML models without separate licensing authority from the source platform

#### 4.9 Sensitive Targeting

- Specifically targeting or profiling based on health conditions, sexual orientation, religious beliefs, political opinions, or other sensitive characteristics
- Targeting children under 16 (or local age of consent for data processing)

#### 4.10 Privacy Law Violations

- Processing personal data of EU/UK/California/Israeli residents without complying with applicable privacy law
- Failing to honor data subject access, deletion, or objection requests
- Processing data for purposes incompatible with its publication context

***

### 5. SOURCE PLATFORM TERMS - YOUR RESPONSIBILITY

#### 5.1 Acknowledgment

The Actor accesses publicly visible data on third-party platforms ("Source Platforms") through the Third-Party API Providers (HarvestAPI / Scrape Creators). Source Platforms include LinkedIn, TikTok, YouTube, Reddit, X (Twitter), Meta/Facebook, Linktree, Komi, Pillar, Linkbio, Linkme, and Amazon.

#### 5.2 Your Sole Responsibility

You acknowledge:

- (a) **You are solely responsible for ensuring your downstream use of data obtained through the Actor complies with the Source Platform's Terms of Service**
- (b) The Publisher makes no representation that any specific use is permitted under any Source Platform's terms
- (c) The Third-Party API Providers, not the Publisher, bear responsibility for the lawfulness of the data collection itself
- (d) You should review Source Platform terms before commercial use:
  - LinkedIn: https://www.linkedin.com/legal/user-agreement
  - TikTok: https://www.tiktok.com/legal/page/global/terms-of-service/en
  - YouTube: https://www.youtube.com/static?template=terms
  - X: https://twitter.com/en/tos
  - Reddit: https://www.redditinc.com/policies/user-agreement
  - Meta: https://www.facebook.com/legal/terms
  - Linktree: https://linktr.ee/s/terms/

#### 5.3 Cease-and-Desist Compliance

If you receive a cease-and-desist letter or other legal demand from a Source Platform regarding your use of Actor outputs, you must:

- (a) Cease the contested use immediately
- (b) Notify UnseenUser within 48 hours via UnseenUser's Apify profile contact form (https://apify.com/UnseenUser)
- (c) Cooperate with the Publisher as needed to mitigate
- (d) Not assert against the Publisher any claim arising from your inability to use the Actor for that Source Platform

***

### 6. DATA PROTECTION - REFLECTING ACTUAL ARCHITECTURE

#### 6.1 Roles Under Privacy Law

For purposes of GDPR, UK GDPR, CCPA, Israel's Privacy Protection Law (PPL) including Amendment 13, and equivalents:

- **You (the User) are the Data Controller** of any personal data you obtain through the Actor and subsequently process for your own purposes
- **HarvestAPI and Scrape Creators** are the entities that collect data from source platforms - they bear the responsibilities of data processors or controllers (depending on context) for the collection itself
- **The Publisher acts solely as a software vendor**, not as a data controller or processor, because the Publisher does not store, retain, or substantively process personal data - the Actor merely passes API responses through

#### 6.2 No Data Retention by the Publisher

The Publisher confirms:

- (a) The Publisher does not maintain a database of personal data obtained through the Actor
- (b) The Actor passes data from the Third-Party API directly to you on the Apify platform - data does not flow through the Publisher's infrastructure
- (c) Apify's standard execution and operational logging may include limited information about Actor runs (input parameters, run duration, data volume) - this is governed by Apify's own privacy practices
- (d) The Publisher does not access, view, or analyze your Actor outputs except as needed for technical support if you specifically share them with the Publisher

#### 6.3 Your Obligations as Data Controller

Where your use of the Actor involves processing personal data, you are responsible for:

- (a) Establishing a lawful basis for your processing (consent, legitimate interest with documented balancing test, contract, etc.)
- (b) Providing transparent notice to data subjects as required by applicable law
- (c) Honoring data subject access, rectification, erasure, restriction, and portability requests
- (d) Implementing appropriate security measures
- (e) Conducting Data Protection Impact Assessments where required
- (f) Appointing a Data Protection Officer if your operations require one
- (g) Registering databases with applicable supervisory authorities
- (h) Honoring opt-out requests for direct marketing
- (i) Cross-border transfer safeguards where data crosses borders

#### 6.4 Israel's Amendment 13 - User Compliance

If your use of the Actor involves Israeli residents' personal data, you must comply with the Privacy Protection Law as amended (Amendment 13, effective August 14, 2025). These obligations are yours as the data controller, not the Publisher's as the software vendor.

#### 6.5 Sensitive Data Targeting Restrictions

You will not use the Actor to specifically target, profile, or build datasets focused on:

- Health or medical conditions
- Religious beliefs
- Political opinions
- Sexual orientation or gender identity
- Genetic or biometric data
- Criminal history
- Children under 16

***

### 7. INTELLECTUAL PROPERTY

#### 7.1 Actor Code

The Actor's source code, schemas, documentation, and branding are owned by the Publisher. You receive a limited, non-exclusive, non-transferable, revocable license to use the Actor for permitted purposes during your active subscription/run with Apify.

#### 7.2 Output Data

The Publisher claims no ownership over the public data the Actor returns. Source Platforms may have copyright, database rights, or other rights in their data; data subjects may have copyright in user-generated content. Your use of output data must respect these rights independently.

#### 7.3 Restrictions

You may not reverse engineer, decompile, or reuse the Actor's code in a competing actor.

#### 7.4 Feedback

Feedback you provide may be used by the Publisher to improve products without compensation to you.

***

### 8. PRICING AND PAYMENT

#### 8.1 Apify Platform Billing

Pricing is administered through Apify's pricing models. Apify processes all payments. Apify's payment terms govern refunds and disputes.

#### 8.2 Pricing Changes

The Publisher may change Actor pricing with at least 14 days' notice via the Actor's Apify listing.

#### 8.3 No Refunds for Misuse

If your access is suspended or terminated for breach of these Terms, you forfeit any unused balance and are not entitled to refunds.

***

### 9. SERVICE AVAILABILITY AND CHANGES

#### 9.1 No Uptime Guarantee

The Actor depends on:

- (a) The Apify platform
- (b) Underlying API providers (HarvestAPI, Scrape Creators)
- (c) Source Platforms' continued public accessibility

Any of these may change behavior, restrict access, or become unavailable without notice. The Publisher makes no uptime guarantees.

#### 9.2 Service Discontinuation

The Publisher may discontinue any Actor at any time. Reasonable notice will be provided when feasible.

***

### 10. DISCLAIMERS

#### 10.1 "AS IS" Service

THE ACTOR IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR PURPOSE, NON-INFRINGEMENT, OR ACCURACY OF DATA.

#### 10.2 No Representation of Lawfulness

The Publisher makes no representation that your specific use of the Actor or the data it returns is lawful in your jurisdiction or under any Source Platform's terms. The burden of determining lawfulness for your use case is yours.

#### 10.3 No Endorsement of Source Content

Content returned by the Actor was created by third parties. The Publisher does not endorse, verify, or take responsibility for it.

***

### 11. LIMITATION OF LIABILITY

#### 11.1 Aggregate Liability Cap

TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE AGGREGATE LIABILITY OF THE PUBLISHER FOR ALL CLAIMS RELATING TO THE ACTOR EXCEED THE GREATER OF:

- (a) ONE HUNDRED U.S. DOLLARS (US $100), OR
- (b) THE AMOUNTS YOU PAID THROUGH APIFY FOR USE OF THE ACTOR IN THE THREE (3) MONTHS IMMEDIATELY PRECEDING THE EVENT

#### 11.2 Excluded Damages

THE PUBLISHER IS NOT LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR LOSS OF PROFITS, REVENUE, OR DATA, EVEN IF ADVISED OF THE POSSIBILITY.

#### 11.3 Time Limit

Any claim must be brought within one (1) year of the event.

***

### 12. INDEMNIFICATION

#### 12.1 Your Indemnification of the Publisher

You agree to defend, indemnify, and hold harmless the Publisher from any:

- Claims arising from your use of the Actor
- Claims arising from your violation of these Terms
- Claims arising from your violation of any law (including privacy law)
- Claims arising from your violation of any Source Platform's Terms of Service
- Claims arising from your processing of personal data obtained through the Actor
- Reasonable attorneys' fees and costs of defending such claims

#### 12.2 Defense

The Publisher may assume defense at your expense. You will cooperate with the Publisher's defense.

#### 12.3 Scope

The indemnification covers reasonable, foreseeable third-party claims arising from your use. It does not extend to:

- Claims arising from the Publisher's gross negligence or willful misconduct
- Claims regarding the Actor's source code itself (those are the Publisher's responsibility)
- Claims regarding the Third-Party API Provider's data collection (those are their responsibility)

***

### 13. SUSPENSION AND TERMINATION

#### 13.1 Termination by the Publisher

The Publisher may terminate your access for material breach, illegal use, breach of warranty, or upon credible legal demand.

#### 13.2 Effects of Termination

Your license ends, you must cease use, and applicable provisions survive.

#### 13.3 Termination by You

You may stop using the Actor at any time on Apify.

***

### 14. DISPUTE RESOLUTION

#### 14.1 Informal Resolution First

Send a detailed written description of the dispute via UnseenUser's Apify profile contact form (https://apify.com/UnseenUser) and wait 60 days for resolution attempt before any formal claim.

#### 14.2 Governing Law

These Terms are governed by the substantive laws of the State of Israel, without regard to conflict of law principles.

#### 14.3 Exclusive Jurisdiction

Any dispute shall be brought exclusively in the competent civil courts of Tel Aviv-Jaffa, Israel.

#### 14.4 No Class Actions

You agree to bring claims only in your individual capacity.

#### 14.5 Attorneys' Fees

The prevailing party recovers reasonable attorneys' fees.

***

### 15. MISCELLANEOUS

#### 15.1 Entire Agreement

These Terms (with Addendum and incorporated documents) are the entire agreement.

#### 15.2 Severability

Unenforceable provisions are reformed to the minimum extent or severed.

#### 15.3 Assignment

You may not assign without the Publisher's consent. The Publisher may assign to affiliates, successors, or acquirers.

#### 15.4 Force Majeure

Neither party is liable for failure due to events beyond reasonable control, including changes by Source Platforms or Third-Party API Providers, or actions by Apify.

#### 15.5 Third-Party Beneficiaries

Apify, HarvestAPI, and Scrape Creators are intended third-party beneficiaries of Sections 4 (Prohibited Uses), 5 (Source Platform Compliance), and 12 (Indemnification).

#### 15.6 Survival

Sections 0 (Acceptance), 4, 5, 6, 7, 10, 11, 12, 14, and 15 survive termination.

#### 15.7 Language

English controls. Translations are for convenience only.

#### 15.8 Publisher Identification for Legal Process

The Publisher operates on the Apify platform under the username **UnseenUser** (apify.com/UnseenUser). The Publisher is a registered legal entity. Upon receipt of valid legal process (subpoena, court order, or equivalent) directed through Apify's official channels, the Publisher's full legal identity may be disclosed as required by law. This Section ensures that you have a valid path to legal recourse if needed.

***

### 16. ACKNOWLEDGMENT

By using any Actor, you acknowledge that:

- (a) You have read these Terms
- (b) You understand the architecture: you are using software (the Actor) on Apify's platform that calls third-party APIs
- (c) You accept responsibility for your use, including for compliance with Source Platform terms
- (d) Your indemnification obligations cover third-party claims arising from your use
- (e) Disputes are resolved in Israeli courts
- (f) The Publisher's identity, while not publicly disclosed in this listing, can be obtained through valid legal process via Apify

For questions, use UnseenUser's Apify profile contact form (https://apify.com/UnseenUser) before running the Actor.

***

## 🛡️ Actor-Specific ToS Addendum - 📘 Facebook Pages Scraper

This addendum supplements the Master Terms of Service V4.0. By running this Actor, you accept both the Master ToS and this addendum.

#### A. Architectural Disclosure

This Actor is a software wrapper. It accepts your input parameters, calls the Scrape Creators `/v1/facebook/profile` endpoint for each page (and, only when you enable them, the `/profile/posts`, `/profile/events`, `/profile/photos` and `/profile/reels` add-on endpoints), and returns the response data to you on the Apify platform. UnseenUser does not store, log, or substantively process the data returned. The data flows from Scrape Creators through Apify's runtime directly to you.

#### B. Nature of Data Returned

This Actor returns Facebook page details: page name, category, intro, creation date, **website and physical address**, services and price range, ratings and rating count, like and follower counts, business hours, an ad-running status signal (`adLibrary.adStatus`), and profile/cover imagery. When add-ons are enabled it also returns posts (text, author, engagement counts, video details, top comments), events, photos (with native captions), and reels. **This Actor does not return email addresses or telephone numbers.** Both are removed before any data is written to the dataset.

Where the Actor's output includes individual people's names, photos, contact details, or content authored by them, that data constitutes **personal data** subject to GDPR, CCPA, Israeli Privacy Protection Law (including Amendment 13), and equivalent privacy laws in your downstream processing - but **only in your hands as the data controller**, not in UnseenUser's hands as the software vendor. The location fields here (physical address, website) are the contact-adjacent data that privacy regulators scrutinize most closely, and a page's "business" address is frequently a home address.

#### C. Permitted Use Cases

You may use this Actor for the following purposes (non-exhaustive list):

- **B2B lead generation** - pull website, address and category for a list of known business pages
- **CRM enrichment** - fill in website, category and rating fields for accounts you already track
- **Local-business prospecting** - build outreach lists for a vertical
- **Competitor research** - check ratings, follower counts and ad-running status
- **Ad-activity monitoring** - surface which pages are currently advertising
- **Market mapping** - profile categories and engagement across a defined set of pages

#### D. Specifically Prohibited Uses

In addition to Master ToS Section 4 prohibitions, you may NOT:

- Send mass cold email or DMs using scraped contact data without anti-spam compliance (GDPR, CAN-SPAM, CASL, Israeli Anti-Spam Law)
- Build or sell a "people search" website or contact list without a consent infrastructure and the required transparency notices
- Resell raw contact lists as a standalone data product (data broker activity)
- Harvest contact details from personal (non-business) profiles for targeting or outreach
- Use ratings, reviews or engagement data to harass or pressure a page owner
- Use sensitive inferences (for example religion or politics inferred from a page's category or content) to make hiring, lending or housing decisions
- Train commercial AI/ML models on page posts, photos or captions without separate licensing authority

#### E. Platform Terms of Service Considerations

Meta's Terms of Service prohibit automated extraction. Meta has aggressively litigated against scrapers (Meta v. BrandTotal - settled with permanent injunction; Meta v. Octopus Data; Meta v. Bright Data - pending). Facebook's Terms of Service prohibit automated extraction. This Actor accesses publicly visible page data via Scrape Creators - Scrape Creators bears responsibility for the lawfulness of the data collection. Your downstream use must independently comply with Meta's Terms of Service.

If Meta issues a cease-and-desist regarding data obtained via this Actor, notify UnseenUser within 48 hours via the Apify profile contact form (apify.com/UnseenUser) and cease your use immediately.

#### F. Contact Data - Heightened Care

Physical address is high-sensitivity personal data. It reveals where to locate a person or business, and it is among the fields that direct-marketing and privacy regimes regulate most closely. This Actor does not return email addresses or telephone numbers, but the obligations below still apply to the location and identity data it does return, and to any contact data you obtain elsewhere and combine with it:

- Store only the contact fields you actually need (data minimization, GDPR Article 5(1)(c))
- Do not retain contact lists indefinitely - set retention limits
- Where a page is a sole proprietor or individual, the "business" address may be a home address - treat it as personal data

#### G. Prospecting Compliance

If you use this Actor for B2B prospecting, cold outreach or lead generation:

- Establish a documented lawful basis (typically legitimate interest with a completed Legitimate Interest Assessment / balancing test)
- Honor opt-outs and the right to object under GDPR Article 21 (absolute for direct marketing, not subject to a balancing test)
- Comply with GDPR, CCPA, Israeli Anti-Spam Law (prior consent required for marketing in Israel), CAN-SPAM, CASL and equivalents
- Issue Article 14 transparency notices when you collect personal data from a source other than the data subject
- Do not use sensitive inferences (health, religion, politics) as a basis for any outreach
- Disclose, when asked, how you found the recipient

#### H. Business vs Personal Pages

Not every "page" is a business. The `/profile` endpoint also returns data for personal profiles and creator pages. When a page is ambiguous or clearly a private individual, treat the data as personal data of an individual (not business contact data) and apply the full data-controller obligations. Do not assume a contact field is fair game for outreach simply because it was publicly visible.

#### I. The Data Broker Question

Contact data across MANY pages IS a data broker asset. California's data broker registration requirements (effective 2024+) apply if you collect personal data from a source that is not the consumer and sell or share that data. If your business model includes selling contact lists or insights derived from them, you may need to register as a data broker in California (and possibly other states), and you trigger GDPR Article 14, the California Delete Act (effective 2026), and Israeli Privacy Law Amendment 13 (statutory damages of NIS 10,000 per data subject without proof of harm). Consult an attorney.

#### J. AI Training - Special Notice

Meta's Terms of Service prohibit using Facebook data to train AI/ML models without authorization. Page posts, photos and captions are no exception. The Publisher (UnseenUser) does NOT authorize, and has no ability to authorize, AI training use. Recent litigation (NYT v. OpenAI, Andersen v. Stability AI, multiple class actions) shows AI training on platform data is contested. Get proper licensing or do not train on this data. Your AI training use is your own legal exposure.

#### K. Cross-Platform Aggregation Limit

Do NOT aggregate this Facebook page data with LinkedIn, Instagram, TikTok, X/Twitter and other personal data to build comprehensive cross-platform identity profiles of named individuals. Cross-platform aggregation multiplies the personal-data risk, triggers heightened GDPR scrutiny (the combination is itself processing), has been the basis for Meta lawsuits (Meta v. BrandTotal, Meta v. Octopus Data), and creates "people search" profiles that the California Delete Act, GDPR Article 14, and Israeli Privacy Law Amendment 13 specifically target.

#### L. Minor Protection - CRITICAL

Facebook has a significant under-18 user population, and some pages are personal profiles that may belong to minors. You MUST:

- NOT use this Actor to scrape contact data or content of users you know or suspect are minors
- NOT use this Actor for any product or service targeted at minors without parental-consent mechanisms compliant with COPPA (US), GDPR Article 8 (EU), and Israeli Privacy Law (heightened sensitivity for minors)
- DELETE any data you discover relates to a minor unless you have valid parental consent

If page metadata or content suggests the subject is under 18, treat the page as belonging to a minor by default. This restriction is non-negotiable - minor-data violations carry the highest regulatory penalties.

#### M. Data Subject Rights - Operational Requirements

Individuals whose personal data you collect have rights under GDPR / CCPA / Israeli Privacy Law:

- **Right to access** - they can demand to know what you hold about them
- **Right to deletion** - they can demand removal from your databases (Article 17)
- **Right to object** - to processing for direct marketing (absolute under GDPR Article 21)
- **Right to rectification** - to correct inaccurate data
- **Right to portability** - a machine-readable copy

Build operational processes from day one to honor these with a typical 30-day SLA: a dedicated request email, a 30-day response SLA, a log of all requests and responses, and a privacy policy linked from any product or outreach using this data.

#### N. Cease-and-Desist Protocol

If a data subject contacts YOU directly demanding deletion of their data:

- Honor the request promptly (typically within 30 days under GDPR)
- Do NOT route them to UnseenUser - UnseenUser is the software vendor, not the data controller
- You may suggest they contact Meta directly (since the data originates there) and comply with your own deletion obligations
- Document the request and your response

If Meta, Scrape Creators, or a regulator contacts UnseenUser regarding your use, UnseenUser will notify Apify per Master ToS Section 8, may suspend access to this Actor pending investigation, and you agree to provide documentation of your lawful basis and processing activities on reasonable request.

***

For questions about these Terms, use UnseenUser's Apify profile contact form: https://apify.com/UnseenUser

***

*Keywords: facebook pages scraper, facebook page data, facebook page details scraper, facebook business pages, facebook page api, facebook lead generation, facebook business scraper, facebook crm enrichment, facebook page competitor analysis, facebook no login scraper.*

# Actor input Schema

## `startUrls` (type: `array`):

One or more public Facebook page URLs, one per line. Use the full page URL, for example https://www.facebook.com/mantraindianfolsom. Click Bulk edit to paste a large list at once.

## `getBusinessHours` (type: `boolean`):

Include the weekly opening hours for each page (Monday through Sunday). No extra cost.

## `cacheMaxAge` (type: `string`):

Reuse a recent cached result for page details instead of scraping fresh. A cache hit is faster and the row is marked with cached: true and cached\_at. Leave as Always fetch live if you need real-time data such as current ad status.

## `includeGatedProfile` (type: `boolean`):

When a page is age-restricted or private, still return the limited public fields Facebook exposes (id, name, category, likeCount, profile picture, links) instead of an empty result. Has no effect on normal public pages.

## `includeEvents` (type: `boolean`):

Also return the page's public events. Each event is emitted as its own row in the dataset and is billed as one result.

## `maxEvents` (type: `integer`):

Only used when Include events is on. Events paginate about 3 per upstream call, so a page with many events costs several calls.

## `includePosts` (type: `boolean`):

Also return the page's recent posts: text, engagement counts, author, top comments, and video details.

## `maxPosts` (type: `integer`):

Only used when Include posts is on. At 0 there is no cap and you accept the full bill for however many posts the page has. Minimum when non-zero: 3 (upstream page size).

## `enrichPosts` (type: `boolean`):

Fetch full detail for each post and reel: share count, accurate view count, and optionally comments and a video transcript. This costs ONE extra upstream call per item on top of the row itself, so it is the most expensive option here. Use Max items to enrich to bound it.

## `maxEnrichedItems` (type: `integer`):

Caps how many posts and reels per page get the extra detail call. Items beyond the cap are still returned, just without enrichment. Strongly recommend a small number here.

## `getComments` (type: `boolean`):

Fetch the full comment thread for each enriched post or reel. Only applies when enrichment is on.

## `getTranscript` (type: `boolean`):

Fetch a transcript for each enriched video post or reel. Only applies when enrichment is on and the item is a video.

## `includePhotos` (type: `boolean`):

Also return the page's photos with Facebook's native captions (alt-text).

## `maxPhotos` (type: `integer`):

Only used when Include photos is on. At 0 there is no cap and you accept the full bill for however many photos the page has.

## `includeReels` (type: `boolean`):

Also return the page's recent reels.

## `maxReels` (type: `integer`):

Only used when Include reels is on. At 0 there is no cap and you accept the full bill for however many reels the page has. Minimum when non-zero: 10 (upstream page size).

## `outputStyle` (type: `string`):

Clean maps every row onto a small, stable set of camelCase columns that line up across pages, posts, photos and reels. Raw returns each item exactly as the source API sends it, including duplicate snake\_case copies of the same values - use it only if you already have an integration reading those exact keys.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.facebook.com/mantraindianfolsom"
  ],
  "getBusinessHours": true,
  "cacheMaxAge": "",
  "includeGatedProfile": false,
  "includeEvents": false,
  "maxEvents": 0,
  "includePosts": false,
  "maxPosts": 0,
  "enrichPosts": false,
  "maxEnrichedItems": 10,
  "getComments": false,
  "getTranscript": false,
  "includePhotos": false,
  "maxPhotos": 0,
  "includeReels": false,
  "maxReels": 0,
  "outputStyle": "clean"
}
```

# Actor output Schema

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

One row per scraped item: the page, then its posts, photos, reels and events. Every row shares the same six leading columns (type, pageUrl, pageName, id, url, scrapedAt). For a CSV with no blank cells, use the per-type pages / posts / photos / reels datasets in the Storage tab - same rows, one shape each, not billed again.

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

End-of-run summary written to OUTPUT\_SUMMARY in the key-value store: totals, timings, addons enabled.

# 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 = {
    "startUrls": [
        "https://www.facebook.com/mantraindianfolsom"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("unseenuser/fb-pages").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 = { "startUrls": ["https://www.facebook.com/mantraindianfolsom"] }

# Run the Actor and wait for it to finish
run = client.actor("unseenuser/fb-pages").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 '{
  "startUrls": [
    "https://www.facebook.com/mantraindianfolsom"
  ]
}' |
apify call unseenuser/fb-pages --silent --output-dataset

```

## MCP server setup

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

```

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/1UKDMn5YUDnVx6nGM/builds/epWxVAL0xer8LEvJd/openapi.json
