Postpone Logo
Platforms

Threads

Schedule posts and threads with media attachments to Meta's Threads platform

Mutation

Use the scheduleThreadsPost mutation to schedule posts to Threads:

Mutation
mutation ScheduleThreadsPost($input: ScheduleThreadsPostInput!) {
  scheduleThreadsPost(input: $input) {
    success
    errors {
      field
      message
    }
    post {
      id
      socialAccount {
        id
        username
      }
      publishingStatus
      submissions {
        id
        text
        order
        postAt
        gallery {
          id
          galleryMediaSet {
            id
            media {
              id
              url
              mimeType
            }
          }
        }
      }
    }
  }
}

Input Parameters

ScheduleThreadsPostInput

username
String! required
The username of the connected Threads account to post from
postAt
DateTime
When to publish the post (must be in the future). Required unless you pass schedulingMode: QUEUE_NEXT when scheduling a new post, or the post is a draft. See Drafts without a date.
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.
thread
[ThreadsPostSubmissionInputType!]! required
Array of posts that make up the thread (minimum 1 post)
replySettings
ThreadsReplySettingsType
Who can reply to the post. Options: EVERYONE, MENTIONED_USERS, FOLLOWING
isGhostPost
Boolean
Whether to publish as a ghost post. Ghost posts are text-only and auto-archive after 24 hours. Cannot be combined with media, GIFs, polls, or multi-post threads.
publishingStatus
PublishingStatusType
Publishing status. Options: READY_TO_PUBLISH, DRAFT (default: READY_TO_PUBLISH)
postTags
[ID!]
Array of post tag IDs to organize your content. See Post Tags.
id
ID
ID of existing post when updating (only for updates)

ThreadsPostSubmissionInputType

Each post in the thread supports these parameters:

text
String! required
The post text content (max 500 characters)
order
Int! required
Position of this post in the thread (0-based)
poll
PollInputType
Poll configuration (cannot be combined with media)
media
[SimpleMediaInput]
Media files to attach to the post. Each item references a file by id, name, or url. See Attaching Media. Only supported when scheduling new posts, not when updating existing ones.
repostAtAmount
Int
Number of time units before auto-retweeting
repostAtUnit
String
Time unit for auto-repost. Options: hour, day
repostRepeatDays
Int
How many days to repeat the auto-repost (max 365)
repostFromSocialAccount
SocialAccountInputType
Account to repost from (must be connected to your Postpone account)
removeAtAmount
Int
Number of time units before auto-deleting the post
removeAtUnit
String
Time unit for auto-deletion. Options: hour, day
removeMinLikes
Int
Minimum likes required to prevent auto-deletion
final
Boolean
Whether this is the final post in the thread (default: false)
topicTag
String
Custom Threads topic tag for the post (max 50 characters). Cannot contain periods (.) or ampersands (&). If omitted, the first hashtag in the text is used as the topic tag. Only the first post in a thread (order: 0) can have a topic tag — values set on later posts are ignored.
id
ID
ID of existing post when updating (only for updates)

Examples

Simple Post

Schedule a basic post with text only.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Hello Threads! This is my first scheduled post 🧵",
        "order": 0
      }
    ]
  }
}

Scheduling at the Next Open Slot

Instead of picking a time yourself, pass schedulingMode: QUEUE_NEXT and leave postAt out. Postpone puts the post in the next open slot on the account's Account Schedule, skipping any slot that already has a post on it.

{
  "input": {
    "username": "myhandle",
    "schedulingMode": "QUEUE_NEXT",
    "thread": [
      {
        "text": "This one goes out at my next open slot.",
        "order": 0
      }
    ]
  }
}

The whole thread lands on that one slot, the same way an explicit postAt applies to every post in the thread.

The account needs a schedule set up for this to work, postAt and QUEUE_NEXT can't be combined, and updateScheduledThreadsPost rejects schedulingMode. See Scheduling at the Next Open Slot for the full rules.

Post with Media URL

Schedule a post by uploading media from an external URL. Use this when you have a direct link to an image, video, or GIF that you want to attach. The media will be automatically downloaded and added to your Content Library.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Check out this amazing sunset! 🌅",
        "order": 0,
        "media": [{ "url": "https://example.com/sunset.jpg" }]
      }
    ]
  }
}

Post with Content Library Media

Schedule a post using media already in your Content Library. Use this when you want to reuse media you've previously uploaded. Reference the file by its id, which every upload mutation returns.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Sharing our company logo! 🏢",
        "order": 0,
        "media": [{ "id": "1042" }]
      }
    ]
  }
}

