---
name: facebook-oauth-app
description: >-
  The Facebook Pages layer on top of the shared `meta-graph-app` skill — read
  that one first for the Meta developer account, app, redirect URIs, access
  levels, review regimes, App ID and Secret, and Graph API versioning. This
  file covers only what Facebook adds: the Page access token and the
  `/me/accounts` exchange that mints it, Page tasks as a second authorization
  axis, the `pages_*` permissions that need Tech Provider verification,
  Facebook Login for Business and `config_id`, per-Page webhook installs, and
  Page Insights metric deprecations. Use when asked to get Facebook OAuth
  credentials, connect customers' Facebook Pages, publish or read Page posts,
  reviews or Insights, or fix a Facebook error like `(#210)`, `(#283)`, an
  invalid metric, or a connection that stops after an hour. For Meta Ads use
  `meta-ads-oauth-app`; for Instagram use `instagram-oauth-app`.
---

# Facebook (Pages) OAuth2 App Registration

Get a working Facebook OAuth2 client — a Meta app with the Pages use case, redirect URIs, `pages_*` permissions and
an App ID and App Secret — for a platform that connects many customers' Facebook Pages on their behalf.

The registration mechanics are not here; they are the same for every Meta product and live in the base skill. Three
things are specific to Facebook Pages, and each one produces a failure that looks like something else.

**First, the token you finish OAuth with is not the token most calls need.** Facebook Login hands you a *user*
access token. Meta's own summary: "Most endpoints require Page access tokens." A user token has to be exchanged,
per Page, for one of those — the documented route is `/{user-id}/accounts`, and reading the `access_token` field on
a Page node works too — and a Page token minted from a short-lived user token is itself short-lived. A connector
that stores the OAuth token and calls Page endpoints with it works in the Graph API Explorer and fails in
production.

**Second, permissions are only half of the authorization check.** Facebook has a second, per-Page axis called
**tasks**. Meta: "When a User uses an app to interact with a Page, depending on the attempted action, we will first
check if the User has been approved for a task that permits that type of action." A customer can grant every
permission you asked for and still fail on one Page, because they hold `ANALYZE` on it and not `CREATE_CONTENT`.
Nothing in your dashboard or your token shows this.

**Third, the Pages use case adds a permission you did not ask for.** Selecting **Manage everything on your Page**
adds `business_management`, `pages_show_list` and `public_profile` by default, and required ones "can't be removed."
`business_management` is on the Access Verification list, so a read-only Page connector inherits the Tech Provider
gate on day one.

## Built on: `meta-graph-app`

**Read `meta-graph-app` first, in full, then come back here.** It owns:

- **The Meta developer account, the business portfolio, and the app** — the creation wizard, and the fact that
  neither the app type nor any use case you add can be undone afterwards. The use case in §3 is one of those.
- **Redirect-URI mechanics** — exact matching, HTTPS only, the dashboard's silently appended trailing slash, the
  requirement that authorize and token exchange send the same value, and this platform's callback list. §3 names
  only *which panel* on this product holds them.
- **Access levels and the four review regimes** — Standard vs Advanced Access and why only app-role users can
  connect without it, App Review submission contents, Business Verification, Access Verification / Tech Provider
  and the `(#100)` that only customers see, Ongoing Review and the annual Data Use Checkup. §5 adds only which
  `pages_*` strings appear on the Access Verification list.
- **The App ID and App Secret**, `appsecret_proof` and the "Require App Secret" switch, what rotating a secret
  breaks, and the rule that Meta issues no OAuth refresh tokens on any surface.
- **Graph API versioning and the two-year rule**, the rate-limit headers and buckets, and the generic `#1` / `#4` /
  `#10` / `#17` / `#100` / `#102` / `#190` / `#200`, `#32` / `#80001` and 80000-series error codes. Pages publishes
  no shorter version clock of its own the way the Marketing API does, so the base's Graph API rule is the one that
  governs every call here.

If you loaded only this file, you are missing all of the above, and nothing below substitutes for it — in
particular, creating the app, registering redirect URIs, getting Advanced Access, capturing the secret and reading
the generic error codes are base-skill steps.

## Inputs specific to Facebook Pages

The base skill's input table applies in full. Collect these on top of it, in the same batch.

