Facebook API · post · schedule · DMs

The Facebook API built for developers

Publish photos, videos, Reels, Stories and links to your Facebook Page with one API call - no Page-token wrangling, no binary upload, no App Review maze. Then answer the comments it earns: the same API turns a Page comment into a private reply DM, and carries the conversation from there.

PhotosVideosReelsStoriesSchedulingComment-to-DM

✓ 5 minutes to first post ✓ 99.92% uptime ✓ Photos, videos, Reels & Stories ✓ DMs

Building an agent instead of an app? The same account works with our Facebook MCP server.

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Open house this weekend! 🏡",
    "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/house.jpg", "filename": "house.jpg" }]
  }'

Posts to your Facebook Page. Add facebook.publishAsReel or facebook.publishAsStory to publish a Reel or a Story instead, or a comment container to tag another Page.

Facebook's Graph API is powerful - and painful

Publishing through the Facebook Graph API means a Meta app, App Review for pages_manage_posts, a Page access token you must exchange for a long-lived one, and binary media uploads - with separate resumable flows for Reels and Stories. Page mentions only work inside comments, and answering a commenter in their inbox means the Messenger Send API, a second permission and a private-reply window. Outstand turns all of it into a single request. If you are doing the token exchange by hand, we wrote up how to get a Page access token that does not expire.

Meta app, App Review and Page-linked permissions
Connect once via OAuth - we manage the app and Page tokens, or bring your own
Short-lived Page tokens you must exchange and refresh
Automatic token refresh - you never see a 401
Reels and Stories each need their own three-phase resumable upload
Pass a media URL and one flag - we drive the right upload flow end to end
Page mentions only work in comments, and need a verified pageId
Give us { pageId, text }; we tag the Page in a comment for you
Comment-to-DM means polling the feed, then a Messenger private reply keyed to the comment id
A comment.received webhook gives you the comment id; one POST sends the private reply and opens the thread
DMs need pages_messaging, a webhook subscription and 24-hour window bookkeeping
On Managed Keys we request the messaging scopes by default, subscribe the webhooks, store every thread and check the window before you send
Opaque rate limits and 429s
We queue, throttle and retry - you never see a 429
New

Facebook comment-to-DM, in one POST

The newest capability on the whole Outstand surface. When someone comments on your Page, the comment.received webhook hands you the comment id - and POST /v1/conversations sends that commenter a private reply in Messenger, opening a real thread you can carry on through the same API key and the same connected Page. Taking a Facebook comment to DM is two HTTP calls, and those two calls are the whole of DM automation here: no flow builder to configure, no second vendor to connect.

Private replies

Answer a public comment in private. Pass the comment id; Messenger delivers the message to its author and the thread becomes a conversation.

Page comment webhooks

comment.received fires for every comment on your Page, with the account id and comment id the private reply needs. No feed polling.

The full thread

List conversations, page through messages, reply with text or media, schedule a reply for later and mark a thread read.

Windows checked for you

We check the private-reply and 24-hour windows when you send, including on scheduled replies, so an out-of-window message is rejected up front instead of failing silently later.

Comment in, DM out

bash
curl https://api.outstand.so/v1/conversations \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "social_account_id": "YOUR_FACEBOOK_ACCOUNT_ID",
    "content": "Thanks for asking! Here is the full price list 👉 https://example.com/pricing",
    "facebook": { "comment_id": "COMMENT_ID_FROM_WEBHOOK" }
  }'

What to know

A Page can only start a conversation with a private reply to a comment. There is no endpoint to cold-message a Facebook user.
One private reply per comment, within 7 days of the comment. After it, nothing more can be sent until the contact replies.
Once they do reply, the standard 24-hour messaging window applies to every follow-up.
The Page needs the pages_messaging scope, which Outstand requests by default on Managed Keys - there is nothing extra to ask for.
Quick replies and buttons are Instagram-only. A Facebook private reply carries text; media can follow once the contact has replied.

Everything Facebook Pages support, through one endpoint

Every content type and capability available on Facebook via Outstand today.

Page posts

Photos

Reels

Stories

Link posts

Direct messages

PublishingSchedulingAnalyticsMedia handlingCommentsDirect messages

Plus video uploads, tagging other Pages in comments, and comment-to-DM private replies - see the comment-to-DM guide. Stories carry a single image or video with no caption and expire after 24 hours. Posting to a personal profile (rather than a Page) is not supported by Meta’s API, and quick replies and buttons are an Instagram-only feature of Meta’s messaging stack - a Facebook private reply is text.