You can also reference the file by name. Names are matched case-insensitively and the first match wins, so prefer id when several files share a name.

{
  "media": [{ "name": "company-logo.png" }]
}

Thread with Multiple Posts

Schedule a multi-post thread.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "replySettings": "FOLLOWING",
    "thread": [
      {
        "text": "🧵 Thread about building great APIs (1/3)",
        "order": 0
      },
      {
        "text": "First, always design your API with the developer experience in mind. Clear documentation and consistent patterns make all the difference.",
        "order": 1
      },
      {
        "text": "Second, implement proper error handling and rate limiting. Your API consumers will thank you when things go wrong (and they will).",
        "order": 2,
        "final": true
      }
    ]
  }
}

Post with Poll

Schedule a post with an interactive poll.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "What's your favorite programming language? 💻",
        "order": 0,
        "poll": {
          "choices": ["JavaScript", "Python", "Go", "Rust"],
          "durationMinutes": 1440
        }
      }
    ]
  }
}

Post with a Custom Topic Tag

Schedule a post with an explicit Threads topic tag. The tag can include spaces and is independent of any hashtags in the text. If topicTag is omitted, the first hashtag in the post text is used instead.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Breaking down the latest model release.",
        "order": 0,
        "topicTag": "AI Threads"
      }
    ]
  }
}

Auto-Repost Configuration

Schedule a post with automatic reposting.

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Don't miss our latest blog post about API best practices! 📖",
        "order": 0,
        "repostAtAmount": 2,
        "repostAtUnit": "hour",
        "repostRepeatDays": 3,
        "repostFromSocialAccount": {
          "username": "mycompany"
        }
      }
    ]
  }
}

Multiple Media Attachments

Schedule a post with multiple images or videos (up to 20 media files per post).

{
  "input": {
    "username": "myhandle",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Here's a collection of our best product shots! 📸",
        "order": 0,
        "media": [
          { "id": "1231" },
          { "id": "1234" },
          { "id": "1250" }
        ]
      }
    ]
  }
}

Response Types

Success Response

{
  "data": {
    "scheduleThreadsPost": {
      "success": true,
      "errors": [],
      "post": {
        "id": "123",
        "socialAccount": {
          "id": "456",
          "username": "myhandle"
        },
        "publishingStatus": "READY_TO_PUBLISH",
        "submissions": [
          {
            "id": "789",
            "text": "Hello Threads! This is my first scheduled post 🧵",
            "order": 0,
            "postAt": "2025-12-01T15:30:00Z",
            "gallery": null,
            "poll": null
          }
        ]
      }
    }
  }
}

Error Response

{
  "data": {
    "scheduleThreadsPost": {
      "success": false,
      "errors": [
        {
          "field": "text",
          "message": "You cannot schedule a post longer than 500 characters."
        }
      ],
      "post": null
    }
  }
}

Updating a Post

To update an existing scheduled post, use the same input type with the corresponding update mutation and include the post id:

Mutation
mutation UpdateScheduledThreadsPost($input: ScheduleThreadsPostInput!) {
  updateScheduledThreadsPost(input: $input) {
    success
    errors {
      field
      message
    }
    post {
      id
    }
  }
}

Pass the id of the post you want to update in the input, along with the fields you want to change:

{
  "input": {
    "id": "12345",
    "username": "myhandle",
    "postAt": "2026-01-15T10:30:00Z",
    "thread": [{"text": "Updated thread text!", "order": 0}]
  }
}
The update mutation uses the same input type as the create mutation. Include the id field to specify which post to update. Only scheduled posts that have not been published yet can be updated.

postAt is required on an update, so every update states the date the post goes out on — pass the date it already has to leave it where it is. A draft staying a draft is exempt, and a draft you're promoting to READY_TO_PUBLISH needs a date of your choosing; see Drafts without a date.

schedulingMode is not accepted on an update at all; see Scheduling at the Next Open Slot.

Validation Rules

The API enforces Threads' content policies and technical limitations:
  • Text Length: Maximum 500 characters per post
  • Media: Maximum 20 images/videos per post
  • Image Size: Maximum 8MB per image
  • GIF Size: Maximum 15MB per GIF
  • Video Size: Maximum 1GB per video file
  • Video Duration: Maximum 300 seconds (5 minutes) per video
  • Polls: 2-4 options, each max 25 characters. Cannot be combined with media attachments.
  • Topic Tag: Maximum 50 characters. Cannot contain periods (.) or ampersands (&). A leading # is allowed and will be stripped.
  • Threads: No hard limit on thread length
  • Scheduling: Posts must be scheduled for future dates only
  • Account Limits: Respects your plan's monthly post limits

Common Errors