Facebook API
Postproxy publishes feed posts, Reels, and Stories to a Facebook Page, and offers the fullest engagement support of any network: complete comment management (including likes) and Messenger direct messages with reactions and private replies.
Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.
Profiles and profile groups
Section titled “Profiles and profile groups”Every post targets one or more profiles. A profile is one connected account — for Facebook, a Facebook Page. Reference one in a request by its id (the prof_abc123 in the examples below) or by the platform name "facebook", which selects the group’s Facebook profile (a group holds at most one profile per platform). List what’s connected with GET /api/profiles.
Profiles live in profile groups — containers that organize the accounts for one brand, client, or project. List groups with GET /api/profile_groups, and connect a new Facebook profile with the Initialize Connection endpoint.
Example: get profiles and profile groups
List the profiles you can post to — GET /api/profiles:
curl -X GET "https://api.postproxy.dev/api/profiles" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "prof_abc123", "name": "My Company Page", "platform": "facebook", "status": "active", "profile_group_id": "grp_xyz789", "expires_at": null, "post_count": 84, "avatar_url": "https://cdn.postproxy.dev/uploads/avatar_prof_abc123.jpg" } ]}List your profile groups — GET /api/profile_groups:
curl -X GET "https://api.postproxy.dev/api/profile_groups" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "grp_xyz789", "name": "Main Brand", "profiles_count": 5 }, { "id": "grp_def456", "name": "Client Project", "profiles_count": 3 } ]}At a glance
Section titled “At a glance”| Platform ID | facebook |
| Formats | post (default), reel, story |
| Character limit | 63,206 (2,200 for Reels) |
| Media | Optional on feed posts; required for Reels and Stories |
| Placements | Pages — page_id (required) |
| Comments | List, reply, delete, hide/unhide, like/unlike |
| Direct messages | Yes — text, media, reactions, private replies, m.me referrals |
| Post chains | No |
Publishing
Section titled “Publishing”Formats
Section titled “Formats”| Format | Description |
|---|---|
post | Feed post (default) |
reel | Facebook Reel |
story | Facebook Story |
Every format requires a page_id — the Page to publish to. Fetch the IDs from placements.
Feed post
Section titled “Feed post”| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | No | "post" (default) |
first_comment | string | No | Comment added after publishing |
page_id | string | Yes | Page to publish to — fetch from placements |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Image | 10 MB | jpg, png, gif, webp | 10 | — |
| Video | 4 GB | mp4, mov | 1 | 1 s – 4 h |
- Text-only posts are allowed; media is optional.
- Images and video cannot be mixed.
- Minimum image dimensions: 200×200 px.
# Feed post with an image and a first commentcurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Exciting news! Check out our latest update." }, "profiles": ["prof_abc123"], "media": ["https://example.com/image.jpg"], "platforms": { "facebook": { "format": "post", "first_comment": "What do you think? Let us know!", "page_id": "123456789" } } }'| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | Yes | "reel" |
title | string | No | Title of the Reel |
page_id | string | Yes | Page to publish to — fetch from placements |
first_comment | string | No | Comment added after publishing |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Video | 300 MB | mp4, mov | 1 | 3 s – 90 s |
- A video is required.
# Reelcurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Behind the scenes 🎬" }, "profiles": ["prof_abc123"], "media": ["https://example.com/video.mp4"], "platforms": { "facebook": { "format": "reel", "title": "Launch BTS", "page_id": "123456789", "first_comment": "Link in bio!" } } }'| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | Yes | "story" |
page_id | string | Yes | Page to publish to — fetch from placements |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Image | 10 MB | jpg, png | 1 | — |
| Video | 4 GB | mp4, mov | 1 | 3 s – 60 s |
- Media is required; text captions are not supported.
- Minimum dimensions: 500×500 px.
# Story (single image)curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": {}, "profiles": ["prof_abc123"], "media": ["https://example.com/story.jpg"], "platforms": { "facebook": { "format": "story", "page_id": "123456789" } } }'Placements
Section titled “Placements”A Facebook profile can manage several Pages. List them with the placements endpoint — each placement’s id is the page_id you pass when creating a post.
page_id is required on every post — there is no default Page, even when the profile has only one. Pass the id of the Page you want to publish to.
# List the Pages (placements) for a Facebook profilecurl "https://api.postproxy.dev/api/profiles/prof_abc123/placements" \ -H "Authorization: Bearer YOUR_API_KEY"Comments
Section titled “Comments”Facebook has the most complete Comments API support. All comment writes are asynchronous and need the profile_id query parameter.
| Action | Supported |
|---|---|
| List / read | Yes |
| Reply | Yes |
| Delete | Yes |
| Hide / unhide | Yes |
| Like / unlike | Yes |
- Comment
attachmentscan carry photo, video, sticker, and share media. - Author metadata is available when Facebook returns it:
is_verified_user,is_user_follow_business,is_business_follow_user, andfollower_count.
# List comments on a postcurl "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"# Reply to a comment (omit parent_id to comment on the post itself)curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Appreciate the feedback!", "parent_id": "cmt_abc123" }'# Like / unlike a commentcurl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/like?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"
curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/unlike?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"# Hide / unhide a commentcurl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/hide?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"
curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/unhide?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"# Delete a commentcurl -X DELETE "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"Direct messages
Section titled “Direct messages”Facebook Messenger is supported through the Direct Messages API. Each send accepts either text or a single attachment.
| Capability | Supported |
|---|---|
| Send / receive text | Yes |
| Attachments | Yes — one per send |
| Reactions | Yes — named reactions map to emoji (love → ❤, like → 👍, …) |
| Edit outbound message | No |
| Delivery / read receipts | Yes |
| Private reply to a comment | Yes |
| m.me link referrals | Yes |
| Inbound delivery | Webhook |
- 24-hour window. Free-form messages are only allowed within 24 hours of the participant’s last message. Sending outside the window is not supported.
- Private replies DM a commenter directly, bypass the 24-hour window (up to 7 days), and are allowed once per comment.
- m.me link referrals. When a user enters the thread via
https://m.me/<page_username>?ref=..., the referral is stored on the chat (metadata.referral), areferral.receivedwebhook fires, and the 24-hour window opens — you can reply before the user sends a message. - Start a chat with the participant’s Page-scoped ID (PSID) as
participant_external_id.
# Create or find a chat by PSIDcurl -X POST "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "participant_external_id": "7000000000000000", "participant_name": "Jane Doe" }'# Send a text messagecurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Hi! How can we help?" }'# Send a single media attachmentcurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "media": ["https://example.com/receipt.pdf"] }'# React to a message (named reaction -> emoji)curl -X POST "https://api.postproxy.dev/api/messages/msg_abc123/react" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }'# Private reply to a commenter (bypasses the 24h window, once per comment)curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/private_reply?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Sent you a DM with the details!" }'Postproxy records periodic stat snapshots you can pull as a timeseries; field names pass through from Facebook unchanged.
Profile stats
Section titled “Profile stats”Page-level metrics, refreshed roughly every 23 hours and scoped per Page — pass the Page’s placement_id. See the Profile stats endpoint (GET /api/profiles/:id/stats).
Fields: fan_count, followers_count, plus daily Page insights (page_impressions, page_views_total, page_fan_adds, page_fan_removes)
# Fetch the stats timeseries for one Page (placement_id is the page_id)curl "https://api.postproxy.dev/api/profiles/prof_abc123/stats?placement_id=123456789" \ -H "Authorization: Bearer YOUR_API_KEY"Post stats
Section titled “Post stats”Per-post engagement, captured after publish via the Post stats endpoint (GET /api/posts/stats).
Fields: impressions, clicks, likes
# Fetch post statscurl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123&profiles=facebook" \ -H "Authorization: Bearer YOUR_API_KEY"Webhooks
Section titled “Webhooks”Subscribe with the Webhooks API. Create a subscription:
curl -X POST "https://api.postproxy.dev/api/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/postproxy", "events": ["platform_post.published", "comment.created", "message.received", "reaction.received"] }'Events relevant to Facebook:
| Event | When |
|---|---|
post.processed | A post is ready to publish |
platform_post.published | A post was published to the platform |
platform_post.failed | A post failed to publish (retries exhausted) |
platform_post.failed_waiting_for_retry | A publish attempt failed; will retry |
platform_post.insights | New analytics snapshot |
comment.created | A comment was synced on a Facebook post |
message.received / .sent | Inbound / outbound DM |
message.delivered / .read | Delivery and read receipts |
message.edited | An inbound message was edited |
reaction.received | A reaction was added or removed on a message |
referral.received | A participant entered a DM thread via an m.me link |
profile.connected / .disconnected | Connection state changed |
profile.stats | New profile stats snapshot (once per Page) |
media.failed | A media attachment failed to process |
Facebook does not report message deletions — message.deleted only fires for Instagram.
- Publishing targets a Facebook Page, not a personal profile.
page_idis required on every post; fetch it from placements.- Reels are video-only and capped at 90 seconds; Stories require 500×500 px media.