# Facebook Graph API: Get a Page's Posts

Get a Facebook Page's posts with the Graph API: /feed vs /posts vs /published_posts, fields, permissions, pagination, and the 100-post and 600-a-year limits.

Canonical page: https://www.tryadeli.com/blog/facebook-page-posts-api
Last updated: 2026-10-26

By Mika Reyes, Co-founder, Adeli. Published 2026-10-26.

## The short answer

To get a Facebook Page's posts with the Graph API, call GET /{page-id}/published_posts (the Page's own published posts) or /{page-id}/feed (which also includes visitor and tagged posts) with a Page access token. The app needs pages_read_engagement and pages_read_user_content. Ask for fields like message, created_time, and permalink_url, page with cursors, and expect at most 100 posts per request.

To get a Facebook Page's posts with the Graph API, send `GET /{page-id}/published_posts` (only the Page's own published posts) or `GET /{page-id}/feed` (everything on the Page) with a **Page access token**. The app needs **`pages_read_engagement`** and **`pages_read_user_content`**, and you choose what comes back with the `fields` parameter.

This post is about **reading** posts. To create them, see [how to post to a Facebook Page via the API](https://www.tryadeli.com/blog/post-to-facebook-via-api). All requests below use Graph API **v26.0**, the version in Meta's current reference.

## Which endpoint returns a Facebook Page's posts?

**Three Page edges return posts: `/feed`, `/posts`, and `/published_posts`.** They differ in whose posts they include and whether unpublished ones appear. Descriptions are from Meta's [Page reference](https://developers.facebook.com/docs/graph-api/reference/page/).

| Edge | What it returns | Use it when |
|---|---|---|
| **`/{page-id}/feed`** | Posts and links by the Page, posts by visitors, and public posts that tag the Page. Includes unpublished posts. | You want everything on the Page, including what visitors wrote |
| **`/{page-id}/posts`** | "This Page's own Posts, a derivative of the `/feed` edge" | You want the Page's own posts |
| **`/{page-id}/published_posts`** | "All published posts by this page" | You want only what the Page actually published |
| **`/{page-id}/visitor_posts`** | Public posts published by visitors on the Page | You're moderating visitor content |
| **`/{page-id}/tagged`** | Photos, videos, and posts in which the Page is tagged | You're tracking mentions |
| **`/{page-id}/scheduled_posts`** | Posts scheduled for a future date | You're showing a content calendar |

**For an analytics or reporting feature, `/published_posts` is usually the right call.** It skips drafts and other people's posts, so the list matches what the Page owner sees as "our posts." Reels have their own edge, `/{page-id}/video_reels`.

## What permissions do I need to read Page posts?

**Reading a Page's feed needs a Page access token from someone who can perform the `CREATE_CONTENT`, `MANAGE`, or `MODERATE` task on that Page, plus `pages_read_engagement` and `pages_read_user_content`.** That's from Meta's [Page feed reference](https://developers.facebook.com/docs/graph-api/reference/page/feed).

| Permission or feature | Why you need it |
|---|---|
| **`pages_show_list`** | List the Pages a person manages, to get each Page ID and token |
| **`pages_read_engagement`** | Read the Page's content and engagement data |
| **`pages_read_user_content`** | Read user-generated content on the Page, such as visitor posts and comments |
| **Page Public Content Access** | Read public posts on Pages your users don't manage. Requires App Review. |

Rules to build around:

- **Use a Page token, not a user token.** Meta says user information isn't included in responses unless the request uses a Page access token.
- **Missing permissions return error 283**, which names `pages_read_engagement` and `pages_read_user_content` among the permissions the call needs.
- **Live testing is limited to Pages you have a role on.** For customers' Pages, you need Advanced Access to these permissions, which means Meta App Review.

To get the Page token in the first place, see [how to get a Facebook Page access token](https://www.tryadeli.com/blog/facebook-page-access-token).

Access to other people's Pages has been gated since 2018. Mike Schroepfer, then Facebook's CTO, wrote in Meta's [April 4, 2018 announcement](https://about.fb.com/news/2018/04/restricting-data-access/) of the change:

> "Until today, any app could use the Pages API to read posts or comments from any Page."

**For a platform reading customers' own Pages, this means you build on Page tokens from each customer**, not on public access to arbitrary Pages.

## How do I get posts from a Facebook Page?

**Call `/{page-id}/published_posts` with a `fields` list and a `limit`, using the Page access token.** In Meta's [Pages API posts guide](https://developers.facebook.com/docs/pages-api/posts), a request without `fields` returns each post's `id`, `message`, and `created_time`, so name everything else you need.

```bash
curl -G "https://graph.facebook.com/v26.0/<PAGE_ID>/published_posts" \
  --data-urlencode "fields=id,message,created_time,permalink_url,full_picture,status_type,shares,reactions.summary(total_count),comments.summary(true)" \
  --data-urlencode "limit=25" \
  --data-urlencode "access_token=<PAGE_ACCESS_TOKEN>"
```

```json
{
  "data": [
    {
      "id": "1234567890_9876543210",
      "message": "Our fall menu is here.",
      "created_time": "2026-10-20T15:04:11+0000",
      "permalink_url": "https://www.facebook.com/...",
      "full_picture": "https://scontent.xx.fbcdn.net/...",
      "shares": { "count": 4 },
      "reactions": { "data": [], "summary": { "total_count": 52 } },
      "comments": { "data": [], "summary": { "total_count": 9 } }
    }
  ],
  "paging": {
    "cursors": { "before": "QVFI...", "after": "QVFI..." },
    "next": "https://graph.facebook.com/v26.0/<PAGE_ID>/published_posts?limit=25&after=QVFI..."
  }
}
```

The post ID is `{page-id}_{post-id}`. Pass it to the comments edge to read a post's comments, covered in the [Facebook comments API guide](https://www.tryadeli.com/blog/facebook-comments-api).

## Which fields can I request for a Page post?

**The fields most integrations need are `message`, `created_time`, `permalink_url`, `full_picture`, `attachments`, `status_type`, and `shares`.** The full list is in Meta's [Post reference](https://developers.facebook.com/docs/graph-api/reference/post).

| Field | What it holds |
|---|---|
| **`message`** | The text of the post |
| **`created_time`** | When the post was published |
| **`permalink_url`** | The post's permanent URL on facebook.com |
| **`full_picture`** | The post's image, resized so its longest side is at most 720 pixels |
| **`attachments`** | Media and link attachments (an edge you can expand) |
| **`status_type`** | The type of status update |
| **`shares`** | An object whose `count` is the number of shares |
| **`is_published`**, **`is_hidden`**, **`is_expired`** | Post state, useful when reading `/feed` |
| **`reactions.summary(total_count)`** | Total reactions on the post |
| **`comments.summary(true)`** | Comments, with `total_count` in `summary` |

**Some older fields are gone.** Since v3.3, `caption`, `description`, `link`, `name`, `object_id`, `source`, and `type` are deprecated on the feed, posts, and published_posts edges. Use `attachments` and `status_type` instead.

For reach and impressions per post, you need the Page Insights API, not this edge. See the [Facebook Page Insights API guide](https://www.tryadeli.com/blog/facebook-page-insights-api).

## How do I paginate Facebook Page posts?

**Follow the `paging.next` URL until it disappears.** The Page post edges use cursor-based pagination, per Meta's [paginated results guide](https://developers.facebook.com/docs/graph-api/results).

- **`limit` maxes out at 100.** Meta's feed reference says you can read at most 100 feed posts per request, and asking for more returns an error.
- **A short page isn't the end.** `limit` is a maximum, not a promise. A page can even come back empty while still holding a `next` link. Stop only when `next` is missing.
- **Don't store cursors.** Meta says a cursor becomes invalid if the item it points to is deleted.
- **Use `since` and `until` for date windows.** Meta's guide recommends setting both and keeping the range to about six months for consistent results.

```javascript
async function getAllPagePosts(pageId, token) {
  const posts = [];
  let url = `https://graph.facebook.com/v26.0/${pageId}/published_posts` +
    `?fields=id,message,created_time,permalink_url&limit=100&access_token=${token}`;

  while (url) {
    const res = await fetch(url);
    const body = await res.json();
    if (body.error) throw new Error(`${body.error.code}: ${body.error.message}`);
    posts.push(...body.data);
    url = body.paging?.next ?? null;
  }
  return posts;
}
```

Every page is a separate call, so a full-history pull counts against the Page's rate limit. The [Facebook Graph API rate limit guide](https://www.tryadeli.com/blog/facebook-graph-api-rate-limit) covers the budget and the error codes.

## What limits apply when reading Page posts?

**Meta caps how much Page history the API returns: about 600 ranked, published posts per year.** That line appears in both the [feed](https://developers.facebook.com/docs/graph-api/reference/page/feed) and [published_posts](https://developers.facebook.com/docs/graph-api/reference/page/published_posts/) references. Other limits from the same pages:

- **100 posts per request**, as above.
- **Expired posts can't be read.** Once a post expires, its content is gone from the Graph API.
- **Shared posts may be invisible** if the original post isn't visible to the token you're using.
- **Tagged posts from other Pages appear only if those Pages are authentic.**
- **Posts with message CTAs can't be read with another Page's token.**
- **Video posts need an admin.** Meta says the person making the request must be a Page admin to get a list of video posts, and the `source` field only appears for the Page's own videos.

**If your product promises "all posts", say what Meta allows.** For a Page that posts several times a day, 600 a year means the API won't return its full history.

## Is there a faster way to get Page posts across networks?

**Adeli returns a customer's Facebook Page posts from the same endpoint as their Instagram, TikTok, YouTube, and Bluesky posts.** `GET /api/v1/posts` lists the posts in one profile, newest first, with engagement such as likes and comments on each, including posts made outside Adeli. The [list posts reference](https://www.tryadeli.com/docs/api/posts/list-posts) has the request format.

[Adeli](https://www.tryadeli.com/product/facebook) holds the Meta developer app, carried Meta's review, and refreshes every connected Page's tokens, so you don't build the token and pagination code above for each network. The same key [publishes to Facebook Pages](https://www.tryadeli.com/social-media-posting-api) and lists their posts. For Page-level numbers, Adeli's [analytics API](https://www.tryadeli.com/social-media-analytics-api) returns a Page's audience, engagement across recent posts, and 28-day Page Insights. Facebook per-post insights aren't part of Adeli's v1 API.

It's a good fit for [vertical SaaS](https://www.tryadeli.com/use-cases/vertical-saas) products that show each customer their own content. Every network returns the same post shape, and billing is per profile (one of your customers) with every platform included. See [pricing](https://www.tryadeli.com/pricing).

## Frequently asked questions

### Can I get posts from a Facebook Page I don't manage?

Only with Meta's Page Public Content Access feature, which requires App Review. Without it, reading a Page's feed needs a token from someone who can perform the CREATE_CONTENT, MANAGE, or MODERATE task on that Page. Even with the feature, Meta returns public posts only.

### Why does the Graph API return fewer posts than the Page has?

Meta's reference says the feed and published_posts edges return about 600 ranked, published posts per year. Expired posts can't be read, and shared posts may be hidden if the original isn't visible to your token. Very active Pages will see gaps in older history.

### How do I get likes and comments counts for each Page post?

Use field expansion in the same request: add reactions.summary(total_count) and comments.summary(true) to the fields parameter, plus shares. Each post then carries its reaction and comment totals, so you don't need one call per post.

### Does /feed return unpublished posts?

Yes. Meta's Page feed reference says published and unpublished posts are both returned from /{page-id}/feed. Request the is_published field to filter them, or call /{page-id}/published_posts instead.

## Related Adeli pages

- [Facebook API for Developers](https://www.tryadeli.com/product/facebook.md): Publish, schedule, and read analytics for Facebook Pages through one API. Adeli owns the Facebook developer app, token refresh, and Meta review. Free to start.
- [Social Media Analytics API](https://www.tryadeli.com/social-media-analytics-api.md): Adeli's analytics API: Instagram, TikTok, Facebook Page, and YouTube insights endpoints, plus per-post engagement on every post an account has made.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Mika Reyes is the CEO behind Adeli and a tech and AI content creator. She was previously co-founder and CEO of Parallax, which was acquired by Phantom, and a product lead at LinkedIn. She is a Forbes 30 Under 30 honoree.
