# FB Page Advanced — WhatsApp Link Eligibility (`ratulislam/fb-page-advanced`) Actor

Checks Facebook cookies for Page WhatsApp-link eligibility, ban reason, page name and linked number via the business inbox + GraphQL.

- **URL**: https://apify.com/ratulislam/fb-page-advanced.md
- **Developed by:** [Ratul Islam](https://apify.com/ratulislam) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## fb-page-advanced — WhatsApp Link Eligibility (Advanced Check)

### What does fb-page-advanced do?

**fb-page-advanced** takes raw Facebook login cookies and tells you, per cookie, whether its **Facebook Page is eligible for a WhatsApp link** — plus the **ban reason**, the **page name**, and any **already-linked WhatsApp number**. It ports the proven `/fb/page-advanced` endpoint and `pageAdvanced` background sweep from the SheetSubmit backend, using plain `fetch` plus regex extraction (no browser, no crawler). It does not post, message, or change anything on the account: it only reads the business inbox page and one read-only GraphQL query.

### Why use fb-page-advanced?

- **Batch screening:** check up to **25 cookies per run** and get one uniform result item per cookie.
- **Stable error codes:** every item uses the shared workspace envelope, so `error.code` (`invalid_cookie`, `session_challenge`, `invalid_page`, `rate_limited`, …) is safe to branch on while `error.message` text may change.
- **Negative answers are data:** a Page that exists but is not eligible still returns `ok: true` with `eligible: false` and a `banReason` — only "could not perform the check" becomes `error`.
- **Platform-native:** Apify Proxy on every request (Facebook blocks bare datacenter IPs), scheduling, API access, dataset exports, and run monitoring come free with the platform.

#### How the check works

1. `GET https://business.facebook.com/latest/inbox/wec` with a desktop Chrome user agent and the cookie.
2. Extract the Page ID from the final URL plus nine HTML patterns (`pageID`, `page_id`, `localScopeID`, `assetID`, `selectedPageId`, `ownerId`, `business_id`, `actorID`), falling back to the cookie's `c_user`; extract the `fb_dtsg` token from `DTSGInitData`.
3. `POST https://business.facebook.com/api/graphql/` with `x-fb-friendly-name: WhatsAppOnboardingUnifiedInboxSurfaceQuery` (`doc_id 27161030553583658`) and read `data.xfb_is_page_eligible_for_wa_link` (`is_eligible`, `ban_reason`, `page_whatsapp_number`) plus `data.page.name`.

### What data can fb-page-advanced extract?

| Field | Type | Description |
|---|---|---|
| `eligible` | boolean | null | `true` when the Page can take a WhatsApp link; `false` for a found-but-ineligible Page; `null` when the check failed |
| `pageName` | string | null | Page name from GraphQL, e.g. `"Example Fashion House"` |
| `linkedNumber` | string | null | WhatsApp number already linked to the Page, if any |
| `banReason` | string | null | Why the Page is ineligible (e.g. `"Not eligible for this page"`) |
| `error` | object | null | `{ code, message, retryable }` — `null` on success |
| `input` | string | null | Echo of the cookie's `c_user`, so you can join results back to your rows |

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. The key-value store record `OUTPUT` holds the run summary (`total`, `succeeded`, `failed`, `errorsByCode`, timing).

### How to check WhatsApp eligibility in bulk

1. Log in to Facebook in your browser and copy the full **Cookie** request header of a logged-in session (it must contain `c_user` and `xs`).
2. Open the Actor, paste one cookie per line into **Facebook cookies** (max 25), keep **Proxy configuration** on Apify Proxy.
3. Click **Start**, then open the **Dataset** tab for per-cookie items and the **Key-value store → OUTPUT** record for totals.
4. Branch on the result: `ok: true` → use `eligible`/`banReason`; `ok: false` → read `error.code` — `invalid_cookie` means grab a fresh cookie, `rate_limited`/`upstream_error`/`service_unavailable` mean retry later.

#### Can I run it from code?

Yes — via the API tab: start a run with `{ "cookies": ["<cookie-header>"], "proxyConfiguration": { "useApifyProxy": true } }`, poll to `SUCCEEDED`, then fetch the default dataset items.

### How much does it cost to check eligibility?

Each cookie costs two lightweight HTTP requests (one page load, one GraphQL call) — a 25-cookie run finishes in well under a minute of compute. Proxy traffic is the only metered extra; keep batches full (25 cookies) to amortize the run overhead.

### Input

See the input tab for full configuration options. `cookies` is required (1–25 raw cookie headers). Each entry must be a non-empty string of at most 50 000 characters. `proxyConfiguration` defaults to Apify Proxy and is required in practice — runs without a proxy are blocked by Facebook.

```json
{
    "cookies": ["c_user=61592912563278; xs=27%3Aabcdef%3A2%3A1786607116%3A-1%3A-1; dpr=2;"],
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

Success — Page found and eligible:

```json
{
    "ok": true,
    "actor": "fb-page-advanced",
    "input": "61592912563278",
    "eligible": true,
    "pageName": "Example Fashion House",
    "linkedNumber": null,
    "banReason": null,
    "friendCount": null,
    "error": null,
    "checkedAt": "2026-10-13T12:00:00.000Z",
    "runId": "abc123XYZ"
}
```

Found but not eligible (still `ok: true`):

```json
{
    "ok": true,
    "actor": "fb-page-advanced",
    "input": "61592912563278",
    "eligible": false,
    "pageName": null,
    "linkedNumber": null,
    "banReason": "Not eligible for this page",
    "friendCount": null,
    "error": null,
    "checkedAt": "2026-10-13T12:00:00.000Z",
    "runId": "abc123XYZ"
}
```

Failure — dead cookie (branch on `error.code`):

```json
{
    "ok": false,
    "actor": "fb-page-advanced",
    "input": "61592912563278",
    "eligible": null,
    "pageName": null,
    "linkedNumber": null,
    "banReason": null,
    "friendCount": null,
    "error": {
        "code": "invalid_cookie",
        "message": "Cookie was rejected or expired (Facebook showed a login page). Get a fresh logged-in cookie and retry.",
        "retryable": false
    },
    "checkedAt": "2026-10-13T12:00:00.000Z",
    "runId": "abc123XYZ"
}
```

#### Tips

- **Fresh cookies win:** `xs` tokens expire. If many items return `invalid_cookie` at once, re-export the headers and re-run.
- **Respect `retryable`:** back off and retry `rate_limited` / `upstream_error` / `service_unavailable`; do not retry `invalid_cookie`, `session_challenge`, or `invalid_page` without new input.
- **`invalid_page` means no Page:** the cookie logs in fine but owns no usable Page for the advanced surface — check it with the simple Actor instead.
- **Keep cookies secret:** never paste them into issues or logs; the Actor only echoes `c_user`, never cookie values.

### FAQ, disclaimers, and support

#### Is this an official Facebook / WhatsApp API?

No. It reads the same internal surfaces the Business Suite web app uses. Facebook may change them; `upstream_error` items signal exactly that.

#### Do you extract private user data?

Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers. Only check cookies for accounts you own or are authorized to manage.

#### Something failed — where do I get help?

See the Issues tab for feedback, and the API tab for programmatic access. Include the `error.code` (never the cookie) when reporting a problem.

# Actor input Schema

## `cookies` (type: `array`):

Raw Facebook Cookie-header strings (the full 'Cookie' request header of a logged-in session, including c_user and xs). One dataset item is produced per cookie. Max 25 per run.

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

Apify Proxy settings. Facebook blocks bare datacenter IPs, so every run must go through the proxy.

## Actor input object example

```json
{
  "cookies": [
    "c_user=123456789012345; xs=PASTE_FRESH_COOKIE_HERE; dpr=2;"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset with one envelope item per cookie

## `keyValueStore` (type: `string`):

OUTPUT record with totals and error counts

# 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 = {
    "cookies": [
        "c_user=123456789012345; xs=PASTE_FRESH_COOKIE_HERE; dpr=2;"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ratulislam/fb-page-advanced").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 = { "cookies": ["c_user=123456789012345; xs=PASTE_FRESH_COOKIE_HERE; dpr=2;"] }

# Run the Actor and wait for it to finish
run = client.actor("ratulislam/fb-page-advanced").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 '{
  "cookies": [
    "c_user=123456789012345; xs=PASTE_FRESH_COOKIE_HERE; dpr=2;"
  ]
}' |
apify call ratulislam/fb-page-advanced --silent --output-dataset

```

## MCP server setup

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

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/tucrVXKnbj9fKCrCO/builds/bsyCEqoT7tlvLbZUy/openapi.json
