PostZen

Facebook

Publish text, image, video, and link posts to Facebook Pages with PostZen.

PostZen publishes text, image, video, and link posts to Facebook Pages. Publishing to personal Facebook profiles is not supported.

Facebook publishing is Pages only. You need admin-level access to the Page you connect; PostZen cannot publish to a personal profile.

Quick reference

FeatureLimit or behavior
Publishing destinationFacebook Pages only
Text63,206 characters; Facebook folds long posts behind See more
ImagesUp to 10 per post, each no larger than 30 MB
Video1 per post, no larger than 1 GB
Mixed mediaImages and video cannot be combined in one post
Image upload formatsJPEG/JPG, PNG, WebP, GIF
Video upload formatsMP4, MPEG, QuickTime, AVI, WebM, M4V
Link postsSet settings.link; link posts cannot include media
First commentUp to 8,000 characters
SchedulingSupported with scheduledFor, at least 60 seconds in the future

Before you start

  • You need a Facebook Page and admin-level access to it. Personal profiles, Groups, and Events are not supported.
  • PostZen manages the Facebook Pages permissions used during OAuth.
  • The free tier allows 2 connected accounts before a payment method is required. Connecting another account returns a 402.
  • A post must set exactly one of publishNow, scheduledFor, or isDraft.
  • Images and video cannot be mixed in the same post. A link post created with settings.link cannot include mediaItems.

Google Drive, Dropbox, OneDrive, and iCloud share links return HTML pages rather than media files. Use a publicly accessible direct image or video URL, or upload the file through POST /v1/media/presign. PostZen downloads and re-hosts external URLs up to 100 MB; presigned uploads can be up to 5 GB, subject to Facebook's per-file limits above.

Connect your account

Request a Facebook connect URL for the PostZen profile that will own the account. Send the user to the returned authUrl to authorize a Page where they have admin-level access.

