Facebook API
Schedule and automate Facebook Page posts with Zernio API - Feed posts, Stories, multi-image, GIFs, and first comments
Quick Reference
| Property | Value |
|---|---|
| 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), Story |
| Scheduling | Yes |
| Inbox (DMs) | Yes (add-on) |
| Inbox (Comments) | Yes (add-on) |
| Inbox (Reviews) | Yes (add-on) |
| Analytics | Yes |
Before You Start
Facebook API only posts to Pages, not personal profiles. You must have a Facebook Page and admin access to it. Also: Facebook often rejects photos larger than 4 MB even though the stated limit is higher. Keep images under 4 MB and use JPEG or PNG format. WebP images are auto-converted to JPEG by Zernio.
- 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
Quick Start
Post to a Facebook Page in under 60 seconds:
const { post } = await zernio.posts.createPost({
content: 'Hello from Zernio API!',
platforms: [
{ platform: 'facebook', accountId: 'YOUR_ACCOUNT_ID' }
],
publishNow: true
});
console.log('Posted to Facebook!', post._id);result = client.posts.create(
content="Hello from Zernio API!",
platforms=[
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
publish_now=True
)
post = result.post
print(f"Posted to Facebook! {post['_id']}")curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello from Zernio API!",
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}'Content Types
Text-Only Post
No media required. Facebook is one of the few platforms that supports text-only posts.
const { post } = await zernio.posts.createPost({
content: 'Just a text update for our followers.',
platforms: [
{ platform: 'facebook', accountId: 'YOUR_ACCOUNT_ID' }
],
publishNow: true
});result = client.posts.create(
content="Just a text update for our followers.",
platforms=[
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer 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
}'Single Image Post
const { post } = await zernio.posts.createPost({
content: 'Check out this photo!',
mediaItems: [
{ type: 'image', url: 'https://example.com/photo.jpg' }
],
platforms: [
{ platform: 'facebook', accountId: 'YOUR_ACCOUNT_ID' }
],
publishNow: true
});result = client.posts.create(
content="Check out this photo!",
media_items=[
{"type": "image", "url": "https://example.com/photo.jpg"}
],
platforms=[
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Check out this photo!",
"mediaItems": [
{"type": "image", "url": "https://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.
const { post } = await zernio.posts.createPost({
content: 'Photo dump from the weekend!',
mediaItems: [
{ type: 'image', url: 'https://example.com/photo1.jpg' },
{ type: 'image', url: 'https://example.com/photo2.jpg' },
{ type: 'image', url: 'https://example.com/photo3.jpg' }
],
platforms: [
{ platform: 'facebook', accountId: 'YOUR_ACCOUNT_ID' }
],
publishNow: true
});result = client.posts.create(
content="Photo dump from the weekend!",
media_items=[
{"type": "image", "url": "https://example.com/photo1.jpg"},
{"type": "image", "url": "https://example.com/photo2.jpg"},
{"type": "image", "url": "https://example.com/photo3.jpg"}
],
platforms=[
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Photo dump from the weekend!",
"mediaItems": [
{"type": "image", "url": "https://example.com/photo1.jpg"},
{"type": "image", "url": "https://example.com/photo2.jpg"},
{"type": "image", "url": "https://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.
const { post } = await zernio.posts.createPost({
content: 'Watch our latest video!',
mediaItems: [
{ type: 'video', url: 'https://example.com/video.mp4' }
],
platforms: [
{ platform: 'facebook', accountId: 'YOUR_ACCOUNT_ID' }
],
publishNow: true
});result = client.posts.create(
content="Watch our latest video!",
media_items=[
{"type": "video", "url": "https://example.com/video.mp4"}
],
platforms=[
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Watch our latest video!",
"mediaItems": [
{"type": "video", "url": "https://example.com/video.mp4"}
],
"platforms": [
{"platform": "facebook", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}'Story (Image or Video)
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.
const { post } = await zernio.posts.createPost({
mediaItems: [
{ type: 'image', url: 'https://example.com/story.jpg' }
],
platforms: [{
platform: 'facebook',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: {
contentType: 'story'
}
}],
publishNow: true
});result = client.posts.create(
media_items=[
{"type": "image", "url": "https://example.com/story.jpg"}
],
platforms=[{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mediaItems": [
{"type": "image", "url": "https://example.com/story.jpg"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
"publishNow": true
}'Reel (Video)
Publish a Facebook Reel (short vertical video). Reels require a single vertical video.
Note:
contentis used as the Reel caption. UseplatformSpecificData.titleto set a separate Reel title.
curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Behind the scenes 🎬",
"mediaItems": [
{"type": "video", "url": "https://example.com/reel.mp4"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reel",
"title": "Studio day"
}
}],
"publishNow": true
}'const { post } = await zernio.posts.createPost({
content: 'Behind the scenes 🎬',
mediaItems: [
{ type: 'video', url: 'https://example.com/reel.mp4' }
],
platforms: [{
platform: 'facebook',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: {
contentType: 'reel',
title: 'Studio day'
}
}],
publishNow: true
});
console.log('Posted Reel to Facebook!', post._id);result = client.posts.create(
content="Behind the scenes 🎬",
media_items=[
{"type": "video", "url": "https://example.com/reel.mp4"}
],
platforms=[{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reel",
"title": "Studio day"
}
}],
publish_now=True
)
post = result.post
print(f"Posted Reel to Facebook! {post['_id']}")Reel requirements
- Single video only (no images)
- Vertical video recommended (9:16)
- Duration: 3–60 seconds
First Comment
Auto-post a first comment immediately after your post is published. Does not work with Stories or Reels.
const { post } = await zernio.posts.createPost({
content: 'New product launch!',
mediaItems: [
{ type: 'image', url: 'https://example.com/product.jpg' }
],
platforms: [{
platform: 'facebook',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: {
firstComment: 'Link to purchase: https://shop.example.com'
}
}],
publishNow: true
});result = client.posts.create(
content="New product launch!",
media_items=[
{"type": "image", "url": "https://example.com/product.jpg"}
],
platforms=[{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"firstComment": "Link to purchase: https://shop.example.com"
}
}],
publish_now=True
)curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "New product launch!",
"mediaItems": [
{"type": "image", "url": "https://example.com/product.jpg"}
],
"platforms": [{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"firstComment": "Link to purchase: https://shop.example.com"
}
}],
"publishNow": true
}'Media Requirements
Images
| Property | Feed Post | Story |
|---|---|---|
| Max images | 10 | 1 |
| Formats | JPEG, PNG, GIF (WebP auto-converted) | JPEG, PNG |
| Max file size | 4 MB | 4 MB |
| Recommended | 1200 x 630 px | 1080 x 1920 px |
Videos
| Property | Feed Video | Story |
|---|---|---|
| Max videos | 1 | 1 |
| Formats | MP4, MOV | MP4, MOV |
| Max file size | 4 GB | 4 GB |
| Max duration | 240 minutes | 120 seconds |
| Min duration | 1 second | 1 second |
| Recommended resolution | 1280 x 720 px min | 1080 x 1920 px |
| Frame rate | 30 fps recommended | 30 fps |
| Codec | H.264 | H.264 |
Platform-Specific Fields
All fields below go inside platformSpecificData for the Facebook platform entry.
| Field | Type | Description |
|---|---|---|
contentType | "story" | "reel" | Set to "story" for Page Stories (24h ephemeral) or "reel" for Reels (short vertical video). 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 only (not Stories or Reels). |
pageId | string | Post to a specific Page when the connected account manages multiple Pages. Get available pages with GET /v1/accounts/{accountId}/facebook-page. |
Multi-Page Posting
If your connected Facebook account manages multiple Pages, you can list them, set a default, or override per post.
List Available Pages
const pages = await zernio.accounts.getFacebookPage('YOUR_ACCOUNT_ID');
console.log('Available pages:', pages);pages = client.accounts.get_facebook_page("YOUR_ACCOUNT_ID")
print("Available pages:", pages)curl -X GET https://zernio.com/api/v1/accounts/YOUR_ACCOUNT_ID/facebook-page \
-H "Authorization: Bearer YOUR_API_KEY"Post to Multiple Pages
Use the same accountId multiple times with different pageId values:
const { post } = await zernio.posts.createPost({
content: 'Exciting news from all our brands!',
platforms: [
{
platform: 'facebook',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: { pageId: '111111111' }
},
{
platform: 'facebook',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: { pageId: '222222222' }
}
],
publishNow: true
});
console.log('Posted to Facebook!', post._id);result = client.posts.create(
content="Exciting news from all our brands!",
platforms=[
{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {"pageId": "111111111"}
},
{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {"pageId": "222222222"}
}
],
publish_now=True
)
post = result.post
print(f"Posted to Facebook! {post['_id']}")curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Exciting news from all our brands!",
"platforms": [
{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"pageId": "111111111"
}
},
{
"platform": "facebook",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"pageId": "222222222"
}
}
],
"publishNow": true
}'You can also set a default page with POST /v1/accounts/{accountId}/facebook-page so you don't need to pass pageId on every request.
Media URL Requirements
- URLs must be publicly accessible via HTTPS
- No redirects, no authentication
- Cloud storage sharing links (Google Drive, Dropbox) may not work -- use direct download URLs
- WebP images are auto-converted to JPEG before upload
Analytics
Requires Analytics add-on
Available metrics via the Analytics API:
| Metric | Available |
|---|---|
| Impressions | ✅ |
| Likes | ✅ |
| Comments | ✅ |
| Shares | ✅ |
| Clicks | ✅ |
| Views | ✅ |
const analytics = await zernio.analytics.getAnalytics({
platform: 'facebook',
fromDate: '2024-01-01',
toDate: '2024-01-31'
});
console.log(analytics.posts);analytics = client.analytics.get(
platform="facebook",
from_date="2024-01-01",
to_date="2024-01-31"
)
print(analytics["posts"])curl "https://zernio.com/api/v1/analytics?platform=facebook&fromDate=2024-01-01&toDate=2024-01-31" \
-H "Authorization: Bearer YOUR_API_KEY"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 specific audiences for organic posts
Common Errors
| Error | Meaning | Fix |
|---|---|---|
| "Photos should be smaller than 4MB and saved as JPG or PNG." | Image exceeds actual size limit or unsupported format | Reduce to under 4 MB. Use JPEG or PNG. |
| "Missing or invalid image file" | Facebook couldn't process image -- corrupt, wrong format, or inaccessible URL | Verify URL in an incognito browser. Ensure JPEG/PNG under 4 MB. |
| "Unable to fetch video file from URL." | Facebook's servers couldn't download the video | Use a direct, publicly accessible URL. Avoid cloud storage sharing links. |
| "Facebook tokens expired. Please reconnect." | OAuth token expired | Reconnect the account. Facebook tokens have shorter lifespans. Subscribe to the account.disconnected webhook. |
| "Confirm your identity before you can publish as this Page." | Facebook security check triggered | Log into Facebook, go to the Page, and complete identity verification. |
| "Publishing failed due to max retries reached" | All 3 retry attempts failed | Usually temporary. Retry manually or wait and try again. |
Inbox
Requires Inbox add-on — Build: +$10/mo · Accelerate: +$50/unit · Unlimited: +$1,000/mo
Facebook has the most complete inbox support across DMs, comments, and reviews.
Direct Messages
| Feature | Supported |
|---|---|
| List conversations | ✅ |
| Fetch messages | ✅ |
| Send text messages | ✅ |
| Send attachments | ✅ (images, videos, audio, files) |
| Quick replies | ✅ (up to 13, Meta quick_replies) |
| Buttons | ✅ (up to 3, generic template) |
| Carousels | ✅ (generic template, up to 10 elements) |
| Message tags | ✅ (4 types) |
| Archive/unarchive | ✅ |
Message tags: Use messagingType: "MESSAGE_TAG" with one of: CONFIRMED_EVENT_UPDATE, POST_PURCHASE_UPDATE, ACCOUNT_UPDATE, or HUMAN_AGENT to send messages outside the 24-hour messaging window.
Persistent Menu
Manage the persistent menu shown in Facebook Messenger conversations. Max 3 top-level items, max 5 nested items.
See Account Settings for the GET/PUT/DELETE /v1/accounts/{accountId}/messenger-menu endpoints.
Comments
| Feature | Supported |
|---|---|
| List comments on posts | ✅ |
| Reply to comments | ✅ |
| Delete comments | ✅ |
| Like comments | ✅ |
| Hide/unhide comments | ✅ |
Reviews (Pages)
| Feature | Supported |
|---|---|
| List reviews | ✅ |
| Reply to reviews | ✅ |
Related Endpoints
- Connect Facebook Account - OAuth flow
- Create Post - Post creation and scheduling
- Upload Media - Image and video uploads
- Analytics - Post performance metrics
- Messages, Comments, and Reviews
- Account Settings - Persistent menu configuration