Skip to main content
Before you start. Facebook publishing happens against a Page (not a personal profile). The connect flow uses Facebook Login for Business, then discovers Pages via GET /me/accounts — one letmepost row per Page. If the user manages no Pages, the connect fails with facebook.pages.none.

Quick reference

Connect an account

POST /v1/accounts/connect/facebook. Standard Facebook Login for Business OAuth. After complete, the provider calls GET /me/accounts and creates one platform_accounts row per Page the user manages, each carrying its own Page Access Token (the non-expiring token used for publishing, distinct from the User Access Token). If the user manages no Pages: facebook.pages.none. Personal profiles cannot publish via the Graph API and are out of scope for v1.

Scopes

extended adds insights / engagement scopes (pages_read_user_content, pages_manage_engagement).

Token lifecycle

The User Access Token from the OAuth handshake is short-lived; the provider swaps it for a long-lived (~60-day) user token, then derives a Page Access Token per Page via /me/accounts. Page Access Tokens are non-expiring as long as the user token stays fresh; refresh runs on schedule. token.expiring fires before expiry on the user token.

Post types

Text post

text.json
Internally this routes to POST /{page-id}/feed with message.

Single image

single-image.json
Internally: POST /{page-id}/photos with caption.

Multi-image (up to 10)

multi-image.json
The publisher stages each photo as published=false via POST /{page-id}/photos, then creates the wall post with POST /{page-id}/feed carrying attached_media: [{ media_fbid }].

Single video

video.json
Routes to POST /{page-id}/videos with the media URL. Only one video per post; mixing image + video on the same post is rejected upfront.

Wisdom (platform-specific things that bite)

  • The Page Access Token is what publishes — not the User Access Token. The provider derives it at connect; revoking the user’s session in Facebook also kills the Page token even though the Page token itself has no documented expiry.
  • Multi-photo posts on Pages are a two-step dance: upload N photos unpublished, then attach the resulting media_fbids to one /feed call. The publisher hides this; if any single photo upload fails, the whole post fails (no half-posted state).
  • FB’s hard cap is 63,206 codeunits; we pre-check at 63,206 graphemes, which is strictly tighter — a payload that passes preflight never trips Meta’s server-side check.
  • The response id comes back as {page-numeric-id}_{post-numeric-id}; the publisher derives a clean https://www.facebook.com/{pageId}/posts/{postId} permalink for the response uri.
  • Link previews are auto-rendered by Facebook when a URL appears in message — no separate field is required; passing link is for explicit-share semantics only and is honored only on text-only posts.
  • Page-level rate limits scale with Page size and prior engagement; bursty publish patterns trigger platform_unavailable (mapped from Meta code: 4).

Common errors

What you can’t do (yet)

  • Posting to a personal profile (Meta’s Graph API doesn’t expose write access to user feeds).
  • First comment / threaded replies as the Page.
  • Story posts, Reels (Facebook Reels live behind a separate publishing surface not in v1).
  • Tagging users or co-authors.
  • Targeted post audience (Facebook geo/demographic targeting).
  • Reading comments, reactions, or insights (those scopes are extended and the read APIs aren’t wired in v1).

API reference