Copy, paste, ship

The same accounts array also fans out to Instagram, X, LinkedIn and more - one request, many platforms.

Post a video

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Highlights from the launch event 🎬",
    "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/event.mp4", "filename": "event.mp4" }]
  }'

Post + tag another Page in a comment

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"],
    "containers": [
      { "content": "Huge thanks to our partners 🙌" },
      { "content": "Shoutout to Outstand for the integration!" }
    ],
    "facebook": { "mentions": [{ "pageId": "123456789", "text": "Outstand" }] }
  }'

Post a Reel

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"],
    "containers": [
      {
        "content": "Behind the scenes of this week's build 🎥",
        "media": [{ "url": "https://media.outstand.so/reel.mp4", "filename": "reel.mp4" }]
      }
    ],
    "facebook": { "publishAsReel": true }
  }'

Post a Story

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"],
    "containers": [
      { "media": [{ "url": "https://media.outstand.so/story.jpg", "filename": "story.jpg" }] }
    ],
    "facebook": { "publishAsStory": true }
  }'

Share a link

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "New blog post is live → https://example.com/post", "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"] }'

Schedule a post (up to 30 days out)

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Weekend sale starts Saturday 🛍️", "accounts": ["YOUR_FACEBOOK_ACCOUNT_ID"], "scheduledAt": "2026-07-04T09:00:00Z" }'

Read analytics

bash
curl https://api.outstand.so/v1/posts/{id}/analytics \
  -H "Authorization: Bearer $OUTSTAND_API_KEY"
# → impressions, reach, reactions, comments, shares, clicks, video_views

Read & reply to comments

bash
# Read the comments on a published post
curl "https://api.outstand.so/v1/posts/{id}/replies?network=facebook" \
  -H "Authorization: Bearer $OUTSTAND_API_KEY"

# Reply to a comment (or comment on your own post)
curl https://api.outstand.so/v1/posts/{id}/replies \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Thanks - see you there! 🎉", "account_username": "yourbrand" }'

Comment-to-DM: answer a commenter with a private reply

bash
curl https://api.outstand.so/v1/conversations \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "social_account_id": "YOUR_FACEBOOK_ACCOUNT_ID",
    "content": "Thanks for asking! Here is the full price list 👉 https://example.com/pricing",
    "facebook": { "comment_id": "COMMENT_ID_FROM_WEBHOOK" }
  }'

Reply again once the contact answers

bash
# List the Page's DM threads, most recent first
curl "https://api.outstand.so/v1/conversations?social_account_id=YOUR_FACEBOOK_ACCOUNT_ID" \
  -H "Authorization: Bearer $OUTSTAND_API_KEY"

# Send a follow-up inside the 24-hour window
curl https://api.outstand.so/v1/conversations/{id}/messages \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Shipping is free over $50 - want me to send the link?" }'

Live in three steps

From signup to your first published Page post in about five minutes.

1

Connect Facebook

Your user authorizes via OAuth and selects a Page. We store and refresh the long-lived Page token. On Managed Keys we request the messaging scopes by default and subscribe the Page to comment and message webhooks too. Use our Managed Keys, or bring your own Meta app.

2

Call POST /v1/posts/

Send text and media with accounts: ["YOUR_FACEBOOK_ACCOUNT_ID"]. Add publishAsReel or publishAsStory to change the post type, a comment container to tag a Page, or scheduledAt to schedule.

3

We do the Graph API work

Media upload, Reels and Stories routing, comment tagging, private replies and retries - returned as a unified response with the published post ID.

More than a Facebook wrapper

One integration that grows with everything you ship next.

One API, 12 platforms

One request publishes to Facebook and 11 more networks. Same JSON shape everywhere - learn one API, ship them all.

Managed Keys or BYOK

Skip Meta App Review - use our Managed Keys, or bring your own Meta app for white-label OAuth on your customers’ screens.

Built for scale

Intelligent rate limiting, automatic token refresh, webhook events and media processing.

Honest pricing

$19/mo includes 3,000 posts, then from $0.007/post. No seats, no annual lock-in.

What you can build

Same endpoints, same data shapes - pick what you ship.

Social schedulers

Let your users queue and auto-publish Facebook content from your app.

AI agents

Give Claude or GPT a tool to post to Facebook. MCP server included.

Analytics dashboards

Pull Facebook reach and engagement alongside every other platform.

