Facebook API
Schedule and automate Facebook Page posts with SocialSyncerAPI — Feed posts, Stories, multi-image, multi-link carousels, GIFs, and first comments.
Quick Reference
- Character limit: 63,206 (truncated at ~480 with "See more")
- Images per post: 10
- Videos per post: 1
- Image formats: JPEG, PNG, GIF (WebP auto-converted to JPEG)
- Image max size: 4 MB (Facebook rejects larger in practice)
- Video formats: MP4, MOV
- Video max size: 4 GB
- Video max duration: 240 min (feed), 120 sec (stories)
- Post types: Feed (text/image/video/multi-image/multi-link carousel), Story, Reel
- Scheduling: Yes
- Analytics: Yes
Before You Start
- API posts to Pages only (not personal profiles)
- User must be Page Admin or Editor
- Facebook tokens expire frequently — subscribe to the
account.disconnectedwebhook - Multiple Pages can be managed from one connected account
- Keep images under 4 MB and use JPEG or PNG format. WebP images are auto-converted to JPEG.
Quick Start
Post to a Facebook Page in under 60 seconds:
Python (httpx)
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Hello from SocialSyncerAPI!",
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
)
print("Posted to Facebook!", resp.json()["id"]) curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello from SocialSyncerAPI!",
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Node.js (fetch)
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Hello from SocialSyncerAPI!",
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
});
const data = await resp.json();
console.log("Posted to Facebook!", data.id); Content Types
Text-Only Post
No media required. Facebook is one of the few platforms that supports text-only posts.
Text-Only — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Just a text update for our followers.",
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
) Text-Only — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Just a text update for our followers.",
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Text-Only — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Just a text update for our followers.",
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
}); Single Image Post
Image — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Check out this photo!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
) Image — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Check out this photo!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Image — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Check out this photo!",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/photo.jpg" }
],
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
}); Multi-Image Post
Facebook supports up to 10 images in a single post. You cannot mix images and videos in the same post.
Multi-Image — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Photo dump from the weekend!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo1.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo2.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo3.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
) Multi-Image — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Photo dump from the weekend!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo1.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo2.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo3.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Multi-Image — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Photo dump from the weekend!",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/photo1.jpg" },
{ type: "image", url: "https://cdn.example.com/photo2.jpg" },
{ type: "image", url: "https://cdn.example.com/photo3.jpg" }
],
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
}); Video Post
A single video per post. For GIFs, use type: 'video' — they are treated as videos internally, auto-play, and loop.
Video — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Watch our latest video!",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/video.mp4"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
) Video — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Watch our latest video!",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/video.mp4"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Video — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Watch our latest video!",
mediaItems: [
{ type: "video", url: "https://cdn.example.com/video.mp4" }
],
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
}); Reel
Publish a Facebook Reel (short vertical video). Reels require a single vertical video (9:16). Duration: 3–60 seconds.
content is used as the Reel caption. Use platformSpecificData.title to set a separate Reel title.Reel — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Behind the scenes",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/reel.mp4"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reel",
"title": "Studio day"
}
}],
"publishNow": True
}
) Reel — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Behind the scenes",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/reel.mp4"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reel",
"title": "Studio day"
}
}],
"publishNow": true
}' Reel — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Behind the scenes",
mediaItems: [
{ type: "video", url: "https://cdn.example.com/reel.mp4" }
],
platforms: [{
platform: "facebook",
accountId: "YOUR_ACCOUNT_ID",
platformSpecificData: {
contentType: "reel",
title: "Studio day"
}
}],
publishNow: true
})
}); Story
Stories are 24-hour ephemeral content. Media is required. Text captions are not displayed on Stories, and interactive stickers are not supported via the API.
Story — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/story.jpg"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
"publishNow": True
}
) Story — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/story.jpg"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
"publishNow": true
}' Story — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
mediaItems: [
{ type: "image", url: "https://cdn.example.com/story.jpg" }
],
platforms: [{
platform: "facebook",
accountId: "YOUR_ACCOUNT_ID",
platformSpecificData: {
contentType: "story"
}
}],
publishNow: true
})
}); Multi-Link Carousel
Render a post as a 2–5 card carousel where each image has its own click-through link and headline. Set facebookSettings.carouselCards to layer per-card metadata. All items must be images.
Carousel — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Check out our latest inventory",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/car-1.jpg"},
{"type": "image", "url": "https://cdn.example.com/car-2.jpg"},
{"type": "image", "url": "https://cdn.example.com/car-3.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True,
"facebookSettings": {
"carouselLink": "https://example.com/inventory",
"carouselCards": [
{"link": "https://example.com/car-1", "name": "2024 Sedan", "description": "Low miles"},
{"link": "https://example.com/car-2", "name": "2023 SUV", "description": "Certified pre-owned"},
{"link": "https://example.com/car-3", "name": "2024 Truck", "description": "Loaded"}
]
}
}
) Carousel — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Check out our latest inventory",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/car-1.jpg"},
{"type": "image", "url": "https://cdn.example.com/car-2.jpg"},
{"type": "image", "url": "https://cdn.example.com/car-3.jpg"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true,
"facebookSettings": {
"carouselLink": "https://example.com/inventory",
"carouselCards": [
{"link": "https://example.com/car-1", "name": "2024 Sedan", "description": "Low miles"},
{"link": "https://example.com/car-2", "name": "2023 SUV", "description": "Certified pre-owned"},
{"link": "https://example.com/car-3", "name": "2024 Truck", "description": "Loaded"}
]
}
}' Carousel — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Check out our latest inventory",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/car-1.jpg" },
{ type: "image", url: "https://cdn.example.com/car-2.jpg" },
{ type: "image", url: "https://cdn.example.com/car-3.jpg" }
],
platforms: [
{ platform: "facebook", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true,
facebookSettings: {
carouselLink: "https://example.com/inventory",
carouselCards: [
{ link: "https://example.com/car-1", name: "2024 Sedan", description: "Low miles" },
{ link: "https://example.com/car-2", name: "2023 SUV", description: "Certified pre-owned" },
{ link: "https://example.com/car-3", name: "2024 Truck", description: "Loaded" }
]
}
})
}); Media Requirements
Images
- Feed Post: Up to 10 images, JPEG/PNG/GIF (WebP auto-converted), max 4 MB, recommended 1200 x 630 px
- Story: 1 image, JPEG/PNG, max 4 MB, recommended 1080 x 1920 px
Videos
- Feed Video: MP4/MOV, max 4 GB, max 240 min, min 1280 x 720 px, 30 fps, H.264
- Story: MP4/MOV, max 4 GB, max 120 sec, recommended 1080 x 1920 px, 30 fps, H.264
Platform-Specific Data
All fields go inside platformSpecificData for the Facebook platform entry.
draft— boolean — Creates an unpublished draft in Facebook Publishing Tools. Not supported for Stories.contentType— string — "story" or "reel". Defaults to feed post if omitted.title— string — Reel title (only for contentType="reel"). Separate from the content caption.firstComment— string — Auto-posted as the first comment after publish. Feed posts and Reels (not Stories). Skipped when draft is true.pageId— string — Post to a specific Page when the connected account manages multiple Pages.carouselCards— array — Multi-link carousel cards (2–5). Requires mediaItems with same length (images only).carouselLink— string — Optional top-level "See more" link for the carousel end card.geoRestriction— object — Restrict post visibility to specific countries.geoRestriction.countries: array of uppercase ISO 3166-1 alpha-2 codes, max 25.
Constraints
- Character limit: 63,206 (truncated at ~480 with "See more")
- Images per post: 10
- Videos per post: 1
- Video size: 4 GB max
- Video duration: 240 min (feed), 120 sec (stories)
- Image size: 4 MB (practical limit)
- Carousel cards: 2–5 for multi-link carousels
What You Can't Do
- Post to personal profiles (Pages only)
- Create Events
- Post to Groups (deprecated by Facebook)
- Go Live (requires the separate Facebook Live API)
- Add interactive story stickers
- Target audiences by demographics for organic posts (country-level geo-restriction IS supported)
Common Errors
- "Photos should be smaller than 4MB" — Image exceeds actual size limit or unsupported format. Reduce to under 4 MB, use JPEG/PNG.
- "Missing or invalid image file" — Facebook couldn't process image. Verify URL in incognito, ensure JPEG/PNG under 4 MB.
- "Unable to fetch video file from URL." — Use a direct, publicly accessible URL. Avoid cloud storage sharing links.
- "Facebook tokens expired." — Reconnect the account. Subscribe to the account.disconnected webhook.
- "Confirm your identity before you can publish" — Facebook security check triggered. Complete identity verification on Facebook.