Platforms
Publish feed posts, multi-image posts, link carousels, Stories and Reels to Facebook Pages, and run Messenger DMs, comments and Page reviews.
Connect a Facebook Page and you can publish text, photos, videos, link carousels, Stories and Reels, save drafts to Facebook's own Publishing Tools, and post to several Pages from one connection. The same account runs Messenger conversations, comments, Page reviews and comment-to-DM automations, and reads Page insights. The platform id is facebook.
#What you can do
| Capability | Supported | Where |
|---|---|---|
| Publish | Text, up to 10 images, one video or GIF, link carousels, Stories, Reels, text on a colour background | Create a post |
| Schedule | Yes | Scheduling |
| Edit after publishing | Text, or remove the post with Unpublish | Edit published posts |
| Analytics | Post metrics, Page insights, demographics, reactions by type, post earnings | Platform insights |
| DMs (Messenger) | Read and reply, attachments, quick replies, buttons, cards, reactions, message requests | Messages |
| Comments | List, reply, like, hide, delete, private reply | Comments |
| Reviews | List and reply to Page recommendations | Reviews |
| Automations | Comment to DM, welcome screen, persistent menu | Automations |
| Ads | Same connection can run Meta Ads and lead forms | Meta Ads |
#Connect
Facebook posts as a Page. Personal profiles cannot publish through the API, and the person connecting must be an admin or editor of the Page.
Start with GET /v1/connect/facebook and a profileId. After Facebook's consent screen the user picks which Page to connect. Pozy hosts that picker by default; to build it into your own UI, use headless mode with List Facebook pages and Select Facebook page. See Headless connect.
The consent screen also asks for ads permissions, so the same connection can drive Meta Ads and lead forms. Pass scopes to ask for fewer areas. A connection limited to analytics is read-only: it cannot change the Page, and the Page receives no webhooks, so inbox events stop.
Facebook ends sessions more often than most platforms (password changes, security checks, removed Page roles). Subscribe to account.disconnected and send the user a reconnect link when it fires.
#Several Pages on one connection
One connection can manage every Page the user administers. List them with List Facebook pages (add refresh=true to re-read from Facebook, at most once a minute). Then either:
- set
pageIdinplatformSpecificDataon each entry, repeating the sameaccountIdonce per Page, or - change the default Page with Update Facebook page so entries without
pageIdgo there.
"platforms": [
{ "platform": "facebook", "accountId": "6720c1a94f3b2e0018d4a7f4", "platformSpecificData": { "pageId": "108236514520117" } },
{ "platform": "facebook", "accountId": "6720c1a94f3b2e0018d4a7f4", "platformSpecificData": { "pageId": "214590882231054" } }
]#Post types
A plain request makes a feed post. Facebook is one of the few platforms that accepts text with no media at all.
curl -X POST https://api.pozy.ai/v1/posts \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Doors open at 9 this Saturday. First 50 visitors get a free tote.",
"mediaItems": [{ "type": "image", "url": "https://cdn.example.com/open-day.jpg" }],
"platforms": [{
"platform": "facebook",
"accountId": "6720c1a94f3b2e0018d4a7f4",
"platformSpecificData": { "firstComment": "Directions: https://example.com/visit" }
}],
"publishNow": true
}'const res = await fetch("https://api.pozy.ai/v1/posts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.POZY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
content: "Doors open at 9 this Saturday. First 50 visitors get a free tote.",
mediaItems: [{ type: "image", url: "https://cdn.example.com/open-day.jpg" }],
platforms: [{
platform: "facebook",
accountId: "6720c1a94f3b2e0018d4a7f4",
platformSpecificData: { firstComment: "Directions: https://example.com/visit" },
}],
publishNow: true,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.post.platforms[0].platformPostUrl);import os, requests
resp = requests.post(
"https://api.pozy.ai/v1/posts",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
json={
"content": "Doors open at 9 this Saturday. First 50 visitors get a free tote.",
"mediaItems": [{"type": "image", "url": "https://cdn.example.com/open-day.jpg"}],
"platforms": [{
"platform": "facebook",
"accountId": "6720c1a94f3b2e0018d4a7f4",
"platformSpecificData": {"firstComment": "Directions: https://example.com/visit"},
}],
"publishNow": True,
},
)
print(resp.json()["post"]["platforms"][0]["platformPostUrl"])| Post type | How to send it |
|---|---|
| Text | content only |
| Photo or multi-photo | Up to 10 images in mediaItems. Images and videos cannot be mixed. |
| Video or GIF | One item. Send a GIF as type: "video" and Facebook loops it. |
| Link carousel | Images plus facebookSettings.carouselCards |
| Text on a colour background | facebookSettings.textFormatPresetId on a text-only post |
| Story | contentType: "story" with one image or video |
| Reel | contentType: "reel" with one vertical video, optional title |
| Draft in Facebook | facebookSettings.draft: true |
#Link carousel
Each card is one image with its own link and headline. carouselCards must have one entry per image in mediaItems (2 to 10, images only). carouselLink sets the "See more" card at the end and defaults to the first card's link. Facebook shows about 35 characters of name and 30 of description; the API accepts up to 255 and truncates on display.
{
"content": "New arrivals this week",
"mediaItems": [
{ "type": "image", "url": "https://cdn.example.com/chair.jpg" },
{ "type": "image", "url": "https://cdn.example.com/lamp.jpg" }
],
"platforms": [{ "platform": "facebook", "accountId": "6720c1a94f3b2e0018d4a7f4" }],
"facebookSettings": {
"carouselLink": "https://shop.example.com/new",
"carouselCards": [
{ "link": "https://shop.example.com/chair", "name": "Oak lounge chair", "description": "Ships in 3 days" },
{ "link": "https://shop.example.com/lamp", "name": "Brass floor lamp", "description": "Back in stock" }
]
},
"publishNow": true
}facebookSettings can sit at the top level of the request (applies to every Facebook entry) or in an entry's platformSpecificData (wins for that entry).
#Stories and Reels
- Story (
contentType: "story"): media is required, the caption is not shown, it disappears after 24 hours, and interactive stickers are not available. - Reel (
contentType: "reel"): one 9:16 video of 3 to 60 seconds.contentis the caption andtitleis a separate Reel title.
#Drafts in Facebook Publishing Tools
facebookSettings.draft: true saves an unpublished draft in the Page's Publishing Tools, for teams who approve inside Facebook. It works for feed posts and Reels, not Stories. Facebook deletes drafts after about 30 days, and firstComment is skipped on drafts. For approvals inside Pozy, see Drafts and approvals.
#Platform fields
Schema: FacebookPlatformData, plus FacebookSettings.
| Field | Notes |
|---|---|
contentType |
story or reel. Leave out for feed posts. |
title |
Reel title. Reels only. |
firstComment |
Posted right after publishing. Feed posts and Reels. |
pageId |
Target Page when the connection manages several. |
geoRestriction.countries |
Up to 25 uppercase ISO country codes. Only people in those countries can see the post. Feed posts, videos and Reels. |
facebookSettings.draft |
Save as a Publishing Tools draft. |
facebookSettings.carouselCards, carouselLink |
Link carousel. Cannot be combined with contentType. |
facebookSettings.textFormatPresetId |
Facebook's numeric preset id for a colour background. Text-only feed posts; rejected with 400 when media, cards or contentType are present or content is empty. Facebook's own composer stops offering backgrounds around 130 characters, so longer text publishes with a warning. |
#Media requirements
Pozy converts WebP images to JPEG before upload. Media URLs must be public HTTPS with no login and no redirects; cloud-drive sharing links usually fail.
Images
| Feed | Story | |
|---|---|---|
| Formats | JPEG, PNG, GIF | JPEG, PNG |
| Max size | 4 MB | 4 MB |
| Count | Up to 10 | 1 |
| Recommended | 1200 x 630 | 1080 x 1920 |
Videos
| Feed video | Reel | Story | |
|---|---|---|---|
| Formats | MP4, MOV (H.264) | MP4, MOV | MP4, MOV |
| Max size | 4 GB | 4 GB | 4 GB |
| Duration | 1 second to 240 minutes | 3 to 60 seconds | 1 to 120 seconds |
| Shape | 1280 x 720 minimum | 9:16, required | 1080 x 1920 |
Custom video covers. Set thumbnail on the video item (an image URL up to 10 MB). It works for feed videos and Reels. It is best effort: if Facebook refuses it, the video publishes with Facebook's automatic cover and no error.
#Limits
| Limit | Value |
|---|---|
| Post text | 63,206 characters. About 480 show before "See more". |
| Images per post | 10 |
| Videos per post | 1 |
| Geo-restriction | 25 countries |
| Carousel cards | 2 to 10 |
The API cannot post to personal profiles or Groups, create Events, go live, add Story stickers, or target organic posts by age, gender or interest (country restriction is supported).
#Analytics
GET /v1/analytics?platform=facebook returns impressions, likes, comments, shares, clicks and views per post, plus engagementRate. likes is the total of all reactions.
| Endpoint | What you get |
|---|---|
| Page insights | Page-level media views, engagements, video metrics and followers over up to 89 days (default 30). followers_gained and followers_lost come from daily snapshots. |
| Page demographics | Follower breakdowns for the Page. |
| Post reactions | A count per reaction type for one post. |
| Post earnings | Lifetime monetization earnings for one post, read live. There is no date range, so never add up totals across dates. Pages without monetization return 0. |
| Visitor posts and tagged posts | Posts other people made on or about the Page. |
Image URLs in analytics responses are served from Pozy storage and do not expire.
#Inbox
Messenger DMs. Read conversations and reply with Send message: text, images, video, audio, files, up to 13 quick replies, up to 3 buttons (text 640 characters or less) and carousels of up to 10 cards (imageAspectRatio: "square" for 1:1 card images). React to messages, archive conversations, and list and accept message requests (folder=requests).
Messenger lets you message someone freely for 24 hours after their last message. After that, a reply typed by a person can still go out for up to 7 days with messagingType: "MESSAGE_TAG" and messageTag: "HUMAN_AGENT". Automated messages cannot use the tag, so workflows and broadcasts reject it. The other message tags were retired by Facebook in April 2026 and fail.
When another app (such as Facebook's Page Inbox) owns a thread, inbound messages arrive with metadata.standby: true, Pozy automations stay quiet and sends return 409 not_thread_owner. Hand the thread over with thread control.
On connect, Pozy imports the Page's existing Messenger history (up to 500 conversations, newest 500 messages each), in the background, already read, with no webhooks.
Welcome screen and menu. Set the greeting text (160 characters, per locale), the Get Started button, up to 4 ice breakers per locale and a persistent menu (3 top-level items, 5 nested). Facebook only shows the menu on Pages with a Get Started button. A tap sends a postback that arrives as message.received with metadata.postbackPayload; a payload of pozy:workflow:<workflowId> starts that workflow. See Conversation starters.
Comments. List, reply, like, hide, unhide and delete, and send one private reply per comment within 7 days. Comment-to-DM automations can like or hide the matched comment and send a product card.
Reviews. List the Page's recommendations and reply to them with the Reviews endpoints.
Page info. Read and update the Page's public details (about, description, website, phone, emails, hours) with Get and Update a Facebook Page's public info. Only the fields you send change.
#Errors you may see
| Message | Cause | Fix |
|---|---|---|
| Photos should be smaller than 4MB and saved as JPG or PNG | Image over 4 MB or unsupported format | Resize to under 4 MB as JPEG or PNG. |
| Missing or invalid image file | Facebook could not read the image | Open the URL in a private window; use JPEG or PNG. |
| Unable to fetch video file from URL | Facebook could not download the video | Use a direct public URL or upload the file. |
| Facebook tokens expired. Please reconnect. | The session ended | Reconnect the account. |
| Confirm your identity before you can publish as this Page | Facebook's security check on the Page | Open the Page in the Facebook app and complete the check. |
not_thread_owner (409) |
Another app owns the conversation | Take or request thread control. |
A rejected publishNow: true post returns 207 with post.status: "failed"; platforms[].errorMessage, errorCategory and errorSource explain why.
#Endpoints
#Webhook events
| Event | When it fires |
|---|---|
post.published |
Post published. |
post.failed |
Post failed. |
post.platform.published |
Post platform published. |
post.platform.failed |
Post platform failed. |
post.platform.deleted |
Post platform deleted. |
account.disconnected |
Account disconnected. |
message.received |
Message received. |
conversation.control_changed |
Conversation control changed. |
conversation.started |
Conversation started. |
message.sent |
Message sent. |
message.edited |
Message edited. |
message.deleted |
Message deleted. |
message.delivered |
Message delivered. |
message.read |
Message read. |
message.played |
Message played. |
message.failed |
Message delivery failed. |
reaction.received |
Reaction received. |
comment.received |
Comment received. |
review.new |
Review new. |
review.updated |
Review updated. |
review.deleted |
Review deleted. |
review.restored |
Review restored. |
lead.received |
Lead received. |