> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-fetch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Facebook

> Posts from public Facebook pages with their reactions, plus page details. scraper_type facebook and facebook_profile.

`facebook` collects the posts of public Facebook pages. One result is one row. For page details only, use
[`facebook_profile`](#page-details).

## Run it

```python Python theme={null}
import os

from gofetch import GoFetchClient

client = GoFetchClient(api_key=os.environ["GOFETCH_API_KEY"])

run = client.actor("facebook").call(run_input={
    "directUrls": ["https://www.facebook.com/metmuseum"],
    "limit": 20,
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if "postId" in row:
        print(row["time"], row["url"], row["likes"], row["comments"], row["shares"])
```

```bash cURL theme={null}
curl https://go-fetch.io/api/v1/jobs/create/ \
  -H "X-API-Key: $GOFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scraper_type": "facebook", "config": {"directUrls": ["https://www.facebook.com/metmuseum"], "limit": 20}}'
```

`facebook_posts` is another name for `facebook`.

## Inputs

| Field | Type | Default | What it does |
| - | - | - | - |
| `directUrls` | list of URLs | | Page links: `https://www.facebook.com/<page>`, `/profile.php?id=<id>`, `/people/<name>/<id>` or `/p/<name>-<id>`. A link to a page's post collects the page. `pageUrls`, `urls` and `startUrls` are accepted as other names. |
| `limit` | integer | `50` | Posts per page, from 0 to 1,000,000. `0` collects every post. |
| `onlyPostsNewerThan` | date (`YYYY-MM-DD`) | | Only posts published on or after this date (from 00:00 UTC). Not in the future. |
| `maxTotalChargeUsd` | number | | A spending cap, split across the pages as a per-page limit that never exceeds your `limit`. See [Billing](https://docs.go-fetch.io/billing.md#cap-a-job-with-maxtotalchargeusd). |

Groups, events, Watch, Marketplace and other links that are not pages are skipped; the job fails only if no link is
usable.

A date filter within the last 29 days makes the job a recent crawl, which is billed at its own rate; see
[Billing](https://docs.go-fetch.io/billing.md#rates). A recent crawl reads the recent part of each page's timeline, and reports in
`completeness` any stretch of dates it could not cover.

## Output

The job returns one `profile_info` row per page (the fields of [page details](#page-details)) and one row per post.
Both are billed as results. A real post row from a job for The Met:

```json theme={null}
[
  {
    "postId": "1553172153522100",
    "url": "https://www.facebook.com/metmuseum/posts/pfbid0QyLKm7CvMnijUF5WqimuPEqufW2fMvoh4asVzqon72vfwnsRV2EN7uEQnJachTYql",
    "facebookUrl": "https://www.facebook.com/metmuseum",
    "pageName": "The Metropolitan Museum of Art, New York | New York NY",
    "pageVerified": true,
    "text": "🎃 Lights out at The Met! 🌙 Join us for The Met Pajama Party, a Halloween-themed evening for the whole family. Wear your costume or your coziest pajamas and enjoy art activities, a Halloween-inspired menu, and live entertainment in the Temple of Dendur and The Charles Engelhard Court.\n\n📅 Wednesday, October 28, 5-7 PM\n📍 The Met Fifth Avenue\n\nGet your tickets and see event details: https://met.org/4B4xP8W",
    "time": "2026-10-14T15:41:04.000Z",
    "likes": 108,
    "comments": 2,
    "shares": 8,
    "isVideo": false,
    "viewsCount": 0,
    "media": [
      {
        "__typename": "Photo",
        "__isMedia": null,
        "id": "100064879894574",
        "image": {
          "uri": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1553172086855440"
        },
        "thumbnail": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1553172086855440"
      },
      {
        "__typename": "Photo",
        "__isMedia": null,
        "id": "1553172086855440",
        "image": {
          "uri": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1553172086855440"
        },
        "thumbnail": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1553172086855440"
      },
      {
        "__typename": "Photo",
        "__isMedia": null,
        "id": "1552215593617756",
        "image": {
          "uri": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1552215593617756"
        },
        "thumbnail": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1552215593617756"
      },
      {
        "__typename": "Photo",
        "__isMedia": null,
        "id": "1552215650284417",
        "image": {
          "uri": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1552215703617745"
        },
        "thumbnail": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1552215703617745"
      }
    ],
    "attachments": [],
    "error": null,
    "errorDescription": null
  }
]
```

| Field | Type | What it holds |
| - | - | - |
| `postId` | text | Facebook's id for the post. |
| `url` | URL | Link to the post; videos link to `https://www.facebook.com/reel/<id>/`. |
| `facebookUrl` | URL | The page link exactly as you sent it. Use it to match rows to your input. |
| `pageName`, `pageVerified` | text, true / false / null | The page and its verified badge. |
| `text` | text | The post's text; `""` when there is none. |
| `time` | date-time or null | When it was posted (ISO 8601, UTC). |
| `likes` | integer | All reactions together, not only likes; `0` when unknown. |
| `comments`, `shares` | integer | Comment and share counts. |
| `isVideo`, `viewsCount` | true / false, integer | A video post and its views; `0` when unknown. |
| `media` | list | Facebook's media objects for the post, passed through as Facebook describes them. |
| `attachments` | list | Always empty. |
| `error`, `errorDescription` | null | Always `null` on a post row. |

## What logged-out means here

**You get:** posts from public pages, with their text, reaction, comment and share counts, as a signed-out visitor
sees them.

**Not available:** pages behind a login wall or with no public timeline, groups, events, and anything only a
signed-in user can see. A page that returned no posts is listed in `scraper_metadata.targets_failed`:

| `reason` | Means | Worth retrying |
| - | - | - |
| `unavailable` | The page shows no public timeline to signed-out visitors, or asks to log in | No |
| `not_found` | The page does not exist or is not available | No |
| `blocked` | Facebook refused the request | No |
| `extraction_failed` | A temporary failure | Yes |

## Completeness

| Key | What it says |
| - | - |
| `profiles_scraped`, `profiles_failed` | Pages processed, and pages that ended with an error and no posts. A page that returned an error counts in both. |
| `completeness.complete` | `false` when any page was not collected over the whole range you asked for. |
| `completeness.pages_total`, `pages_incomplete`, `pages_failed`, `pages_rate_limited` | Pages by outcome. |
| `completeness.gaps` | Stretches of dates a page could not cover, each with `page`, `from` and `to`. |
| `completeness.reason` | Why the job is incomplete, when it is. |
| `targets_failed` | Pages that returned nothing: `target`, `reason`, `detail` (for reading, not parsing) and `retriable`. |

## Page details

`facebook_profile` returns one row per page with its details. It takes the same page links, and bills one result per
page that answered, including a page that answers it is not available. `limit` and date filters do not apply.

```python Python theme={null}
import os

from gofetch import GoFetchClient

client = GoFetchClient(api_key=os.environ["GOFETCH_API_KEY"])

run = client.actor("facebook_profile").call(run_input={
    "directUrls": ["https://www.facebook.com/NASA", "https://www.facebook.com/metmuseum"],
})

for page in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(page.get("pageName"), page.get("followers"), page.get("categories"))
```

```bash cURL theme={null}
curl https://go-fetch.io/api/v1/jobs/create/ \
  -H "X-API-Key: $GOFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scraper_type": "facebook_profile", "config": {"directUrls": ["https://www.facebook.com/NASA"]}}'
```

A real row for NASA's page (the links to stored images are masked here):

```json theme={null}
[
  {
    "facebookUrl": "https://www.facebook.com/NASA",
    "facebookId": "100044561550831",
    "pageName": "NASA - National Aeronautics and Space Administration",
    "title": "NASA - National Aeronautics and Space Administration",
    "likes": 28714724,
    "followers": 28714724,
    "verified": true,
    "categories": [
      "User",
      "Government organization"
    ],
    "info": [
      "NASA - National Aeronautics and Space Administration. 28,714,724 followers",
      "124,545 talking about this. Explore the universe and discover our home planet. \nThere's space for everybody. ✨"
    ],
    "profilePictureUrl": "<masked: https://go-fetch.io/api/v1/jobs/{id}/media/{name}?token=…>",
    "coverPhotoUrl": "<masked: https://go-fetch.io/api/v1/jobs/{id}/media/{name}?token=…>",
    "profilePhoto": "https://www.facebook.com/photo/?fbid=423033359192046&set=a.416661003162615",
    "type": "profile_info"
  }
]
```

| Field | Type | What it holds |
| - | - | - |
| `type` | text | `profile_info`. |
| `facebookUrl` | URL | The page link as you sent it. |
| `facebookId` | text or null | The page's id. |
| `pageName`, `title` | text | The page's name. |
| `followers` | integer | Followers; `0` when not shown. |
| `likes` | integer | Equal to `followers` when Facebook shows the count in the page's summary, which it labels "followers" or "likes"; otherwise `0`. |
| `verified` | true / false / null | The verified badge. |
| `categories` | list of text | The kind of page, then its category, such as `["User", "Government organization"]`. |
| `info` | list of text | The page's public description, split into parts. |
| `profilePictureUrl`, `coverPhotoUrl` | text or null | Absolute links to copies we stored, `https://go-fetch.io/api/v1/jobs/{id}/media/{name}?token=…`. No API key needed: `GET` or `HEAD` on the link returns a `302` to a download link for that method, valid for 10 minutes. The link itself is valid for 5 days, and each read of the results returns fresh ones. Without the token, the path still works with your `X-API-Key` header (counts toward the key's hourly rate limit); a bad or expired token is a `404`. The copies go when the job's results are deleted. Facebook's own links if storing failed. |
| `profilePhoto` | URL or null | Link to the profile photo's Facebook page. |

A page that answers it is not available returns `{"url", "error": "not_available", "errorDescription"}`. Pages that
do not answer at all are listed in `targets_failed`, not returned as rows. For this type, `completeness` reports no
pages and can be ignored.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.