Facebook API for page posting and scheduling
Publish text and photo posts to every Facebook Page you manage from one endpoint. PostMCP resolves page access tokens and calls Graph API v26.0 for you.
- Endpoint
- POST /api/tools/create_post
- Platform value
- "facebook"
- Auth
- x-api-key or Bearer token
- Upstream
- Graph API v26.0
What the Facebook API gives you
Facebook publishing goes through the Graph API, and the friction is rarely the POST itself — it is page discovery, exchanging a user token for a per-page access token, keeping those tokens alive, and remembering that text posts go to /feed while photo posts go to /photos with a different body shape.
The PostMCP Facebook API handles all of it. Connecting an account syncs every page you administer; a single create_post call then fans the same copy out to each connected page, choosing the /feed or /photos endpoint based on whether you attached a mediaUrl.
Page feed posts
Text updates published to /{page-id}/feed as the page, not as a personal profile.
Native photo posts
Set mediaUrl and the engine switches to /{page-id}/photos, sending the image URL and caption so it lands as a real photo post.
Multi-page sync
Every page returned by pages_show_list is connected at once, each with its own page access token.
Per-page targeting
Use targetAccounts with a profileId to publish to one specific page instead of the whole set.
Scheduled publication
Queue posts by date and time and edit or cancel them any time before the slot.
Cross-network broadcast
Combine facebook with instagram, threads and the rest in one platforms array.
Common uses
- Broadcast one announcement to a dozen regional pages in a single call.
- Publish a product photo with caption straight from your CMS webhook.
- Let an AI agent draft page updates and queue them for a human to approve.
- Mirror Instagram content to the matching Facebook page automatically.
Post to Facebook in three steps
Connect the account once, grab an API key, then send a single request. The same body works from a shell, a server, or an AI agent.
- 1
Connect your Facebook account
Open the dashboard, choose Facebook and complete the hosted connect flow. Credentials are encrypted into the user vault and never returned to your client.
- 2
Create an API key
Generate a key from the dashboard. Send it as
x-api-key, as anAuthorization: Bearerheader, or as anapikeyquery parameter on the MCP transport. - 3
Send your first post
POST to
/api/tools/create_postwithplatforms: ["facebook"]. SetpublishImmediatelyto broadcast now, or supplyscheduleDateandscheduleTimeto queue it.
curl -X POST "https://api.postmcpai.com/api/tools/create_post" \
-H "Content-Type: application/json" \
-H "x-api-key: $POSTMCPAI_API_KEY" \
-d '{"content":"Shipping something new today. Built with PostMCP AI.","platforms":["facebook"],"publishImmediately":true}'{
"success": true,
"message": "Post created and queued successfully",
"post": {
"id": "66a50c89e4b019a2b72f",
"content": "Shipping something new today. Built with PostMCP AI.",
"platforms": [
"facebook"
],
"status": "published"
}
}Facebook API endpoints
Every endpoint is a POST against the base URL https://api.postmcpai.com. The same seven operations cover all connected networks — set the platform value to "facebook" to target Facebook.
| Operation | Endpoint | What it does |
|---|---|---|
| preflight_post | POST/api/tools/preflight_post | Dry-run copy against limits, targets and credits before publishing. |
| create_post | POST/api/tools/create_post | Schedule a post or broadcast it immediately. |
| publish_post_now | POST/api/tools/publish_post_now | Force a queued post out ahead of its slot, or retry the profiles that failed. |
| list_posts | POST/api/tools/list_posts | Read the queue — scheduled, published, draft and failed — with counts. |
| get_post | POST/api/tools/get_post | Read one post, with per-profile delivery state and live URLs. |
| get_post_analytics | POST/api/tools/get_post_analytics | Read how a post did: views, likes, comments and shares per profile. |
| get_profile_analytics | POST/api/tools/get_profile_analytics | Read a profile’s followers, post count and views from its network. |
| update_post | POST/api/tools/update_post | Edit copy, targets, schedule or status before publication. |
| reschedule_post | POST/api/tools/reschedule_post | Move a post to another slot, keeping its copy and targets. |
| reset_stuck_post | POST/api/tools/reset_stuck_post | Release a post left stuck mid-publish so it can be retried. |
| delete_post | POST/api/tools/delete_post | Remove a scheduled or draft post from the queue. |
| get_connected_accounts | POST/api/tools/get_connected_accounts | List connected profiles, handles and page IDs per platform. |
| get_account_health | POST/api/tools/get_account_health | Find connections whose token expired or is about to. |
| generate_image | POST/api/tools/generate_image | Generate a post image and get back a hosted URL for mediaUrl. |
| list_workspaces | POST/api/tools/list_workspaces | List the workspaces on this key, with the id to scope other calls to. |
| get_user_info | POST/api/tools/get_user_info | Read plan tier and credit balance. |
create_post parameters
| Field | Type | Required | Description |
|---|---|---|---|
| content | string | Yes | Text body of the post. Truncation rules are enforced by the destination network, not by PostMCP. |
| targetAccounts | array[object] | Yes | The profiles that receive the post. Each entry takes platform and profileId (from get_connected_accounts). Only the profiles listed here are posted to. |
| platforms | array[string] | Optional | Shorthand for whole networks — linkedin, twitter, facebook, instagram, threads, bluesky, youtube. Each one expands to every connected profile on it, so prefer targetAccounts unless you mean that fan-out. Optional when targetAccounts is given. |
| publishImmediately | boolean | Optional | When true the post is broadcast on receipt. Defaults to false, which queues it. |
| scheduleDate | string | Optional | Publication date as YYYY-MM-DD. Required when publishImmediately is false. |
| scheduleTime | string | Optional | Publication time as HH:MM on a 24-hour clock. Required when publishImmediately is false. |
| timezone | string | Optional | IANA zone the schedule above is written in, e.g. Asia/Kolkata. Omit it and the wall-clock slot resolves as UTC, which is rarely what "10am" meant. |
| mediaUrl | string | Optional | Publicly reachable image or video URL. PostMCP fetches it and re-uploads it in the format the network expects. Required, and must be a video, when the post targets YouTube. |
| workspaceId | string | Optional | Workspace to post from, taken from list_workspaces. Omitted, the call resolves to the default workspace on the key. |
Facebook OAuth and API keys
Two layers of auth sit under every request: the Facebook credential you grant once during connect, and the PostMCP API key your code sends on each call.
Open the connect URL
Send the user to /connect/facebook. PostMCP builds a facebook.com/v26.0/dialog/oauth URL with a signed state JWT.
Re-request consent
auth_type=rerequest is set so previously declined page permissions are asked for again rather than silently skipped.
Page token exchange
The callback code becomes a user token, which is exchanged for a page access token per administered page.
Encrypted storage
Each page token is encrypted into the user vault and used automatically when you publish.
Scopes requested from Facebook
| Scope | Why it is needed |
|---|---|
| pages_show_list | Lists the pages the user administers so they can be connected. |
| pages_manage_posts | Creates, edits and deletes posts on those pages. |
Sending your API key
x-api-key: pmcp_sec_…Authorization: Bearer pmcp_sec_…/mcp?apikey=pmcp_sec_…How PostMCP publishes to Facebook
One request from you becomes this sequence server-side. Knowing the shape helps when you are debugging a failed broadcast.
- 1
Load the page token
The connected account record supplies the page
profileIdand its decrypted page access token. - 2
Pick the endpoint
mediaUrlpresent routes to/photos; absent routes to/feed. The body shape changes with it. - 3
Post to Graph
Facebook fetches the image from your URL directly — no binary upload happens from PostMCP for photo posts.
- 4
Check for a Graph error
Graph returns 200 with an
errorobject on some failures, so the engine inspects the body as well as the status. - 5
Persist the post ID
The returned ID is stored against the post so you can trace what landed where.
Upstream Facebook calls
| Method | Endpoint | Purpose |
|---|---|---|
| POST | https://graph.facebook.com/v26.0/{page-id}/feed | Creates a text post with `message` and the page access token. |
| POST | https://graph.facebook.com/v26.0/{page-id}/photos | Creates a photo post from a public image `url` plus a `caption`. |
Direct Facebook API vs PostMCP
| Aspect | Calling Facebook directly | With PostMCP |
|---|---|---|
| Page discovery | Call /me/accounts and store each token | Every administered page synced on connect |
| Text vs photo | Different endpoint and body per post type | Set `mediaUrl` or leave it off |
| Multi-photo posts | Upload each photo unpublished, then attach the ids to a feed story | One `mediaUrls` array, up to 10 photos |
| Token lifecycle | Track expiry and re-exchange per page | Encrypted vault, refreshed for you |
| Scheduling | Publish-time scheduling with caveats | Uniform queue across all seven networks |
| Error surface | Errors hide inside 200 responses | Normalised per-platform status on the post |
Facebook limits and supported media
These ceilings are set by Facebook, not by PostMCP. Your content field is forwarded unchanged, so the network enforces them rather than silently truncating.
Common Facebook API errors
Failures are recorded per platform on the post record, so a multi-network broadcast that partially succeeds tells you exactly which leg failed and why.
| Code | Message | Likely cause | Fix |
|---|---|---|---|
| 190 | Error validating access token | The page token expired, or the user changed their Facebook password. | Reconnect Facebook to re-issue page tokens. |
| 200 | Requires pages_manage_posts permission | The user declined the posting permission during consent. | Reconnect — the flow sets `auth_type=rerequest` so the prompt reappears. |
| 100 | Invalid parameter — could not fetch image | Facebook could not download the mediaUrl, usually because it is private or behind auth. | Serve the image from a public URL with no redirect chain. |
| 368 | Temporarily blocked for policies violations | The page tripped Facebook's automated posting-behaviour checks. | Reduce posting frequency and vary the copy between posts. |
Post to Facebook from an AI agent
The same seven operations are exposed as MCP tools. Point Claude Desktop, Cursor, or any MCP client at the server and your agent can publish to Facebook directly.
{
"mcpServers": {
"postmcpai": {
"command": "npx",
"args": ["-y", "@postmcpai/server"],
"env": {
"POSTMCPAI_API_KEY": "pmcp_sec_YOUR_SECRET_KEY",
"POSTMCPAI_API_URL": "https://api.postmcpai.com"
}
}
}
}Prompt the agent directly
With the server connected, natural language is enough — the agent picks the tool and fills the arguments:
“Draft a Facebook post about today’s release and schedule it for 9:30am tomorrow.”
Facebook API questions
How do I post to a Facebook Page with the Graph API?
Directly you would POST to https://graph.facebook.com/v26.0/{page-id}/feed with a page access token. Through PostMCP you POST to /api/tools/create_post with targetAccounts: [{ platform: "facebook", profileId: "…" }] and the engine resolves the token for that page.
Can I post to multiple Facebook Pages at once?
Yes. Connecting an account syncs every page returned by pages_show_list. List each page you want in targetAccounts, or pass platforms: ["facebook"] to deliberately fan out to all of them.
How do I publish a photo instead of a text post?
Add a public mediaUrl. The engine switches from /feed to /photos and sends the image URL with your text as the caption, so it renders as a native photo post.
Which permissions does Facebook posting need?
pages_show_list to enumerate the pages you administer, and pages_manage_posts to publish on them. The connect URL sets auth_type=rerequest so declined permissions are asked for again.
Can I post to a personal Facebook profile?
No. Meta removed programmatic publishing to personal profiles from the Graph API. Page publishing is the supported path, and it is what PostMCP implements.
Which Graph API version does PostMCP use?
v26.0 for both the OAuth dialog and the feed and photos publishing calls.
Other social media APIs
One authenticated POST publishes to a LinkedIn profile or company page. PostMCP owns the OAuth dance, the image upload handshake and the versioned LinkedIn REST calls underneath.
Read the referenceSend one request and PostMCP handles Twitter API v2 for you — PKCE OAuth, the three-step chunked media upload, refresh tokens and the final tweet call.
Read the referenceInstagram publishing is a two-phase asynchronous flow. PostMCP creates the media container, polls it to FINISHED and publishes it — you send a caption and a media URL.
Read the referenceThreads processes every post asynchronously, even plain text. PostMCP creates the container, polls it to FINISHED and publishes — one call from your side.
Read the referenceBluesky is not OAuth — it is a session against an AT Protocol server. PostMCP refreshes that session, uploads image blobs and writes the feed record for you.
Read the referenceYouTube is the one network here that will not take a URL. It wants the video bytes over a resumable session — PostMCP fetches, uploads and publishes them for you.
Read the referenceStart posting to Facebook today
Connect the account, take an API key and send your first request in under five minutes — from a shell, your backend, or an AI agent.