| Input | Notes |
| --- | --- |
| **Which Page capabilities** the connector uses | Posts, reviews, insights, messaging — each maps to a different permission *and* a different task (§2, §4) |
| **Read-only or publishing?** | Decides whether `pages_manage_posts` and its review submission are in scope (§4) |
| **Login product**: classic Facebook Login or Facebook Login for Business | Changes the consent payload from `scope` to `config_id` and the panel the redirect URIs live in (§3) |
| **Token type**: user access token or Business Integration System User token | Decides whether re-authorization is a scheduled campaign (§6) |
| **A test Page you can perform every needed task on**, plus a second Page owned by someone with **no role on your app** | The only test that exercises both gates (§8) |
| **Will the connector consume Page webhooks?** | Needs an app-level subscription *and* a per-Page install (§7) |

## Quick Start

1. Read **Platform state** below — the permissions reference is currently unreachable and the Pages guides contain
   permission-string typos, so where you copy strings from matters.
2. Create the app per the base skill and add the **Manage everything on your Page** use case (§3).
3. Decide classic Facebook Login vs Facebook Login for Business, and register the redirect URIs in that product's
   settings panel (§3).
4. Prune the use case's default permissions to what the connector calls, and know each one's task requirement (§4).
5. Run the base skill's four review regimes; note which `pages_*` strings are also on the Access Verification
   list (§5).
6. Wire the user token → `/me/accounts` → Page token exchange, and decide the token term *before* launch (§6).
7. If you need webhooks, subscribe the Page object at app level **and** install the app on each Page (§7).
8. Verify with a Page whose owner has no role on your app, and with a person who holds only some tasks (§8).
9. Hand off with the token term, the task requirements and the review status recorded (§9).

## Platform state (verified 2026-09-20 — re-verify before trusting)

Read this alongside the base skill's Platform state; these are the Pages-specific facts.

- **Meta's permissions reference is broken today.** `developers.facebook.com/docs/permissions` returns **HTTP 500**,
  and the `/documentation/permissions` twin returns HTTP 200 with a "Page Not Found" body. Meta's own Pages pages
  link to it. Until it is back, take exact permission strings from the Facebook Login for Business supported-
  permissions table or from each endpoint's Graph API reference, not from a guide.
- **The Pages guides contain permission-string typos.** The Pages API Get Started page lists
  `pages_manage_read_engagement`; the Manage a Page and Posts guides list `pages_read_user_engagement`. Neither
  string appears in the Facebook Login for Business supported-permissions table, which lists `pages_read_engagement`
  and `pages_read_user_content`. Do not paste a permission out of a guide into an authorize URL.
- **The Pages use case force-adds permissions.** Customizing **Manage everything on your Page**: "The following
  permissions are required for this use case and added by default: `business_management`, `pages_show_list`,
  `public_profile`," and "If a permission or feature is required for a use case, it can't be removed."
- **Page Insights metrics have been deprecated in waves, for all API versions at once.** 14 March 2024,
  15 June 2025 and 15 November 2025. `page_fans` → `page_follows`, `page_impressions` → `page_media_view`,
  `page_impressions_unique` → `page_total_media_view_unique`, `post_impressions` → `post_media_view`. Meta: "The API
  will return an invalid metric error when calling any of these metrics." Pinning an old Graph version does **not**
  protect you — these are version-independent.
- **Meta's two Insights pages disagree by a year.** The Page Insights reference carries a banner reading "By
  June 15, **2026**, a number of the Page Insights metrics will be deprecated for all API versions," while the
  deprecated-metrics list dates that same wave "By June 15, **2025**." Trust the dated list, and say in your handoff
  which you followed.
- **Page Insights has hard data limits** that read as bugs: "Page Insights data is only available on Pages with 100
  or more likes," "Only the last two years of insights data is available," and "Only 90 days of insights can be
  viewed at one time when using the `since` and `until` parameters."
- **`pages_manage_metadata` and `pages_messaging` are *not* on the Access Verification list**, while
  `pages_show_list`, `pages_read_engagement`, `pages_read_user_content`, `pages_manage_posts`,
  `pages_manage_engagement`, `pages_manage_ads`, `pages_manage_cta`, `pages_manage_instant_articles`,
  `page_events`, `pages_utility_messaging` and `read_insights` all are (§5).