Agencies & white-label

Run Facebook posting for clients under your own brand and app.

Facebook API FAQ

The questions developers ask before they build.

Does Facebook have an official API?

Yes - the Facebook Graph API lets approved apps publish to Pages, upload photos and videos, post Reels and read insights. Outstand is a managed layer on top of it, so you skip the App Review and token management.

Can I post to a personal profile or only a Page?

Only Pages. Meta’s Graph API does not allow third-party apps to publish to personal profiles - publishing is limited to Pages you manage. Outstand publishes to your connected Page.

Can I post Facebook Reels via API?

Yes. Send a video to POST /v1/posts/ with accounts: ["YOUR_FACEBOOK_ACCOUNT_ID"] and facebook: { "publishAsReel": true }, and Outstand drives Meta's three-phase Reels upload for you. Without the flag the video publishes as a regular Page video.

Can I post Facebook Stories via API?

Yes. Send one image or video with facebook: { "publishAsStory": true }. Meta's Story endpoints take no caption, no comments and no mentions, so those are rejected rather than silently dropped - send a Story as its own request. Stories expire after 24 hours, after which analytics return null.

Can I tag another Page on Facebook via API?

Yes, in a comment. Meta only supports @[pageId] mentions in comments, not the main post body, so pass facebook.mentions and include a comment container whose text contains the anchor. Outstand verifies the pageId before publishing.

Can I schedule Facebook posts via the API?

Yes. Add a scheduledAt ISO-8601 timestamp (up to 30 days ahead) and Outstand publishes the post automatically - no cron or queue on your side.

Can I read and reply to Facebook comments via the API?

Yes. Read the comments on a published post with GET /v1/posts/{id}/replies?network=facebook and post a reply with POST /v1/posts/{id}/replies.

Can I delete a Facebook post via the API?

Yes. Facebook supports deleting posts via the API, and Outstand exposes it through DELETE /v1/posts/{id}/remote.

Can I set up Facebook comment to DM via the API?

Yes. Subscribe to the comment.received webhook, which fires for every comment on your connected Page and carries accountId and commentId. Pass those to POST /v1/conversations as social_account_id and facebook.comment_id with the text you want to send, and Messenger delivers it to the comment author as a private reply - which starts a conversation you can continue through the same API.

Does Outstand do Facebook DM automation?

It gives you the API to build it. DM automation on Facebook comes down to two things Outstand exposes directly: the comment.received and message.received webhooks that tell you something happened, and the Conversations API that answers - a private reply to start the thread, then messages inside the 24-hour window. There is no visual flow builder; you write the logic in your own product, against seven REST endpoints.

What is a Facebook private reply?

It is the one way Meta lets a Page message someone first: a Messenger message addressed to a public comment rather than to a user. A comment can receive one private reply, and only within 7 days of the comment. Until the contact replies to it, no further message can be sent - POST /v1/conversations/{id}/messages is rejected with a 422. Once they reply, the normal 24-hour messaging window applies.

Can I read and reply to Facebook Page DMs via the API?

Yes. The Outstand Conversations API lists the Page's threads with GET /v1/conversations, reads one with GET /v1/conversations/{id}/messages and replies with POST /v1/conversations/{id}/messages - text, media or both, sent now or scheduled for later. The Page needs the pages_messaging scope, and replies must land inside Facebook's 24-hour window from the contact's last message.

Can I send the first DM to a Facebook user via the API?

Only as a private reply to a comment they left on your Page. There is no endpoint to cold-message an arbitrary Facebook user, through Outstand or directly through Meta - Messenger requires the person to have contacted the Page, or to have commented on it.

How do I know when someone comments on my Facebook Page?

Subscribe to the comment.received webhook. Outstand receives the comment from Meta and forwards it to your endpoint with the account id, the comment id and the author, which is everything POST /v1/conversations needs to send a private reply. Comments your own Page leaves are filtered out, so an auto-reply cannot loop on itself.

Do Facebook DMs support quick replies or buttons?

Not on Facebook. Quick replies and buttons are available on Instagram private replies, where you can attach up to 13 quick replies or up to 3 buttons. A Facebook private reply carries text; Outstand rejects Instagram-only options on a Facebook conversation rather than dropping them silently.

Ship Facebook posting and comment-to-DM today

Grab an API key and publish your first Page post in the next five minutes - then answer its comments with a private reply DM from the same API. 3,000 posts included, then $0.007/post - dropping to $0.005 at volume.