Postpone Logo
Scheduling Posts

Introduction

Learn how to schedule posts across multiple social media platforms using the Postpone API.

Scheduling Posts via API

The Postpone API provides powerful GraphQL mutations to schedule posts across multiple social media platforms. This comprehensive guide will walk you through the process of scheduling posts programmatically.

Before getting started with scheduling posts, make sure you've read through the API introduction to learn how to work with the Postpone API playground and make API calls.

Overview

Postpone supports scheduling posts to the following platforms through dedicated GraphQL mutations:

Reddit

Schedule notification posts to multiple subreddits with custom timing, flair selection, and more.

X/Twitter

Schedule tweets with media attachments and thread support.

Instagram

Schedule photo and video posts with captions and hashtags.

Facebook

Schedule posts to Facebook Pages.

Threads

Schedule posts to Meta's Threads platform.

Bluesky

Schedule posts to the decentralized Bluesky network.

TikTok

Schedule video content to TikTok.

YouTube Shorts

Schedule short-form video content to YouTube.

LinkedIn

Schedule professional posts to LinkedIn profiles and pages.

Pinterest

Schedule pins to Pinterest boards.

Mastodon

Schedule posts to Mastodon instances.

Tumblr

Schedule posts to Tumblr blogs.

Platform-Specific Mutations

Each platform has its own dedicated GraphQL mutation for scheduling posts. Here's a quick reference:

PlatformMutation NameDescription
RedditscheduleRedditPostSchedule posts to multiple subreddits
X/TwitterscheduleTweetSchedule tweets and threads
InstagramscheduleInstagramPostSchedule feed posts, Reels, and Stories posts
FacebookscheduleFacebookPostSchedule posts to Pages
ThreadsscheduleThreadsPostSchedule posts to Threads
BlueskyscheduleBlueskyPostSchedule posts to Bluesky
TikTokscheduleTikTokPostSchedule video content
YouTube ShortsscheduleYouTubePostSchedule short-form videos
LinkedInscheduleLinkedInPostSchedule professional posts
PinterestschedulePinterestPostSchedule pins to boards
MastodonscheduleMastodonPostSchedule posts to Mastodon
TumblrscheduleTumblrPostSchedule posts to Tumblr

Common Parameters

While each platform has specific requirements, most scheduling mutations share common parameters:

username
String! required
The username of the connected social media account to post from.
postAt
DateTime
ISO 8601 timestamp indicating when the post should be published (must be in the future). Required, except on a draft (see Drafts without a date) or on a new post scheduled with schedulingMode: QUEUE_NEXT.
schedulingMode
SchedulingModeType
How the post date is decided. Options: SPECIFIC_TIME, QUEUE_NEXT (default: SPECIFIC_TIME). Only accepted when scheduling a new post. See Scheduling at the Next Open Slot.
text
String
The main text content of your post (character limits vary by platform).
media
[SimpleMediaInput]
Media files to attach to the post, each referenced by id, name, or url. See Attaching Media.
gallery
GalleryInput
Media gallery for platforms that support per-item captions and outbound links. Only needed when media isn't enough.
publishingStatus
PublishingStatusType
Publishing status. Options: READY_TO_PUBLISH, DRAFT (default: READY_TO_PUBLISH).
postTags
[ID!]
Array of post tag IDs to organize your content.
id
ID
ID of existing post when updating (only for updates).

Scheduling at the Next Open Slot

Instead of working out a time yourself, you can hand that job to Postpone: pass schedulingMode: QUEUE_NEXT, leave postAt out, and the post lands on the next open slot in the account's Account Schedule.

{
  "input": {
    "username": "myhandle",
    "schedulingMode": "QUEUE_NEXT"
  }
}

The rest of the input stays exactly as it was — only the date changes hands. Each platform page has a worked example.

A slot counts as taken when a scheduled post falls on it, or within about 30 minutes of it. Queue several posts in a row and they walk down the schedule one open slot at a time rather than piling onto the same time. The queue never fills up either: an account booked solid for months gets the first slot past the end of its queue.

This is the single-request version of querying Next Scheduled Dates and passing the result back as postAt. Prefer it over that two-step approach when you are only placing a post — because the slot is picked and taken in one transaction, two posts queued at the same moment can never be handed the same slot.

