Skip to main content

1. Overview

Facebook publishing uses the Meta Graph API directly against your connected Facebook Page. SocialAPI selects the correct Graph API endpoint based on the content type: text and link posts go to /{page-id}/feed, photo posts to /{page-id}/photos, and video posts to /{page-id}/videos.
FieldValue
Platform slugfacebook
Auth typeOAuth 2.0 (Meta)
APIMeta Graph API (Facebook Pages)
Create postYes
Update postYes (message text only)
Delete postYes
ScheduleYes (deferred publish via schedule_at)
First commentNo
CarouselNo

2. Supported media

Content typeHow to triggerNotes
Text onlyNo media_ids; no link in platform_dataPublishes a plain text status update
Link previewNo media_ids; include link in platform_data.facebookFacebook generates an Open Graph preview card
Single photoOne image URL in media_idsRoutes to /{page-id}/photos; platform_data is ignored
Single videoOne video URL in media_ids (.mp4, .mov, .avi, .mkv, .webm)Routes to /{page-id}/videos
Route selection is automatic. If media_ids is non-empty, SocialAPI inspects the first entry’s file extension to choose between the photo and video endpoints. If media_ids is empty, the feed endpoint is used and any keys in platform_data.facebook are forwarded. Caption limit: Follows Facebook’s standard post message limit (approximately 63,206 characters, though shorter posts perform better). Multi-media and carousels: Not supported. Only the first entry in media_ids is used.

3. Create post

Use POST /v1/posts with account_ids targeting a Facebook Page account. The text field becomes the post message.
curl -X POST https://api.social-api.ai/v1/posts \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_ids": ["acc_01HZ9X3Q4R5M6N7P8V2K0W1J"],
    "text": "Exciting news from our team. Read the full announcement on our website.",
    "platform_data": {
      "facebook": {
        "link": "https://example.com/announcement"
      }
    }
  }'

Platform data fields

Pass these inside platform_data.facebook. These fields apply to text and link posts only. Photo and video posts ignore platform_data entirely.
FieldTypeDescription
linkstringURL to attach as a link preview card. Facebook generates the Open Graph preview automatically.
picturestringImage URL to use as the link preview thumbnail. Overrides the Open Graph image from the linked URL.
SocialAPI forwards any additional keys in platform_data.facebook directly to the underlying platform API. These fields are not validated by SocialAPI and may break if the platform changes its API. See Facebook Pages API reference for the full list of supported parameters.

Photo post

Provide a single image URL in media_ids. The platform_data block is ignored for photo posts.
curl -X POST https://api.social-api.ai/v1/posts \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_ids": ["acc_01HZ9X3Q4R5M6N7P8V2K0W1J"],
    "text": "Our new product is here.",
    "media_ids": ["https://cdn.example.com/product.jpg"]
  }'

Video post

Provide a single video URL in media_ids. SocialAPI detects the video extension and routes to /{page-id}/videos.
curl -X POST https://api.social-api.ai/v1/posts \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_ids": ["acc_01HZ9X3Q4R5M6N7P8V2K0W1J"],
    "text": "Watch our latest brand film.",
    "media_ids": ["https://cdn.example.com/brand-film.mp4"]
  }'

Scheduling

Set schedule_at to an ISO 8601 timestamp (UTC) to defer publishing:
{
  "account_ids": ["acc_01HZ9X3Q4R5M6N7P8V2K0W1J"],
  "text": "Scheduled announcement.",
  "schedule_at": "2026-04-15T10:00:00Z"
}

4. Update post

Facebook supports editing the message text of a post that was created by the same app. Media cannot be changed after publish. Use PATCH /v1/posts/:pid with a text field:
curl -X PATCH https://api.social-api.ai/v1/posts/post_01HZ9X3Q4R5M6N7P8V2K0W1J \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Updated message text."
  }'
SocialAPI calls POST /{page-id}_{post-id} with the new message value. Only the text field is forwarded; all other patch fields are ignored for Facebook targets. Limitation: Only posts created by your app can be updated. Posts imported from the platform (via sync) may return a 400 from Facebook if the app does not own them.

5. Delete post

curl -X DELETE https://api.social-api.ai/v1/posts/post_01HZ9X3Q4R5M6N7P8V2K0W1J \
  -H "Authorization: Bearer $SOCAPI_KEY"
Or, to delete only the Facebook target of a cross-platform post:
curl -X DELETE "https://api.social-api.ai/v1/posts/post_01HZ9X3Q4R5M6N7P8V2K0W1J?platform=facebook" \
  -H "Authorization: Bearer $SOCAPI_KEY"
Deletion calls DELETE /{page-id}_{post-id} on the Graph API. If the post no longer exists on Facebook, the call returns success.

6. Retrieve posts

Use GET /v1/posts to list posts. Filter by platform or account:
curl "https://api.social-api.ai/v1/posts?platform=facebook&account_ids=acc_01HZ9X3Q4R5M6N7P8V2K0W1J&limit=20" \
  -H "Authorization: Bearer $SOCAPI_KEY"
Each post includes a targets array with per-platform status and engagement metrics:
{
  "id": "post_01HZ9X3Q4R5M6N7P8V2K0W1J",
  "text": "Exciting news from our team.",
  "status": "published",
  "targets": [
    {
      "platform": "facebook",
      "platform_post_id": "123456789012345_987654321098765",
      "status": "published",
      "permalink": "https://www.facebook.com/permalink/123456789012345",
      "metrics": {
        "likes": 15,
        "comments": 3,
        "shares": 7,
        "saves": 0,
        "extra": null,
        "metrics_synced_at": "2026-04-10T12:00:00Z"
      }
    }
  ]
}
Metrics notes:
  • likes and comments are synced periodically from the Graph API.
  • shares is populated for Facebook posts. Facebook is the only platform where SocialAPI reports a non-zero share count.
  • saves is not exposed by the Facebook Pages API and is always 0.
  • metrics_synced_at reflects when SocialAPI last refreshed the metrics from Facebook.

