Facebook Scheduling API
Schedule Facebook Page posts for a future time via API, with per-target delivery status.
To schedule a Facebook Page post via API, send the same POST /api/posts request used for immediate publishing and add an ISO 8601 scheduled_at field — or set scheduled_at to "queue" to take the next open slot in a recurring queue defined under /api/schedules. Until it fires, the post sits in a scheduled state and can be updated or canceled.
Scheduling a Facebook Page post through the API isn't a separate resource from publishing one — it's the same POST /api/posts call with one extra field. This page covers a fixed future time, a recurring queue, and what to expect when the scheduled instant arrives.
How do I publish at a fixed instant?
scheduled_at to a normal create-post request. PostGate materializes and delivers the post at that instant; until then it sits in a scheduled state and can still be updated or canceled.curl -X POST "https://postgate.studio/api/posts?profile_group_id=grp_acme123" \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: launch-post-001" \
-d '{
"post": { "body": "Live in one hour." },
"profiles": ["pro_facebook789"],
"media": ["https://cdn.example.com/launch.jpg"],
"scheduled_at": "2026-09-01T14:00:00Z"
}'How do I take the next slot in a queue instead?
scheduled_at: "queue" instead of a fixed timestamp and the post takes the next open slot in the Page's recurring queue, defined separately under /api/schedules. Use kind: "slots" with comma-separated HH:mm times such as 09:00, 13:30, 18:00, or kind: "cron" for an arbitrary cron expression.curl -X POST https://postgate.studio/api/schedules \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekday update",
"kind": "cron",
"expression": "0 9 * * 1-5",
"timezone": "America/Sao_Paulo",
"profile_group_id": "grp_acme123",
"template": {
"post": { "body": "Good morning from Acme." },
"profiles": ["pro_facebook789"],
"media": []
}
}'Media is revalidated at publish time, not just at creation
failed hours or days after you created it. Watch target status, not only the initial acceptance.How do I pause a queue or cancel a single post?
PATCH /api/schedules/{id} with active: false stops future materialization while keeping the template. DELETE /api/posts/{id} cancels one still-scheduled post outright. Neither touches posts already delivered.Can a queue still hit Facebook's own posting limits?
Frequently asked questions
Can I cancel a scheduled Facebook post via the API?
Yes. DELETE /api/posts/{id} cancels a single still-scheduled post outright, and PATCH /api/schedules/{id} with active: false pauses a recurring schedule without deleting its template — future materialization stops but the definition stays. Neither action touches posts that have already been delivered.
Why did my scheduled Facebook post fail hours after I created it?
Because media is revalidated at publish time, not just at creation. A media URL that resolved fine when you scheduled the post can go stale before it fires — the file gets deleted or the CDN link expires. PostGate re-checks the asset at the scheduled instant, so a schedule can still terminate as failed hours or days after you created it. Watch target status, not only the initial acceptance.
Does scheduling through PostGate bypass Facebook’s rate limits?
No. PostGate’s scheduling is just timing — it doesn’t exempt a Page from Meta’s own limits. A burst of many scheduled slots firing close together on one Page can still trip Facebook’s throttling or the separate spam-prevention cap on Reels, so don’t pack a queue too tightly.
How do I set up a recurring posting queue for a Facebook Page?
Define a schedule under /api/schedules for the Page. Use kind: "slots" with comma-separated HH:mm times such as 09:00, 13:30, 18:00, or kind: "cron" for an arbitrary cron expression — for example 0 9 * * 1-5 with a timezone for weekday mornings. Posts created with scheduled_at: "queue" then take the next open slot.