const { data } = await postzen.connect.createConnectUrl({
  path: { platform: 'facebook' },
  query: { profileId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e' },
});

console.log(data.authUrl); // redirect the user here
console.log(data.state);   // expires after 10 minutes
response = client.connect.create_connect_url(
    "facebook",
    profile_id="jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
)

print(response.authUrl)  # redirect the user here
print(response.state)    # expires after 10 minutes
curl "https://api.postzen.dev/v1/connect/facebook?profileId=jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e" \
  -H "Authorization: Bearer $POSTZEN_API_KEY"

The response is { authUrl, state }. The state expires after 10 minutes. After OAuth completes, PostZen connects the selected Facebook Page, not the user's personal profile.

Quick start

Publish a text post to a connected Facebook Page. Set the target's accountId to the connected Page account returned by GET /v1/accounts.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'Our summer hours start today.',
    publishNow: true,
    platforms: [
      { platform: 'facebook', accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e' },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="Our summer hours start today.",
    publish_now=True,
    platforms=[
        {"platform": "facebook", "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e"},
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Our summer hours start today.",
    "publishNow": true,
    "platforms": [
      { "platform": "facebook", "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e" }
    ]
  }'

Content types

Text posts

A text post needs content and a Facebook Page target. Keep content at or below 63,206 characters.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'Registration is open for our next workshop.',
    publishNow: true,
    platforms: [
      { platform: 'facebook', accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e' },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="Registration is open for our next workshop.",
    publish_now=True,
    platforms=[
        {"platform": "facebook", "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e"},
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Registration is open for our next workshop.",
    "publishNow": true,
    "platforms": [
      { "platform": "facebook", "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e" }
    ]
  }'

Multi-image posts

Add up to 10 images in mediaItems. Each image can be no larger than 30 MB.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'A few photos from launch day.',
    publishNow: true,
    mediaItems: [
      { url: 'https://cdn.example.com/launch-1.jpg' },
      { url: 'https://cdn.example.com/launch-2.jpg' },
    ],
    platforms: [
      { platform: 'facebook', accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e' },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="A few photos from launch day.",
    publish_now=True,
    media_items=[
        {"url": "https://cdn.example.com/launch-1.jpg"},
        {"url": "https://cdn.example.com/launch-2.jpg"},
    ],
    platforms=[
        {"platform": "facebook", "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e"},
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "A few photos from launch day.",
    "publishNow": true,
    "mediaItems": [
      { "url": "https://cdn.example.com/launch-1.jpg" },
      { "url": "https://cdn.example.com/launch-2.jpg" }
    ],
    "platforms": [
      { "platform": "facebook", "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e" }
    ]
  }'

Do not add a video to the same mediaItems array. Facebook posts created through PostZen can contain images or one video, but not both.

Video posts

Attach one video in mediaItems. The video can be no larger than 1 GB.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'Watch the product walkthrough.',
    publishNow: true,
    mediaItems: [
      { url: 'https://cdn.example.com/walkthrough.mp4' },
    ],
    platforms: [
      { platform: 'facebook', accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e' },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="Watch the product walkthrough.",
    publish_now=True,
    media_items=[
        {"url": "https://cdn.example.com/walkthrough.mp4"},
    ],
    platforms=[
        {"platform": "facebook", "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e"},
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Watch the product walkthrough.",
    "publishNow": true,
    "mediaItems": [
      { "url": "https://cdn.example.com/walkthrough.mp4" }
    ],
    "platforms": [
      { "platform": "facebook", "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e" }
    ]
  }'

Set settings.link to a valid http or https URL. Link posts cannot include mediaItems. You can also set settings.firstComment to publish a first comment of up to 8,000 characters.

const { data } = await postzen.posts.createPost({
  body: {
    content: 'Read the full launch notes.',
    publishNow: true,
    platforms: [
      {
        platform: 'facebook',
        accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
        settings: {
          link: 'https://example.com/launch-notes',
          firstComment: 'Which update are you trying first?',
        },
      },
    ],
  },
});

console.log(data.post._id);
response = client.posts.create_post(
    content="Read the full launch notes.",
    publish_now=True,
    platforms=[
        {
            "platform": "facebook",
            "account_id": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
            "settings": {
                "link": "https://example.com/launch-notes",
                "first_comment": "Which update are you trying first?",
            },
        },
    ],
)

print(response.post.field_id)
curl -X POST https://api.postzen.dev/v1/posts \
  -H "Authorization: Bearer $POSTZEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Read the full launch notes.",
    "publishNow": true,
    "platforms": [
      {
        "platform": "facebook",
        "accountId": "jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e",
        "settings": {
          "link": "https://example.com/launch-notes",
          "firstComment": "Which update are you trying first?"
        }
      }
    ]
  }'

Media requirements

Images

RequirementValue
Images per postUp to 10
File sizeNo larger than 30 MB per image; an oversize image produces a warning
Formats accepted by /v1/media/presignJPEG/JPG, PNG, WebP, GIF
Mixed mediaCannot be combined with video in the same post

Videos

RequirementValue
Videos per post1
File sizeNo larger than 1 GB
Formats accepted by /v1/media/presignMP4, MPEG, QuickTime, AVI, WebM, M4V
Mixed mediaCannot be combined with images in the same post

Platform settings

Place Facebook settings inside the Facebook target in platforms:

{
  platform: 'facebook',
  accountId: 'jh72r5nqk9wx3v8m1t4cz6bs0fy5dg3e',
  settings: {
    link: 'https://example.com/launch-notes',
    firstComment: 'Which update are you trying first?',
  },
}
SettingTypeNotes
linkstring (URI)Shares a link with a preview card. Must use http or https and cannot be combined with mediaItems.
firstCommentstringPosts the value as the first comment after publishing. Maximum 8,000 characters.

PostZen analytics is live for Facebook Page insights, including post metrics, Page follower counts, and best-time-to-post suggestions. Facebook has retired its post reach and impression metrics, so those are not available. Likes, comments, and shares summaries on Page posts are not reported because PostZen does not request the permission that unlocks them. Pages connected before analytics launched may need to be reconnected to grant the Page insights permission before page-level metrics appear.

What you can't do

  • Publish to personal profiles, Groups, or Events. PostZen publishes to Facebook Pages only.
  • Publish Facebook Stories or Reels.
  • Live stream or use demographic targeting.
  • Edit a published post.
  • Read or manage comments. The firstComment setting can only publish the first comment with the post.
  • Read or manage DMs or an inbox.
  • Manage ads or receive engagement webhooks.

Common errors

ErrorMeaningFix
Link post includes mediaItemssettings.link cannot be combined with media.Remove mediaItems, or remove settings.link.
Invalid link URLsettings.link is not a valid http or https URL.Supply a valid URL beginning with http:// or https://.
Image over 30 MBThe image exceeds Facebook's PostZen limit and produces a warning.Use an image no larger than 30 MB.
Video over 1 GBThe video exceeds Facebook's PostZen limit.Use a video no larger than 1 GB.
Images and video combinedFacebook posts cannot mix images and video.Use images or one video in the post.
Expired Page tokenThe Facebook account needs to be reconnected. It appears with status: "disconnected" in GET /v1/accounts.Reconnect the Page account.
402 while connectingThe free-tier limit of 2 connected accounts has been reached without a payment method.Add a payment method before connecting another account.

On this page