7. Quirks, errors, and recovery

Page token lifetime

Facebook Page tokens derived from long-lived user tokens do not expire. Once an account is connected, the token remains valid indefinitely unless the user revokes app access or changes their password. Reconnection is only needed if you see an auth error.

Multi-page OAuth

When a user completes the Facebook OAuth flow, SocialAPI connects all Facebook Pages that the user manages in a single OAuth exchange. Each page becomes a separate connected account entry. Users do not need to repeat the OAuth flow for additional pages.

platform_data ignored for media posts

The platform_data.facebook block is only forwarded to the Graph API for text and link posts (the /{page-id}/feed endpoint). For photo and video posts, the block is silently ignored. Pass all image or video content exclusively via media_ids and text.

Only first media_ids entry is used

Facebook does not support multi-photo albums or carousels via this API path. If you pass more than one URL in media_ids, only the first is used. The others are silently dropped.

Reviews deprecated

The Facebook Graph API v22.0 removed the reviews edge. GET /v1/inbox/reviews for a Facebook account returns 501 Not Implemented. This is a platform-level deprecation and cannot be worked around.

DM 24-hour window

Facebook Messenger only allows pages to send outbound DMs within a 24-hour window after the user last messaged the page. Attempting to send outside this window returns a platform error. SocialAPI surfaces this as an api_error.

Error shapes

When a publish fails, the post target’s error field contains a structured error:
{
  "code": "platform.facebook.api_error",
  "message": "Invalid OAuth access token.",
  "category": "platform",
  "caused_by": "platform"
}
Error codeCategoryCaused byMeaning
platform.facebook.api_errorplatformplatformThe Graph API rejected the request. Check message for details.
platform.facebook.rate_limitrate_limitplatformFacebook rate limit hit. Retry after a delay.
platform.facebook.authauthplatformAccess token invalid or revoked. Reconnect the account.

Recovery

  • Rate limit: Retry the post via POST /v1/posts/:pid/retry after waiting. SocialAPI applies exponential backoff for scheduled retries.
  • Auth error: Disconnect and reconnect the Facebook account through the OAuth flow to obtain a fresh token.
  • API error: Check the message field for the Graph API error description. Common causes include missing page permissions, a post that no longer exists, or an invalid media URL.

8. Full worked example

The following example publishes a link preview post with a custom thumbnail, then checks the metrics after publish. Step 1: Publish the post
curl -X POST https://api.social-api.ai/v1/posts \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_ids": ["acc_01HZ9X3Q4R5M6N7P8V2K0W1J"],
    "text": "We just launched our spring collection. Shop now and get 20% off your first order.",
    "platform_data": {
      "facebook": {
        "link": "https://example.com/spring-collection",
        "picture": "https://cdn.example.com/spring-og.jpg"
      }
    }
  }'
Response:
{
  "id": "post_01HZ9X3Q4R5M6N7P8V2K0W1J",
  "text": "We just launched our spring collection. Shop now and get 20% off your first order.",
  "status": "publishing",
  "targets": [
    {
      "platform": "facebook",
      "status": "publishing"
    }
  ],
  "created_at": "2026-04-10T09:00:00Z"
}
Step 2: Check status
curl "https://api.social-api.ai/v1/posts/post_01HZ9X3Q4R5M6N7P8V2K0W1J" \
  -H "Authorization: Bearer $SOCAPI_KEY"
Response once published:
{
  "id": "post_01HZ9X3Q4R5M6N7P8V2K0W1J",
  "text": "We just launched our spring collection. Shop now and get 20% off your first order.",
  "status": "published",
  "targets": [
    {
      "platform": "facebook",
      "platform_post_id": "123456789012345_987654321098765",
      "status": "published",
      "permalink": "https://www.facebook.com/permalink/123456789012345",
      "metrics": {
        "likes": 15,
        "comments": 3,
        "shares": 7,
        "saves": 0,
        "extra": null,
        "metrics_synced_at": "2026-04-10T12:00:00Z"
      }
    }
  ],
  "created_at": "2026-04-10T09:00:00Z",
  "published_at": "2026-04-10T09:00:12Z"
}
Step 3: Refresh metrics on demand
curl "https://api.social-api.ai/v1/posts/post_01HZ9X3Q4R5M6N7P8V2K0W1J/metrics" \
  -H "Authorization: Bearer $SOCAPI_KEY"

9. Required OAuth scopes

The following Meta app scopes must be approved for your application before publishing will work:
ScopePurpose
pages_show_listList the pages the user manages
pages_read_engagementRead likes, comments, and shares on page posts
pages_read_user_contentRead posts and comments made by users on the page
pages_manage_engagementReply to and delete comments
pages_manage_metadataAccess page metadata and settings
pages_messagingSend and receive Messenger DMs
pages_manage_postsCreate, update, and delete page posts
public_profileAccess the user’s basic public profile
All publishing scopes (pages_manage_posts, pages_show_list) are required for create, update, and delete operations. If any required scope is missing, the Graph API returns a 200 with an error object or a 403, depending on the operation. To verify which scopes your connected account has, call GET /v1/accounts/:id/limits.