Rules

  • A schedule is required. The account has to have an Account Schedule set up. Without one the mutation fails with <username> has no schedule set up.
  • postAt and QUEUE_NEXT are mutually exclusive. Pass one or the other, never both. Sending both fails with Pass either a post date or QUEUE_NEXT, not both.
  • New posts only. Update mutations reject schedulingMode outright — QUEUE_NEXT and SPECIFIC_TIME alike — with schedulingMode is not supported when updating a post. An already-scheduled post occupies a slot, so queueing it again would read that slot as taken and walk the post forward. To move a scheduled post, pass a postAt.
  • Not for drafts. A draft doesn't hold a slot, so queueing one would hand the same slot to every other queued post. Save the draft without a date (or with a postAt), then set a date when you promote it to publishingStatus: READY_TO_PUBLISH.
  • Reddit is not supported. scheduleRedditPost has no schedulingMode parameter — Account Schedules don't apply to Reddit. Pass a postAt on each submission.
On platforms where postAt lives inside submissions (Instagram, Facebook, TikTok, YouTube Shorts, LinkedIn, Pinterest, and Tumblr), schedulingMode sits at the top level of the input instead, because it decides one date for the whole post. Every submission of a post shares that date.

Drafts without a date

A draft is somewhere to put a post before you've decided when it goes out, so postAt is optional on one:

{
  "input": {
    "username": "myhandle",
    "text": "still thinking about this one",
    "publishingStatus": "DRAFT"
  }
}

A date is still stored against the post, but it's a placeholder parked about 30 days out, not a time you chose.

Rules

  • Drafts only. A post going out as READY_TO_PUBLISH still has to say when. Leaving postAt off one fails with Provide a post date, or use QUEUE_NEXT.
  • Promotion needs a date. Promoting a draft to publishingStatus: READY_TO_PUBLISH without a postAt fails with Provide a post date. schedulingMode isn't accepted on an update either, so the date has to be spelled out.
  • Editing doesn't need one. Updating a draft that stays a draft can leave postAt out; the draft stays parked. Pass a postAt to give it a real date at any point.
  • A lapsed date gets re-parked. If a draft's stored date has passed by the time you edit it, a dateless edit pushes the placeholder back out. A date still in the future is never moved by an edit, whether you chose it or we parked it there.
  • Reddit is not supported. scheduleRedditPost requires a postAt on each submission, drafts included.
On platforms where postAt lives inside submissions, just leave it off the submission entries. publishingStatus sits at the top level of the input either way.

Attaching Media

Scheduling mutations take a media parameter: a list of the images, videos, or GIFs to attach to the post. Each item points at a single file, in one of three ways:

id
ID
ID of a file already in your Content Library.
name
String
Name of a file in your Content Library. The first match is used, and the match is case-insensitive.
url
String
Public URL of a file to be uploaded to your Content Library.

Every item must set exactly one of id, name, or url, and no file can be attached to the same post twice. You can mix the three forms freely within one list:

{
  "media": [
    { "id": "1001" },
    { "name": "company-logo.png" },
    { "url": "https://example.com/images/hero.jpg" }
  ]
}

If a file can't be resolved, the whole mutation fails with an error rather than scheduling the post without it. The number of items you can attach depends on the platform, so check the platform-specific docs.

See Uploading Media for how to get files into your Content Library and pick up their id.

media is only supported when scheduling a new post. Update mutations reject it.

Deprecated Media Parameters

mediaUrl, mediaUrls, and mediaName are deprecated in favor of media. They still work, but new integrations should use media, and existing ones should migrate:

DeprecatedUse instead
"mediaName": "logo.png""media": [{ "name": "logo.png" }]
"mediaUrl": "https://example.com/a.jpg""media": [{ "url": "https://example.com/a.jpg" }]
"mediaUrls": ["https://example.com/a.jpg", "https://example.com/b.jpg"]"media": [{ "url": "https://example.com/a.jpg" }, { "url": "https://example.com/b.jpg" }]

Response Format

All scheduling mutations return a consistent response structure:

{
  success: Boolean!
  errors: [ValidationError]
}
success
boolean
Indicates whether the post was successfully scheduled.
errors
[ValidationError]
Array of validation errors with specific error codes and messages.

Common Errors

These errors are commonly encountered across multiple platforms when scheduling posts:

Best Practices

When using the scheduling API, keep these best practices in mind:

Getting Started

To begin scheduling posts via the API:

Connect Your Accounts

Ensure you have connected the social media accounts you want to post to in your Postpone dashboard.

Obtain API Credentials

Get your API key from Postpone settings to authenticate your requests.

Choose Your Platform

Select the platform you want to schedule posts for and refer to the platform-specific documentation.

Test Your Integration

Use the API playground to test your mutations before implementing them in production.

Next Steps

Ready to start scheduling posts? Choose a platform from the list above to see detailed examples and platform-specific requirements.

Each platform has unique features and requirements. Be sure to read the platform-specific documentation for detailed parameter information and examples.