Postpone Logo
Scheduling Posts

Bluesky

Schedule posts and threads with media attachments to Bluesky

Mutation

Use the scheduleBlueskyPost mutation to schedule posts to Bluesky:

Mutation
mutation ScheduleBlueskyPost($input: ScheduleBlueskyPostInput!) {
  scheduleBlueskyPost(input: $input) {
    success
    errors {
      field
      message
    }
    post {
      id
      socialAccount {
        id
        username
      }
      publishingStatus
      allowRepliesFrom
      submissions {
        id
        text
        order
        postAt
        contentWarning
        languages
        tags
        gallery {
          id
          media {
            id
            url
            type
          }
        }
      }
    }
  }
}

Input Parameters

ScheduleBlueskyPostInput

username
String! required
The username of the connected Bluesky account to post from
postAt
DateTime! required
When to publish the post (must be in the future)
thread
[BlueskyPostSubmissionInputType!]! required
Array of posts that make up the thread (minimum 1 post)
allowRepliesFrom
BlueskyAllowRepliesFromType
Who can reply to the post. Options: EVERYBODY, MENTIONED_USERS, FOLLOWED_USERS, NOBODY
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)

BlueskyPostSubmissionInputType

Each post in the thread supports these parameters:

text
String! required
The post text content (max 300 characters)
order
Int! required
Position of this post in the thread (0-based)
contentWarning
BlueskyContentWarningType! required
Content warning label. Options: NONE, SUGGESTIVE, NUDITY, PORN
gallery
GalleryInput
Media attachments (images, videos)
languages
[String!]
IETF BCP 47 language codes for the post content
tags
[String!]
Additional hashtags or topic tags for the post
mediaName
String
Name of a file from your Content Library (case-insensitive)
mediaUrl
String
URL of media to upload and attach to the post
repostAtAmount
Int
Number of time units before auto-reposting
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)
id
ID
ID of existing post when updating (only for updates)

Examples

Simple Post

Schedule a basic post with text only.

{
  "input": {
    "username": "myhandle.bsky.social",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Hello Bluesky! This is my first scheduled post 🌤️",
        "order": 0,
        "contentWarning": "NONE"
      }
    ]
  }
}

Post with Media URL

Schedule a post by uploading media from an external URL. The media will be automatically downloaded and added to your Content Library.

{
  "input": {
    "username": "myhandle.bsky.social",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Check out this amazing sunset! 🌅",
        "order": 0,
        "contentWarning": "NONE",
        "mediaUrl": "https://picsum.photos/seed/socialmedia/900/1600"
      }
    ]
  }
}

Post with Content Library Media

Schedule a post using media already in your Content Library. The search is case-insensitive and will use the first matching file based on its name.

{
  "input": {
    "username": "myhandle.bsky.social",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Sharing our company logo! 🏢",
        "order": 0,
        "contentWarning": "NONE",
        "mediaName": "company-logo.png"
      }
    ]
  }
}

Thread with Multiple Posts

Schedule a multi-post thread with reply restrictions.

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

Post with Content Warning

Schedule a post with appropriate content warning labeling.

{
  "input": {
    "username": "myhandle.bsky.social",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Artistic photography from my latest shoot 📸",
        "order": 0,
        "contentWarning": "SUGGESTIVE",
        "mediaUrl": "https://picsum.photos/seed/socialmedia/900/1600"
      }
    ]
  }
}

Multi-Language Post

Schedule a post with language tags for better discoverability.

{
  "input": {
    "username": "myhandle.bsky.social",
    "postAt": "2025-12-01T15:30:00Z",
    "thread": [
      {
        "text": "Hello world! / Hola mundo! / Bonjour le monde!",
        "order": 0,
        "contentWarning": "NONE",
        "languages": ["en", "es", "fr"],
        "tags": ["multilingual", "greetings"]
      }
    ]
  }
}

Auto-Repost Configuration

Schedule a post with automatic reposting.

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

Response Types

Success Response

{
  "data": {
    "scheduleBlueskyPost": {
      "success": true,
      "errors": [],
      "post": {
        "id": "123",
        "socialAccount": {
          "id": "456",
          "username": "myhandle.bsky.social"
        },
        "publishingStatus": "READY_TO_PUBLISH",
        "allowRepliesFrom": "EVERYBODY",
        "submissions": [
          {
            "id": "789",
            "text": "Hello Bluesky! This is my first scheduled post 🌤️",
            "order": 0,
            "postAt": "2025-12-01T15:30:00Z",
            "contentWarning": "NONE",
            "languages": [],
            "tags": [],
            "gallery": null
          }
        ]
      }
    }
  }
}

Error Response

{
  "data": {
    "scheduleBlueskyPost": {
      "success": false,
      "errors": [
        {
          "field": "text",
          "message": "Post text cannot exceed 300 characters."
        }
      ],
      "post": null
    }
  }
}

Validation Rules

The API enforces Bluesky's content policies and technical limitations:
  • Text Length: Maximum 300 characters per post
  • Media: Supports images and videos with reasonable file size limits
  • Content Warnings: Required field for all posts, use NONE for general audiences
  • Languages: Use standard IETF BCP 47 language codes (e.g., en, es, fr)
  • 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