- **Every `pages_*` permission is available to both token types** under Facebook Login for Business — the supported-
  permissions table marks all of them ✓ for user access tokens *and* for Business Integration System User tokens.
- **Switching an existing app to Facebook Login for Business is reversible for 30 days**, and the switch is not
  free: "If you request permissions or features from business clients that Facebook Login for Business doesn't
  support, those permissions and features will be **revoked immediately** once you switch." Newly created Business
  type apps cannot switch back at all.

If the App Dashboard does not look like this, stop and report what you actually see rather than clicking on.

## 1. Reuse the existing app, or register a new one

The base skill's reuse-versus-new decision applies unchanged. One Pages-specific addition: because the Pages use
case cannot be removed once added (base §3) and it force-adds `business_management` (§ Platform state), an app
created "just to try Pages" carries a permission on the Access Verification list forever. If a ticket proposes
adding the Pages use case to an app that deliberately avoids Tech Provider review, that is a new-app decision, not
a config change. Say which path you are taking before you touch anything.

## 2. The Page, its roles, and its tasks

This is the concept with no equivalent on the other Meta surfaces, and the one that produces "it works for me."

Permissions say what *your app* may attempt. **Tasks** say what *this person* may do *on this Page*. Meta checks
the task first. The full set:

| Task | Permitted actions (Meta's wording, abridged) |
| --- | --- |
| `ADVERTISE` | Create ads; create unpublished Page posts; create ads for a connected Instagram account |
| `ANALYZE` | View Insights of the Page; view which Page admin published a post or comment |
| `CREATE_CONTENT` | Publish content as the Page on the Page |
| `MANAGE` | Assign and manage Page tasks |
| `MANAGE_LEADS` | View and manage leads |
| `MESSAGING` | Send messages as the Page |
| `MODERATE` | Respond to and delete comments on Page posts; for a connected Instagram account, publish, moderate, message, sync contact info and create ads |
| `VIEW_MONETIZATION_INSIGHTS` | View monetization insights |

"If a person is given Admin access to a Page in the UI, that person is able to perform all tasks on that Page" —
which is why testing with your own admin account never surfaces a task problem.

What each Page capability actually demands, from the endpoint references:

| Capability | Permissions | Page task the person must hold |
| --- | --- | --- |
| List the Pages a person manages | `pages_show_list` | — (the response's `tasks` array tells you what they hold) |
| Read a Page's feed | `pages_read_engagement` + `pages_read_user_content` | `CREATE_CONTENT`, `MANAGE` **or** `MODERATE` |
| Publish to a Page's feed | `pages_manage_posts` | `CREATE_CONTENT` |
| Read a Page's recommendations/ratings | `pages_read_user_content` | `CREATE_CONTENT`, `MANAGE` **or** `MODERATE` |
| Read Page Insights | `read_insights` + `pages_read_engagement` | `ANALYZE` |
| Read or write a Page's webhook subscription | `pages_manage_metadata` + `pages_show_list` | `CREATE_CONTENT`, `MANAGE` **or** `MODERATE` |

Two further traps here:

- **Pages the customer does not own or manage are a different product.** Meta, on reading a Page's feed: "If you do
  not own or manage the Page, you will need the Page Public Content Access Feature" — a Feature reviewed separately
  from every permission, and Meta adds "use a system user access token to avoid rate limiting issues."
- **You cannot fully enumerate who holds what.** `GET /{page-id}/roles` needs `MANAGE`, and "This edge only returns
  people who do not belong to a business. To find business users, query the Page Assigned Users edge." For a
  business-managed Page — i.e. most customers — the roles edge will look emptier than reality.

Fixing a missing task is the Page owner's job in Page settings. Hand it back; do not loop.

## 3. The use case, the login product, and the redirect URIs

**Add the use case.** In the creation wizard (base §3), pick **Manage everything on your Page**. Then **Dashboard →
Customize the Manage everything on your Page use case** to add and remove permissions. Per the base skill this use
case cannot be removed later, and its required permissions cannot be removed at all (§ Platform state).

**Pick the login product, deliberately.** Meta ships two and the Pages API overview is explicit about which it
prefers: "Facebook Login for Business is the preferred authentication and authorization solution for Tech Providers
and business app developers who need access to their business clients' assets," while classic Facebook Login "is
recommended for consumer authentication."

| | **Classic Facebook Login** | **Facebook Login for Business** |
| --- | --- | --- |
| App type | Any | **Business** type only |
| Consent payload | `scope` | `config_id` — a saved configuration; "`config_id` has replaced `scope` (which should not be used)" |
| Partial grants | A user can decline individual permissions | All-or-nothing across the configuration |
| Token types offered | User access token | User access token **or** Business Integration System User token (§6) |
| Rollback | — | Allowed within **30 days** of switching; unsupported permissions are revoked immediately on switch |

The configuration's own mechanics — creating one, the all-or-nothing grant, `response_type=code` for system-user
tokens — are the same as on the ads surface and are documented in `meta-ads-oauth-app` §1; read them there rather
than re-deriving them. What matters here is that the choice is visible to customers and, if you later roll back,
"Facebook Login does not support the `config_id` parameter and you need to replace the `config_id` parameter with
the `scope` parameter instead" — a client change, not a dashboard toggle.

**Redirect URIs** live in that product's settings panel: **App Dashboard → Facebook Login (for Business) →
Settings → Redirect URI**, with a **Check URI** button that validates the value before you save. Use it — the base
skill's exact-match and trailing-slash rules are precisely what it checks for you. The same panel holds the
**Deauthorize Callback URL** and the **Data Deletion Request URL**, both of which App Review asks about.

**Product facts about the connector, as of 2026-09-20.** Recorded from one day's configuration; confirm with the
connector's owner before relying on any of it.

- It uses the **classic Facebook Login flow with `scope`**, not a Facebook Login for Business `config_id`. It sends
  `client_id`, `redirect_uri`, `state` and `scope` to the authorize dialog, and exchanges the code against the
  Graph host's token endpoint with `client_id`, `redirect_uri`, `client_secret` and `code` carried as a **JSON POST
  body** — the client secret travels in the request body, not in a Basic auth header and not in the query string.
- Both its authorize URL and its token URL are **unversioned**. Per base §8 that means they resolve against
  whatever version the app dashboard's upgrade card is set to, and will drift when that changes.
- Its Page-object calls are pinned to **Graph v21.0**, hard-coded into the request path of every object it
  implements — so the pin is a multi-file change, not a config edit. Per the base's version table v21.0 is in the
  last months of its life; calendar the re-pin.
- It presents the access token as a **URL query parameter**, not an `Authorization: Bearer` header. Meta accepts
  both; the query-parameter form is the one that ends up in proxy and access logs.
- Its login/identity scopes are `email` and `public_profile`, and on connect it reads the authorizing person's name
  and email from the Graph `/me` node.
- **This platform ships shared default OAuth credentials for Facebook**, unlike its Instagram connector, which ships
  none. That means one shared Meta app's App Review, Advanced Access and Tech Provider status govern every customer
  who does not bring their own App ID and Secret — so the review work in §5 is not optional for it, and a single
  app-level restriction takes down every customer at once.
- Two sibling connectors exist on the same Graph host, and each needs **different things registered**, so do not
  assume one app covers all three: the Messenger connector needs the **Messenger product** added plus an app-level
  webhook callback URL and verify token configured once per Meta app, and it stores an **App Secret per connection**
  for signature checking; the Marketplace connector is not a Pages product at all — it runs on Commerce/Catalog
  endpoints with `catalog_management` and `business_management` and depends on approved Marketplace Partner status.
  The Pages connector needs none of those, and they need none of the `pages_*` permissions below.

## 4. Permissions

Request only what the connector calls; the base skill explains what an unused permission costs at review time.
These are the strings as the Facebook Login for Business supported-permissions table spells them.

| Permission | Grants | Add it when |
| --- | --- | --- |
| `pages_show_list` | Listing the Pages a person can perform a task on, with their tasks and Page tokens | Always — it is how you reach any Page at all (§6) |
| `pages_read_engagement` | Reading a Page's own content and metadata | Always, for any read |
| `pages_read_user_content` | Reading user-generated content on a Page: feed posts, comments, recommendations | Reading a feed or reviews |
| `pages_manage_posts` | Publishing and scheduling Page posts | Only if the connector publishes |
| `pages_manage_engagement` | Moderating comments and reactions as the Page | Only if the connector moderates |
| `pages_manage_metadata` | Page settings — and the webhook subscription edge | Only if the connector manages settings or webhooks (§7) |
| `read_insights` | Page and post Insights | Only if the connector reads metrics |
| `pages_messaging` | Messaging as the Page | A different product — see the Messenger surface, not this one |

Two Facebook-only properties of this family:

- **They are exempt from the 90-day data-access expiry.** Meta's data-access rule is that "The expiration period for
  data access is 90 days, based on when the user was last active," after which "your app can't access their data"
  until re-authorization — but every permission in the table above appears on Meta's list of permissions that "do
  not expire." Your Pages permissions therefore survive an inactive customer; the *token* still does not (§6). Note
  the separate rule that does still bite: "if your app does not use a permission for 90 days, that permission may
  expire," even one approved through App Review.
- **A grant can be partial by Page, not just by permission.** Debugging a token shows `granular_scopes` with a
  `target_ids` array — the specific Pages a scope was granted for. A customer who ticks two of their six Pages in
  the consent dialog produces a token that legitimately holds `pages_show_list` and legitimately cannot see four of
  their Pages. Read `granular_scopes` from the debug endpoint before treating a short Page list as a bug.

**As of 2026-09-20, this platform's Facebook connector requests** `pages_show_list` and `pages_read_engagement` as
its base Page-reading set, adds `pages_read_user_content` for Page posts and for reviews/recommendations, adds
`pages_manage_posts` for publishing, and adds `read_insights` for Page metrics. That set lines up with the endpoint
requirements in §2. It does **not** request `pages_manage_metadata`, which means it cannot manage Page webhook
subscriptions (§7). Confirm the current set with the connector's owner before you register anything.

## 5. What the base skill's gates mean here

All four review regimes in the base apply unchanged. Four Pages-specific consequences:

**Nothing is grantable to a stranger without App Review.** Meta, on the Pages API: "All permissions require App
Review before an app user can grant them to your app after it is live. For Business apps, which do not have app
modes, permissions must be approved for Advanced access before they can be granted to your app by an app user
without a role on the app itself or a role in a Business that has claimed it."

**Most of this family is on the Access Verification list**, so a multi-tenant Page connector needs Tech Provider
status for the claiming business on top of App Review and Business Verification, and will show the base skill's
`(#100)` symptom until it has it. Covered: `pages_show_list`, `pages_read_engagement`, `pages_read_user_content`,
`pages_manage_posts`, `pages_manage_engagement`, `pages_manage_ads`, `pages_manage_cta`,
`pages_manage_instant_articles`, `page_events`, `pages_utility_messaging`, `read_insights` — and
`business_management`, which the use case adds for you. Not covered: `pages_manage_metadata`, `pages_messaging`.

**The use case pre-commits you.** Because `business_management` is required by the Pages use case and is on the
list, there is no read-only Pages configuration that escapes Access Verification. Budget for it from the start
rather than discovering it when the first customer cannot connect.

**Features are a separate approval from permissions.** Meta: "Some endpoints require a Feature which must be
approved through the App Review process before your app can use them when your app goes live. Features allow you to
access public Page data without a permission or the ability to perform a task on the Page." Page Public Content
Access is the one a Pages connector most often discovers it needs (§2), and asking for it changes the review
conversation.

## 6. Tokens: the third rung the other Meta surfaces do not have

The user-token ladder itself — the short-lived token from the code exchange, the server-side exchange into a
~60-day long-lived token, and the fact that an expired token cannot be exchanged — is identical to the ads surface
and is documented in `meta-ads-oauth-app` §5. Read it there. What Pages adds is a **third rung**, and its term is
inherited rather than chosen:

| Rung | How you get it | Term |
| --- | --- | --- |
| User access token | The code exchange (base §7; `meta-ads-oauth-app` §5) | Short-lived, then long-lived if you exchange it |
| **Page access token from a short-lived user token** | `GET /{user-id}/accounts` with that token | Meta calls what comes back "a **short-lived** Page access token" |
| **Page access token from a long-lived user token** | `GET /{user-id}/accounts` with the long-lived token; "The person requesting the token must have a role on the Page" | Meta: long-lived Page access tokens "do not have an expiration date and only expire or are invalidated under certain conditions" |
| Business Integration System User token | A Facebook Login for Business configuration (§3) | Defaults to never expire |

The consequences that decide whether Page connections survive:

- **The Page token's term is decided upstream, not at `/me/accounts`.** The same call returns a token that dies in
  an hour or a token that does not expire, depending entirely on which user token you called it with. This is the
  single highest-leverage fact on this surface: doing the user-token exchange *before* enumerating Pages converts a
  connector from hourly breakage to indefinite operation.
- **Page tokens are per person, per Page, per app.** "Page access tokens are unique to each Page, admin, and app
  combination." Caching them is fine; caching them without tying the entry to all three, and without an expiry, is
  how a stale token outlives the user token that minted it.
- **The Business Integration System User token is the alternative that removes re-authorization**, and the FLB
  supported-permissions table marks every `pages_*` permission available to it. Its general mechanics are in
  `meta-ads-oauth-app` §5; the Pages-relevant prerequisites Meta states are that logins can only come from **web
  surfaces**, the customer must have or create a business portfolio, and **your app must be associated with a
  business portfolio you have full control of, separate from the client's**. To test the flow "the tester must have
  a role on the app and full control of the client business" — so this path cannot be smoke-tested with a stranger's
  Page the way §8 tests the user-token path.
- **Either token type can be revoked by the customer, in two different places.** Business Integration System User
  tokens: **Business Manager → Settings → Business Settings → Integrations → Connected apps**. User tokens:
  **Settings & privacy → Settings → Security and login → Business Integrations**. Neither revocation notifies you;
  you learn about it from a `(#190)`.

**Product facts about the connector, as of 2026-09-20.** Confirm with the connector's owner before relying on them.

- **It performs no short-lived → long-lived exchange at all**, and neither does any other connector on this
  platform: Meta's token-extension parameter appears nowhere in the product, so no Facebook, Messenger or
  Marketplace connection ever gets a long-lived user token. Given that Meta's code-grant user token is good for
  about one to two hours and Meta issues no refresh
  token on any surface (base §7), a Facebook connection is expected to stop working within about two hours of being
  created, and the customer must re-authorize to restore it. This is the single most consequential gap on this
  surface and should be raised with the connector's owner before any registration work is treated as finished.
- **The same gap compounds at the Page rung.** Because Page tokens are minted from that short-lived user token,
  every Page token the connector obtains is itself short-lived, and no long-lived Page token — the one Meta says has
  no expiration date — is ever created. Fixing the user-token exchange fixes both rungs at once; fixing neither
  means the connector never reaches the "never expires" state that this surface makes available.
- It resolves Page tokens on demand and **caches them in an in-process cache that evicts only on capacity, with no
  time-to-live**, so an entry can be served after the user token behind it has expired. It also keys the cache by
  the connection when it has one and by the *workspace* when it does not, so two connections in one workspace can
  read each other's cached Page token.
- It obtains the Page token by reading the `access_token` field on the Page node rather than from the accounts
  listing, and then **mutates the in-flight connection's stored credential in place** to swap the user token for the
  Page token — an approach its own notes describe as deliberate. It is worth confirming with the connector's owner
  that the mutated object cannot outlive the request or be persisted, because a Page token written back onto a
  connection record would be a silent, hard-to-diagnose credential substitution.

## 7. Webhooks: two subscriptions, not one

Page webhooks fail silently for a reason that is not a permission problem, and this is the Facebook-specific shape
of it: **there are two independent subscriptions and you need both.**

1. **App level.** Configure the callback URL and verify token once per Meta app, choose the **Page** object, and
   subscribe to the fields you want — `feed` for posts, reactions and shares; `messages` for Messenger.
2. **Page level.** "Webhook notifications will only be sent if your Page has installed your Webhooks configured-app,
   and if the Page has not disabled the App platform in its App Settings." You install it by posting to the Page's
   `subscribed_apps` edge **with that Page's access token**.

And the rule that turns a half-finished setup into silence rather than an error: "It is possible to subscribe to
more fields at the page level than the app level. However, **only fields with subscriptions at both the page and app
levels will get Webhooks**."

Requirements for the Page-level install: a Page access token from a person who can perform `CREATE_CONTENT`,
`MANAGE` or `MODERATE` on that Page, plus `pages_manage_metadata` and `pages_show_list`. Messaging fields need the
`MESSAGING` task and `pages_messaging` instead.

**Product facts about the connector, as of 2026-09-20.** The Facebook Pages connector implements **no webhook
handling and does not request `pages_manage_metadata`**, so Page events are not available through it today; reads
are poll-only. The separate Messenger connector does implement the two-level pattern — an app-level callback
configured by hand and a programmatic per-Page install — which is a working reference for what adding Page webhooks
here would involve, and a reminder that the app-level half is a dashboard task a human must do.

## 8. Capture the credentials, and verify

The App ID and App Secret, and where they live, are in the base skill. Unlike the Instagram surface there is **no
second, separately-displayed pair** here — if someone hands you an "Instagram App ID" for a Pages connector, they
are on the wrong product.

Record these Pages-specific values alongside the base skill's list: the use case you added and the permissions it
force-added; the login product and, if Facebook Login for Business, the configuration ID and token type; the task
each capability requires; whether Page Public Content Access is in scope; and the pinned Graph version.

Verification follows the base skill's round trip, with these layered on:

1. Run authorize → callback → code exchange, then **exchange the user token for a long-lived one and confirm the
   connector stored the new value** before doing anything else. Everything below inherits that decision (§6).
2. Call `/me/accounts` and read the `tasks` array that comes back for each Page. That array, not your permission
   list, is what predicts which calls will succeed.
3. Make one real read with a **Page** token — a feed read or an Insights read — at the pinned version.
4. Repeat against a Page owned by someone with **no role on your app**. Base §10 explains what the two failures at
   this step mean and which gate each one points at; this is the only test that reaches either.
5. Repeat once more as a person who holds only `ANALYZE` on the Page. Insights should work and publishing should
   not. If publishing succeeds, you tested with an admin account by mistake.

| Symptom | Cause |
| --- | --- |
| Works in the Graph API Explorer, fails from the connector | The Explorer's Page-token dropdown was used; the connector is still sending the user token (§6) |
| Every Page call dies about an hour or two after each connect | The short-lived user token was never exchanged, so the Page tokens minted from it are short-lived too (§6) |
| `(#283)` *That action requires the extended permission `pages_read_engagement` and/or `pages_read_user_content` and/or `pages_manage_ads` and/or `pages_manage_metadata`* | The named permission was not granted — Facebook's own hint at which one (§4) |
| `(#210)` *User not visible* | The call needs a Page access token and is being made with a user token, or the Page/user pair is not visible to this token (§6) |
| `(#190)` subcode `463` / `460` / `458` | Session expired / user logged out or changed password / user de-authorized the app — three different remediations, all requiring the subcode to tell apart |
| `(#459)` or `(#483)` | The person is checkpointed, or in consent-app blocking — customer-side, unfixable by you |
| `(#368)` | The action "has been deemed abusive or is otherwise disallowed" — publishing volume or content, not auth |
| One customer succeeds on some Pages and fails on others | Either a missing **task** on those Pages (§2), or a granular grant that covered only some Pages — check `granular_scopes.target_ids` (§4) |
| Publishing fails for a customer who can read fine | They hold `ANALYZE`/`MODERATE` but not `CREATE_CONTENT` on that Page (§2) |
| Reading a Page the customer does not manage fails | Needs the **Page Public Content Access** Feature, reviewed separately from permissions (§2, §5) |
| Insights returns an invalid-metric error | A deprecated Page Insights metric is in the request; one bad name fails the whole call, and pinning an old version does not help (§ Platform state) |
| `(#3001)` subcode `1504028` | No metric was specified on an Insights call |
| Insights returns nothing for a small Page | Page Insights needs 100 or more likes (§ Platform state) |
| Insights range silently truncated | More than 90 days requested at once with `since`/`until` (§ Platform state) |
| Webhooks never arrive, no error anywhere | The field is subscribed at only one of the two levels, or the Page never installed the app, or the Page disabled the App platform (§7) |
| The roles list looks emptier than the customer says | `/{page-id}/roles` omits people who belong to a business; query Page Assigned Users (§2) |
| A permission approved in review stops working after a quiet quarter | Unused permissions may expire after 90 days (§4) |

## 9. Hand off

Follow the base skill's handoff rules and add, to its closing list: the use case added and the permissions it
force-added; the login product and, if Facebook Login for Business, the configuration ID, token type and the date
the 30-day rollback window closes; the exact `pages_*` strings and the Page task each capability requires; whether
Page Public Content Access is needed; the token term the platform ends up with at both the user and Page rungs, and
the re-authorization cadence that implies; the pinned Graph version; and, if webhooks are in scope, which fields are
subscribed at app level and how Pages get installed.

## Stop and ask

The base skill's stop-and-ask list applies. Additionally, hand back to a human when: the connector calls Page
endpoints with a user access token and there is no plan to mint Page tokens, since that is a code change and not a
registration one; there is no short-lived → long-lived exchange, which makes every connection and every Page token
derived from it short-lived; the choice between user access tokens and Business Integration System User tokens has
not been made, since it decides whether re-authorization is a recurring campaign; adding the Pages use case would
force `business_management` onto an app whose owner does not want Tech Provider review; customers' Pages are
business-managed and you cannot confirm who holds which task; the connector needs to read Pages the customer does
not manage, which is a Feature review rather than a permission; or an Insights implementation hard-codes metric
names with no plan to track Meta's deprecation waves.

## References

Facebook Pages specific. The generic Meta developer-account, app-creation, review, credential, token-ladder and
Graph API references are in `meta-graph-app` and `meta-ads-oauth-app`. Every link below verified to return HTTP 200
on 2026-09-20.

- Pages API overview (tasks, Features, Page access tokens, permissions, the `/me/accounts` flow) — https://developers.facebook.com/docs/pages-api/overview
- Customize the "Manage everything on your Page" use case (forced permissions, redirect URI panel, Tech Provider) — https://developers.facebook.com/docs/pages-api/create-an-app
- Pages API get started (short-lived Page tokens, composite post IDs) — https://developers.facebook.com/docs/pages-api/getting-started
- Manage a Page (tasks and tokens from `/user_id/accounts`, `/page_id/roles`) — https://developers.facebook.com/docs/pages-api/manage-pages
- Pages API posts (publishing, scheduling, Page Public Content Access) — https://developers.facebook.com/docs/pages-api/posts
- `/{user-id}/accounts` reference (the `tasks` field, error codes `283`, `459`, `483`, `368`) — https://developers.facebook.com/docs/graph-api/reference/user/accounts/
- Page feed reference (read/publish tasks and permissions, Page Public Content Access) — https://developers.facebook.com/docs/graph-api/reference/page/feed/
- Page ratings reference (recommendations: `pages_read_user_content`, error `210`) — https://developers.facebook.com/docs/graph-api/reference/page/ratings/
- Page insights reference (`read_insights` + `ANALYZE`, the 100-like and 90-day limits, error `3001`/`1504028`) — https://developers.facebook.com/docs/graph-api/reference/page/insights/
- Page roles reference (business users are not returned) — https://developers.facebook.com/docs/graph-api/reference/page/roles/
- Page `subscribed_apps` reference (the both-levels rule, install permissions) — https://developers.facebook.com/docs/graph-api/reference/page/subscribed_apps/
- Webhooks for Pages (app-level fields, per-Page install, messaging requirements) — https://developers.facebook.com/docs/graph-api/webhooks/getting-started/webhooks-for-pages
- Authentication versus data access (the 90-day data-access expiry and the permissions exempt from it) — https://developers.facebook.com/docs/facebook-login/auth-vs-data
- Access token debugging and error handling (`granular_scopes`, subcodes `458` / `460` / `463`) — https://developers.facebook.com/docs/facebook-login/access-tokens/debugging-and-error-handling
- Deprecated Facebook Page Insights metrics (the 2024, 2025 waves and their replacements) — https://developers.facebook.com/docs/platforminsights/page/deprecated-metrics/
- Page Insights API updates, 15 August 2025 (the `impressions` and `page fans` deprecation notice) — https://developers.facebook.com/blog/post/2025/08/15/page-insights-api-updates/
