How to fix: Use a ui:// URI and text/html;profile=mcp-app. For mcp-use v1, use widgetMetadata.metadata.widgetDescription; for v2, use the bound tool's view.description. The current description check reads _meta.ui.widgetDescription or _meta["openai/widgetDescription"] on resource contents or linked tools, not resource.description. Consequently, v2 view.description alone may leave this warning: report the checker compatibility gap instead of adding unsupported v1 fields or claiming the warning is fixed.
How to fix: For tools that render a UI resource, add openai/toolInvocation with string fields invoking and invoked (present-tense labels shown while the tool runs and after it finishes, e.g. "Searching…" / "Searched").
How to fix: For ChatGPT submission, set one exact HTTPS origin such as "https://app.example.com" on every view via _meta.ui.domain (or openai/widgetDomain). Paths are not valid and all views in one app must share the origin.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List all connected social media channels (X/Twitter, Instagram, LinkedIn, Facebook, TikTok, etc.). Returns channel ID, platform, account name, and token status, plus a `capabilities` object saying whether the caller may create, publish or approve posts. Check that before attempting a write rather than discovering the permission from a 403. Use this when the user wants to see which social accounts are connected.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
active
Filter by active status. Defaults to true (only active channels). false also includes up to 100 disconnected channels, most recently updated first.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Create a new social media post. Can be saved as a draft or scheduled for a specific time. Supports platform-specific content overrides, media attachments, labels, and thread format. IMPORTANT: YouTube requires a video. TikTok requires a video, or 1 to 35 images with postTypeOverrides.tiktok = "photo_slideshow". Do not include either on a text-only post. Instagram defaults to feed_photo — set postTypeOverrides for video content (reel, feed_video). Use this when the user wants to draft or schedule one new post. It never publishes immediately; publish_post does that.
The description explains the capability, when to use it, and what to expect.
Inputs57/100
168 of 229 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
content
The post text content. Optional — defaults to empty for media-only posts. LinkedIn mentions: write @[Display Name](urn:li:organization:ID) for a Page or @[Display Name](urn:li:person:ID) for a person; The token publishes as a real mention on LinkedIn and as plain @Display Name on other channels.
Clear enough to supply this argument.
channels › items › channelId
Channel ID to post to.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
channels › items › platform
Platform name. One of the supported BulkPublish platforms.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
Post status. "draft" (default) or "scheduled".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scheduledAt
ISO 8601 datetime for scheduling (e.g. 2025-01-15T10:00:00Z). Required when status is scheduled.
Clear enough to supply this argument.
timezone
Timezone for scheduling (e.g. "America/New_York"). Defaults to UTC.
Clear enough to supply this argument.
mediaFileIds
Array of media file IDs to attach. Upload media first with upload_media.
Clear enough to supply this argument.
labels
Array of label IDs to tag the post with.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
platformSpecific › youtube › title
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › privacyStatus
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › categoryId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › madeForKids
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › playlistId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › thumbnailUrl
Not provided
Missing description. Explain what this value means and how to supply it.
true discloses realistic altered or synthetic content. Video and short posts.
Clear enough to supply this argument.
platformSpecific › youtube › notifySubscribers
Only an explicit false changes anything: publishes without notifying subscribers.
Clear enough to supply this argument.
platformSpecific › youtube › license
Default youtube; creativeCommon publishes under Creative Commons Attribution.
Clear enough to supply this argument.
platformSpecific › youtube › embeddable
false stops other websites embedding the video.
Clear enough to supply this argument.
platformSpecific › youtube › publicStatsViewable
false hides extended statistics on the watch page.
Clear enough to supply this argument.
platformSpecific › youtube › defaultLanguage
Language of the title and description, e.g. 'en', 'pt-BR', 'zh-Hans'.
Clear enough to supply this argument.
platformSpecific › youtube › defaultAudioLanguage
Language spoken in the video, e.g. 'en'.
Clear enough to supply this argument.
platformSpecific › youtube › recordingDate
YYYY-MM-DD or an ISO 8601 date-time; a plain date is stored as midnight UTC.
Clear enough to supply this argument.
platformSpecific › pinterest › title
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › description
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › link
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › dominantColor
Hex color e.g. #FF5733
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › coverImageUrl
Cover image URL for video pins. Optional — server falls back to an attached image, then the video's auto-extracted poster frame.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › boardSectionId
Numeric ID of a section of the chosen board (list with get_channel_options and boardId). Send it beside its board, per channel or flat. Pin, video_pin and carousel. A flat value is ignored for a channel with its own boardId, and any section is ignored when no board was chosen.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › coverKeyFrameTime
video_pin only: use the frame at this many seconds (whole number, 0 or more) as the cover. A time past the end uses the last frame; coverImageUrl wins when both are sent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › gmb › ctaType
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › ctaUrl
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › eventTitle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › startDate
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › startTime
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › endDate
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › endTime
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › couponCode
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › redeemOnlineUrl
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › termsConditions
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › privacyLevel
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableDuet
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableStitch
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableComment
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › isAigc
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › brandContentToggle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › brandOrganicToggle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › thumbnailTimestamp
Cover frame for the video, in seconds from the start.
Clear enough to supply this argument.
platformSpecific › tiktok › sendToDrafts
Send a video or photo_slideshow post to the creator's TikTok drafts instead of publishing it (default false). privacyLevel is then not required, and the direct-post settings (privacyLevel, disableDuet, disableStitch, disableComment, isAigc, brandContentToggle, brandOrganicToggle, autoAddMusic, thumbnailTimestamp) are ignored. A video draft carries no caption; a photo draft sends it. Once delivered the destination becomes published with no platformUrl; if the creator posts it within about a week, platformPostId becomes the video id, platformUrl is filled in and analytics are collected.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tiktok › photoCoverIndex
photo_slideshow only: which image is the cover, a whole number 0 to 34 counting from 0 in attachment order (default 0). An index past the last image falls back to the first.
Clear enough to supply this argument.
platformSpecific › tiktok › autoAddMusic
Photo posts published directly only: lets TikTok add a recommended track (default false). Ignored with sendToDrafts.
Clear enough to supply this argument.
platformSpecific › x › replySettings
Who can reply: everyone, following, verified, subscribers or mentionedUsers. Applies to a single post and to the first post of a thread.
Clear enough to supply this argument.
platformSpecific › x › repostId
With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › poll › options
2 to 4 choices, each 1 to 25 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › poll › durationMinutes
How long the poll stays open, whole minutes from 5 to 10080 (7 days).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › quoteId
The post to quote: its numeric ID or its x.com / twitter.com status URL. Cannot be combined with poll. On a thread it applies to the first post.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › communityId
Posts into an X Community: its numeric ID or its https://x.com/i/communities/<id> URL. The account must be a member.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › shareWithFollowers
With communityId, also shows the post to your followers (default false). Ignored without communityId.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › facebook › shareToStory
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › facebook › textFormatPresetId
Digits only (a Facebook background ID). Shows a short text post on a coloured background. Used only on a Page feed post with no photo, video or link card and at most 130 characters; anywhere else it is left out and the post publishes as plain text. If Facebook refuses the background the post is published once more without it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › facebook › thumbnailUrl
Cover image URL for a video or Reel. Facebook only accepts a cover once the video exists, so it is applied after the video publishes and appears a moment after the post; a cover that cannot be fetched or that Facebook rejects leaves the video published with Facebook's own chosen frame rather than failing the post.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › collaborators
Comma-separated Instagram usernames (no leading @) tagged as co-authors. Applies with postTypeOverrides.instagram of 'feed_photo', 'feed_video', 'reel' or 'carousel' — on a carousel the co-authors are set on the carousel itself, not on its individual items. Ignored on 'story', which has no co-author concept.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › shareToStory
Not provided
Missing description. Explain what this value means and how to supply it.
Which attached media item the tag belongs to, counting from 0 in attachment order (default 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › shareToFeed
Reels only. false shows the Reel only in the Reels tab; true also shows it in the main feed. Omitted: Instagram's own default (feed and Reels tab).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › locationId
Digits only: the numeric ID of a Facebook Page that has a location. Applies to photos, videos, Reels and carousels, not Stories. Instagram refuses the post if it does not recognise the ID as a place.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › trialReel
Publish as a trial reel, shown to people who do not follow the account first. Only takes effect with postTypeOverrides.instagram of 'reel' — a 'feed_video' publishes as an ordinary reel and this is ignored, even though both use the same underlying reel container.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › graduationStrategy
How a trial reel becomes a normal one: 'manual' (the creator releases it) or 'auto' (released automatically if it performs well). Default 'manual'. Ignored unless trialReel is true.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › thumbnailTimestamp
Cover frame for a video or Reel, in seconds from the start. Applies to postTypeOverrides.instagram of 'feed_video' or 'reel'. Ignored when coverUrl is also set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › coverUrl
Cover image URL for a video or Reel. Takes precedence over thumbnailTimestamp: Instagram accepts one or the other and rejects a request carrying both, so only this one is forwarded when both are sent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › quotePostId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › threads › repostId
With postTypeOverrides.threads = 'repost': the numeric ID of the Threads post to repost (Threads links cannot be used; the ID of a post published through BulkPublish is in get_post's platforms[].platformPostId).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › topicTag
One topic tag for the post, without a leading '#'. Must not contain periods or ampersands.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › locationId
Numeric place ID from get_channel_options with a `q` search on a Threads channel. Only works once the channel has granted location tagging.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › replyControl
Who can reply (default everyone). parent_post_author_only means only you. Applies to the post itself, never to later replies in a thread; ignored on a repost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › pollOptions
2 to 4 poll choices, each 1 to 25 characters. Text-only posts: on an image, video or carousel post the poll is left out. In a thread it goes on the first part when that part has no media.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › linkAttachment
An http(s) URL on a public host shown as the preview card on a text post; left out on other post types. Threads refuses a post with more than 5 links in total, and a link here that differs from every link in the text counts as one more.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › documentTitle
`document` posts only: the title shown above the document in the feed. Defaults to the file's name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › question
Up to 140 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › options
2 to 4 answers, each up to 30 characters; blank entries are ignored.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › duration
Default THREE_DAYS.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › reshareId
Required for `reshare` posts: the post's LinkedIn link, or its urn:li:share:<id> / urn:li:ugcPost:<id> ID. Activity links (urn:li:activity:<id>) cannot be reshared.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › thumbnailUrl
Cover for a `post` that carries a video: a public http(s) link to an image of up to 10MB. A cover that cannot be fetched is skipped and LinkedIn picks the frame.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › visibility
Who can see the post (default PUBLIC). CONNECTIONS applies to personal profiles only; on a Page it is published as PUBLIC.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › disableReshare
true stops other members resharing the post (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › repostId
With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › replyAllow
Who can reply. Omitted or [] means everyone; otherwise ['nobody'] or any mix of mention, following, follower ('nobody' cannot be combined). Set right after the post publishes; if Bluesky refuses it the post stays published without it. First post of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › allowQuotes
false stops other accounts quoting the post (default true). Set right after publishing, like replyAllow.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › quoteId
The post to quote: a bsky.app post link or an at:// URI (a bare ID is read as one of your own posts). Replaces a link card; with media attached both appear together. Publishing fails before anything is posted if the post cannot be found.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › langs
Up to 3 language codes such as 'en' or 'pt-BR'. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › contentLabel
Adds a content warning. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › repostId
With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › options
2 to 4 choices, each 1 to 50 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › expiresIn
Seconds the poll stays open, 300 to 2629746.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › multiple
Voters may pick more than one choice (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › hideTotals
Hide counts until the poll ends (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › sensitive
Hides attached media behind a click (default false). No effect without media. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › quoteId
The post to quote: its URL, or its status ID on your own server. Needs a server running Mastodon 4.5 or later, otherwise publishing fails and nothing is posted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › discord › anyOf › 1 › silent
Suppress notifications for the message.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › blogName
Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › title
Rendered as a heading block above the body.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › tags
Tumblr tags, without the leading '#'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › link
Appended as a link block.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › sourceUrl
Attribution URL stored as the post's source.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › state
Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › slug
Up to 200 characters; lowercased and hyphenated into the permalink.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Spotlight only. Default true; false sends skip_save_to_profile to Snap.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformContent › facebook
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › instagram
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › x
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › tiktok
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › youtube
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › threads
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › bluesky
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › pinterest
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › linkedin
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › mastodon
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › gmb
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › discord
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › telegram
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › tumblr
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › snapchat
Not provided
Missing description. Explain what this value means and how to supply it.
postFormat
Post format. "post" (default), "video", "reel", "story", "carousel", or "thread" for multi-part threads.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
threadParts › items › content
Thread part content.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
threadParts › items › mediaFileIds
Media files for this thread part.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postTypeOverrides › instagram
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › facebook
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › x
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › tiktok
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › youtube
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › threads
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › bluesky
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › linkedin
document: one PDF, Word or PowerPoint file from the media library (exactly one document, no images or videos; title from platformSpecific.linkedin.documentTitle). poll: a question with 2-4 answers from platformSpecific.linkedin.poll (needs post text, no media). reshare: shares an existing LinkedIn post from platformSpecific.linkedin.reshareId (post text optional, no media).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postTypeOverrides › pinterest
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › gmb
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › mastodon
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › discord
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › telegram
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › tumblr
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › snapchat
story (default): 1 image or video, caption NOT sent. saved_story: 1 image or video with a title. spotlight: video only, 6–60s, caption becomes the description. Story videos must be 5–60s; a video outside its range is refused when the post is scheduled or published. saved_story video length is not checked.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
requestApproval
Optional (default false). Set true to hold a scheduled post for team approval (approvalStatus becomes 'pending'). Forced on server-side for API keys of roles without post:publish (contributors), regardless of this flag.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
publishWhenApproved
Optional (default false). Set true on a post that waits for approval when it should go out as soon as it is approved, even if that is after its scheduled time. This is how someone who needs approval says 'publish now': status 'scheduled', scheduledAt = now, requestApproval true (or a contributor key), publishWhenApproved true. An approval arriving more than 15 minutes late then publishes immediately; with false it is approved but returned to draft for a new time. Stored only when the post ends up approvalStatus 'pending'; otherwise saved as false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
linkTrackingOverride
Optional per-post override for link tracking (bulkpubli.sh). true forces links in this post to be shortened and their clicks counted, false forces them to publish as written, and null/omitted (the default) inherits the organization's Link Tracking setting. Shortening happens at publish time, per channel, so two accounts on the same platform get distinct codes; it is skipped for a channel when the rewrite would push the post past that platform's character limit (a short URL is 28 characters and can be longer than the link it replaces). Short links are part of the Pro and Business plans: on Free, links always publish as written and true has no effect.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
deleteMediaAfterPublish
Optional (default false: media is kept in the library). Set true to delete the attached media once every channel has published, so it stops counting toward the storage limit. Forced to false when repeatSchedule is set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
repeatSchedule › frequency
How often the post repeats.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
repeatSchedule › daysOfWeek
Weekly/biweekly: days to post on, 0=Sunday … 6=Saturday.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
repeatSchedule › dayOfMonth
Monthly: day of the month.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
repeatSchedule › timeOfDay
Time to post, HH:MM (24-hour).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
repeatSchedule › timezone
IANA timezone for timeOfDay. Defaults to the post's timezone, then UTC.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
autoPlugEnabled
Optional (default false). Automatically post a follow-up comment (autoPlugText) once the published post reaches autoPlugThreshold likes.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
autoPlugText
Optional. The follow-up comment text for auto-plug.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
autoPlugThreshold
Optional (default 50). Likes needed before the auto-plug comment is posted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
autoRepostEnabled
Optional (default false). Automatically repost/reshare the post once it reaches autoRepostThreshold likes.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
autoRepostThreshold
Optional (default 100). Likes needed before the post is reposted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "create_post",
"title": "Create post",
"description": "Create a new social media post. Can be saved as a draft or scheduled for a specific time. Supports platform-specific content overrides, media attachments, labels, and thread format. IMPORTANT: YouTube requires a video. TikTok requires a video, or 1 to 35 images with postTypeOverrides.tiktok = \"photo_slideshow\". Do not include either on a text-only post. Instagram defaults to feed_photo — set postTypeOverrides for video content (reel, feed_video). Use this when the user wants to draft or schedule one new post. It never publishes immediately; publish_post does that.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"channels"
],
"properties": {
"labels": {
"type": "array",
"items": {
"type": "number"
},
"description": "Array of label IDs to tag the post with."
},
"status": {
"enum": [
"draft",
"scheduled"
],
"type": "string",
"description": "Post status. \"draft\" (default) or \"scheduled\"."
},
"content": {
"type": "string",
"description": "The post text content. Optional — defaults to empty for media-only posts. LinkedIn mentions: write @[Display Name](urn:li:organization:ID) for a Page or @[Display Name](urn:li:person:ID) for a person; The token publishes as a real mention on LinkedIn and as plain @Display Name on other channels."
},
"channels": {
"type": "array",
"items": {
"type": "object",
"required": [
"channelId",
"platform"
],
"properties": {
"platform": {
"enum": [
"facebook",
"instagram",
"x",
"tiktok",
"youtube",
"threads",
"bluesky",
"pinterest",
"gmb",
"linkedin",
"mastodon",
"discord",
"telegram",
"tumblr",
"snapchat"
],
"type": "string",
"description": "Platform name. One of the supported BulkPublish platforms."
},
"channelId": {
"type": "number",
"description": "Channel ID to post to."
}
}
},
"description": "Array of channels to post to. Get channel IDs from list_channels."
},
"timezone": {
"type": "string",
"description": "Timezone for scheduling (e.g. \"America/New_York\"). Defaults to UTC."
},
"postFormat": {
"enum": [
"post",
"video",
"reel",
"story",
"carousel",
"thread"
],
"type": "string",
"description": "Post format. \"post\" (default), \"video\", \"reel\", \"story\", \"carousel\", or \"thread\" for multi-part threads."
},
"scheduledAt": {
"type": "string",
"description": "ISO 8601 datetime for scheduling (e.g. 2025-01-15T10:00:00Z). Required when status is scheduled."
},
"threadParts": {
"type": "array",
"items": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"description": "Thread part content."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Media files for this thread part."
}
}
},
"description": "Thread parts array. Required when postFormat is thread (min 2 parts). EVERY part is measured against the character limit of every platform the post targets, not only the first — an over-long part is rejected with 400 VALIDATION_ERROR naming the part number, the platform and its limit. URLs count as 23 characters on X and Mastodon, their real length elsewhere."
},
"autoPlugText": {
"type": "string",
"description": "Optional. The follow-up comment text for auto-plug."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Array of media file IDs to attach. Upload media first with upload_media."
},
"repeatSchedule": {
"type": "object",
"required": [
"frequency"
],
"properties": {
"timezone": {
"type": "string",
"description": "IANA timezone for timeOfDay. Defaults to the post's timezone, then UTC."
},
"frequency": {
"enum": [
"daily",
"weekly",
"biweekly",
"monthly"
],
"type": "string",
"description": "How often the post repeats."
},
"timeOfDay": {
"type": "string",
"description": "Time to post, HH:MM (24-hour)."
},
"dayOfMonth": {
"type": "integer",
"maximum": 31,
"minimum": 1,
"description": "Monthly: day of the month."
},
"daysOfWeek": {
"type": "array",
"items": {
"type": "integer",
"maximum": 6,
"minimum": 0
},
"description": "Weekly/biweekly: days to post on, 0=Sunday … 6=Saturday."
}
},
"description": "Optional. Make this a repeating post: it is re-published on this cadence. Media on a repeating post is always kept (deleteMediaAfterPublish is forced to false)."
},
"autoPlugEnabled": {
"type": "boolean",
"description": "Optional (default false). Automatically post a follow-up comment (autoPlugText) once the published post reaches autoPlugThreshold likes."
},
"platformContent": {
"type": "object",
"properties": {
"x": {
"type": "string"
},
"gmb": {
"type": "string"
},
"tiktok": {
"type": "string"
},
"tumblr": {
"type": "string"
},
"bluesky": {
"type": "string"
},
"discord": {
"type": "string"
},
"threads": {
"type": "string"
},
"youtube": {
"type": "string"
},
"facebook": {
"type": "string"
},
"linkedin": {
"type": "string"
},
"mastodon": {
"type": "string"
},
"snapchat": {
"type": "string"
},
"telegram": {
"type": "string"
},
"instagram": {
"type": "string"
},
"pinterest": {
"type": "string"
}
},
"description": "Per-platform content overrides, e.g. { \"x\": \"Short tweet\", \"linkedin\": \"Longer LinkedIn post\" }."
},
"requestApproval": {
"type": "boolean",
"description": "Optional (default false). Set true to hold a scheduled post for team approval (approvalStatus becomes 'pending'). Forced on server-side for API keys of roles without post:publish (contributors), regardless of this flag."
},
"platformSpecific": {
"type": "object",
"properties": {
"x": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"options",
"durationMinutes"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 choices, each 1 to 25 characters."
},
"durationMinutes": {
"type": "number",
"description": "How long the poll stays open, whole minutes from 5 to 10080 (7 days)."
}
},
"description": "Adds a poll. Cannot be combined with media or quoteId. On a thread it goes on the first post."
},
"quoteId": {
"type": "string",
"description": "The post to quote: its numeric ID or its x.com / twitter.com status URL. Cannot be combined with poll. On a thread it applies to the first post."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet)."
},
"communityId": {
"type": "string",
"description": "Posts into an X Community: its numeric ID or its https://x.com/i/communities/<id> URL. The account must be a member."
},
"replySettings": {
"type": "string",
"description": "Who can reply: everyone, following, verified, subscribers or mentionedUsers. Applies to a single post and to the first post of a thread."
},
"shareWithFollowers": {
"type": "boolean",
"description": "With communityId, also shows the post to your followers (default false). Ignored without communityId."
}
},
"additionalProperties": {}
},
"gmb": {
"type": "object",
"properties": {
"ctaUrl": {
"type": "string"
},
"ctaType": {
"type": "string"
},
"endDate": {
"type": "string"
},
"endTime": {
"type": "string"
},
"startDate": {
"type": "string"
},
"startTime": {
"type": "string"
},
"couponCode": {
"type": "string"
},
"eventTitle": {
"type": "string"
},
"redeemOnlineUrl": {
"type": "string"
},
"termsConditions": {
"type": "string"
}
},
"additionalProperties": {}
},
"tiktok": {
"type": "object",
"properties": {
"isAigc": {
"type": "boolean"
},
"disableDuet": {
"type": "boolean"
},
"autoAddMusic": {
"type": "boolean",
"description": "Photo posts published directly only: lets TikTok add a recommended track (default false). Ignored with sendToDrafts."
},
"privacyLevel": {
"type": "string"
},
"sendToDrafts": {
"type": "boolean",
"description": "Send a video or photo_slideshow post to the creator's TikTok drafts instead of publishing it (default false). privacyLevel is then not required, and the direct-post settings (privacyLevel, disableDuet, disableStitch, disableComment, isAigc, brandContentToggle, brandOrganicToggle, autoAddMusic, thumbnailTimestamp) are ignored. A video draft carries no caption; a photo draft sends it. Once delivered the destination becomes published with no platformUrl; if the creator posts it within about a week, platformPostId becomes the video id, platformUrl is filled in and analytics are collected."
},
"disableStitch": {
"type": "boolean"
},
"disableComment": {
"type": "boolean"
},
"photoCoverIndex": {
"type": "number",
"description": "photo_slideshow only: which image is the cover, a whole number 0 to 34 counting from 0 in attachment order (default 0). An index past the last image falls back to the first."
},
"brandContentToggle": {
"type": "boolean"
},
"brandOrganicToggle": {
"type": "boolean"
},
"thumbnailTimestamp": {
"type": "number",
"description": "Cover frame for the video, in seconds from the start."
}
},
"additionalProperties": {}
},
"tumblr": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"link": {
"type": "string",
"description": "Appended as a link block."
},
"slug": {
"type": "string",
"description": "Up to 200 characters; lowercased and hyphenated into the permalink."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tumblr tags, without the leading '#'."
},
"state": {
"enum": [
"published",
"queue",
"draft",
"private"
],
"type": "string",
"description": "Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish."
},
"title": {
"type": "string",
"description": "Rendered as a heading block above the body."
},
"blogName": {
"type": "string",
"description": "Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options)."
},
"reblogUrl": {
"type": "string",
"description": "A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment."
},
"sourceUrl": {
"type": "string",
"description": "Attribution URL stored as the post's source."
},
"reblogInteraction": {
"enum": [
"everyone",
"noone"
],
"type": "string",
"description": "Who can reblog the post."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"link": {
"type": "string",
"description": "Appended as a link block."
},
"slug": {
"type": "string",
"description": "Up to 200 characters; lowercased and hyphenated into the permalink."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tumblr tags, without the leading '#'."
},
"state": {
"enum": [
"published",
"queue",
"draft",
"private"
],
"type": "string",
"description": "Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish."
},
"title": {
"type": "string",
"description": "Rendered as a heading block above the body."
},
"blogName": {
"type": "string",
"description": "Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options)."
},
"reblogUrl": {
"type": "string",
"description": "A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment."
},
"sourceUrl": {
"type": "string",
"description": "Attribution URL stored as the post's source."
},
"reblogInteraction": {
"enum": [
"everyone",
"noone"
],
"type": "string",
"description": "Who can reblog the post."
}
},
"additionalProperties": {}
}
],
"description": "Tumblr options, nested under the BulkPublish channel id: { \"12\": { \"blogName\": \"myblog\", \"tags\": [\"art\"] } } (tags: array of strings or one comma-separated string). A flat object applies to every Tumblr channel on the post. Up to 30 images OR exactly one video per post."
},
"bluesky": {
"type": "object",
"properties": {
"langs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 3 language codes such as 'en' or 'pt-BR'. Applies to every part of a thread."
},
"quoteId": {
"type": "string",
"description": "The post to quote: a bsky.app post link or an at:// URI (a bare ID is read as one of your own posts). Replaces a link card; with media attached both appear together. Publishing fails before anything is posted if the post cannot be found."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost."
},
"replyAllow": {
"type": "array",
"items": {
"enum": [
"nobody",
"mention",
"following",
"follower"
],
"type": "string"
},
"description": "Who can reply. Omitted or [] means everyone; otherwise ['nobody'] or any mix of mention, following, follower ('nobody' cannot be combined). Set right after the post publishes; if Bluesky refuses it the post stays published without it. First post of a thread."
},
"allowQuotes": {
"type": "boolean",
"description": "false stops other accounts quoting the post (default true). Set right after publishing, like replyAllow."
},
"contentLabel": {
"enum": [
"sexual",
"nudity",
"porn",
"graphic-media"
],
"type": "string",
"description": "Adds a content warning. Applies to every part of a thread."
}
},
"additionalProperties": {}
},
"discord": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin the message. If Discord refuses, the post stays published and a warning is recorded. The bot needs the Pin Messages permission."
},
"poll": {
"type": "object",
"required": [
"question",
"answers"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 10 answers, each up to 55 characters."
},
"question": {
"type": "string",
"description": "Up to 300 characters."
},
"multiselect": {
"type": "boolean"
},
"durationHours": {
"type": "number",
"description": "Whole hours 1 to 768 (default 24)."
}
},
"description": "A native poll. The bot needs the Send Polls permission."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 5 forum tag IDs (digits) for a forum channel; IDs come from get_channel_options."
},
"embed": {
"type": "object",
"properties": {
"color": {
"enum": [
"orange",
"blue",
"green",
"red",
"purple",
"gray"
],
"type": "string"
},
"title": {
"type": "string",
"description": "Up to 256 characters."
}
},
"description": "Send the text as a rich embed with the first image inside."
},
"silent": {
"type": "boolean",
"description": "Suppress notifications for the message."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 80 characters."
}
}
},
"description": "Link buttons, up to 5."
},
"channelId": {
"type": "string",
"description": "Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options."
},
"threadName": {
"type": "string",
"description": "Name for that thread, up to 100 characters."
},
"startThread": {
"type": "boolean",
"description": "Start a thread from the message (no effect on a forum channel)."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin the message. If Discord refuses, the post stays published and a warning is recorded. The bot needs the Pin Messages permission."
},
"poll": {
"type": "object",
"required": [
"question",
"answers"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 10 answers, each up to 55 characters."
},
"question": {
"type": "string",
"description": "Up to 300 characters."
},
"multiselect": {
"type": "boolean"
},
"durationHours": {
"type": "number",
"description": "Whole hours 1 to 768 (default 24)."
}
},
"description": "A native poll. The bot needs the Send Polls permission."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 5 forum tag IDs (digits) for a forum channel; IDs come from get_channel_options."
},
"embed": {
"type": "object",
"properties": {
"color": {
"enum": [
"orange",
"blue",
"green",
"red",
"purple",
"gray"
],
"type": "string"
},
"title": {
"type": "string",
"description": "Up to 256 characters."
}
},
"description": "Send the text as a rich embed with the first image inside."
},
"silent": {
"type": "boolean",
"description": "Suppress notifications for the message."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 80 characters."
}
}
},
"description": "Link buttons, up to 5."
},
"channelId": {
"type": "string",
"description": "Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options."
},
"threadName": {
"type": "string",
"description": "Name for that thread, up to 100 characters."
},
"startThread": {
"type": "boolean",
"description": "Start a thread from the message (no effect on a forum channel)."
}
},
"additionalProperties": {}
}
],
"description": "Discord options, nested under the BulkPublish channel id: { \"12\": { \"channelId\": \"1090123456789012345\" } }. A flat object applies to every Discord channel on the post. The inner channelId is the target Discord text channel. Posting uses a global bot token, so failures are permission problems, never a reconnect issue."
},
"threads": {
"type": "object",
"properties": {
"repostId": {
"type": "string",
"description": "With postTypeOverrides.threads = 'repost': the numeric ID of the Threads post to repost (Threads links cannot be used; the ID of a post published through BulkPublish is in get_post's platforms[].platformPostId)."
},
"topicTag": {
"type": "string",
"description": "One topic tag for the post, without a leading '#'. Must not contain periods or ampersands."
},
"locationId": {
"type": "string",
"description": "Numeric place ID from get_channel_options with a `q` search on a Threads channel. Only works once the channel has granted location tagging."
},
"pollOptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 poll choices, each 1 to 25 characters. Text-only posts: on an image, video or carousel post the poll is left out. In a thread it goes on the first part when that part has no media."
},
"quotePostId": {
"type": "string"
},
"replyControl": {
"enum": [
"everyone",
"accounts_you_follow",
"mentioned_only",
"parent_post_author_only",
"followers_only"
],
"type": "string",
"description": "Who can reply (default everyone). parent_post_author_only means only you. Applies to the post itself, never to later replies in a thread; ignored on a repost."
},
"linkAttachment": {
"type": "string",
"description": "An http(s) URL on a public host shown as the preview card on a text post; left out on other post types. Threads refuses a post with more than 5 links in total, and a link here that differs from every link in the text counts as one more."
}
},
"additionalProperties": {}
},
"youtube": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"license": {
"enum": [
"youtube",
"creativeCommon"
],
"type": "string",
"description": "Default youtube; creativeCommon publishes under Creative Commons Attribution."
},
"categoryId": {
"type": "string"
},
"embeddable": {
"type": "boolean",
"description": "false stops other websites embedding the video."
},
"playlistId": {
"type": "string"
},
"madeForKids": {
"type": "boolean"
},
"thumbnailUrl": {
"type": "string"
},
"privacyStatus": {
"enum": [
"public",
"private",
"unlisted"
],
"type": "string"
},
"recordingDate": {
"type": "string",
"description": "YYYY-MM-DD or an ISO 8601 date-time; a plain date is stored as midnight UTC."
},
"defaultLanguage": {
"type": "string",
"description": "Language of the title and description, e.g. 'en', 'pt-BR', 'zh-Hans'."
},
"notifySubscribers": {
"type": "boolean",
"description": "Only an explicit false changes anything: publishes without notifying subscribers."
},
"publicStatsViewable": {
"type": "boolean",
"description": "false hides extended statistics on the watch page."
},
"defaultAudioLanguage": {
"type": "string",
"description": "Language spoken in the video, e.g. 'en'."
},
"containsSyntheticMedia": {
"type": "boolean",
"description": "true discloses realistic altered or synthetic content. Video and short posts."
}
},
"additionalProperties": {}
},
"facebook": {
"type": "object",
"properties": {
"shareToStory": {
"type": "boolean"
},
"thumbnailUrl": {
"type": "string",
"description": "Cover image URL for a video or Reel. Facebook only accepts a cover once the video exists, so it is applied after the video publishes and appears a moment after the post; a cover that cannot be fetched or that Facebook rejects leaves the video published with Facebook's own chosen frame rather than failing the post."
},
"textFormatPresetId": {
"type": "string",
"description": "Digits only (a Facebook background ID). Shows a short text post on a coloured background. Used only on a Page feed post with no photo, video or link card and at most 130 characters; anywhere else it is left out and the post publishes as plain text. If Facebook refuses the background the post is published once more without it."
}
},
"additionalProperties": {}
},
"linkedin": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 answers, each up to 30 characters; blank entries are ignored."
},
"duration": {
"enum": [
"ONE_DAY",
"THREE_DAYS",
"SEVEN_DAYS",
"FOURTEEN_DAYS"
],
"type": "string",
"description": "Default THREE_DAYS."
},
"question": {
"type": "string",
"description": "Up to 140 characters."
}
},
"description": "Required for `poll` posts, which also need post text and take no media."
},
"reshareId": {
"type": "string",
"description": "Required for `reshare` posts: the post's LinkedIn link, or its urn:li:share:<id> / urn:li:ugcPost:<id> ID. Activity links (urn:li:activity:<id>) cannot be reshared."
},
"visibility": {
"enum": [
"PUBLIC",
"CONNECTIONS",
"LOGGED_IN"
],
"type": "string",
"description": "Who can see the post (default PUBLIC). CONNECTIONS applies to personal profiles only; on a Page it is published as PUBLIC."
},
"thumbnailUrl": {
"type": "string",
"description": "Cover for a `post` that carries a video: a public http(s) link to an image of up to 10MB. A cover that cannot be fetched is skipped and LinkedIn picks the frame."
},
"documentTitle": {
"type": "string",
"description": "`document` posts only: the title shown above the document in the feed. Defaults to the file's name."
},
"disableReshare": {
"type": "boolean",
"description": "true stops other members resharing the post (default false)."
}
},
"additionalProperties": {}
},
"mastodon": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"options",
"expiresIn"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 choices, each 1 to 50 characters."
},
"multiple": {
"type": "boolean",
"description": "Voters may pick more than one choice (default false)."
},
"expiresIn": {
"type": "number",
"description": "Seconds the poll stays open, 300 to 2629746."
},
"hideTotals": {
"type": "boolean",
"description": "Hide counts until the poll ends (default false)."
}
},
"description": "Adds a poll. Cannot be combined with media. First post of a thread. A server with tighter limits refuses it at publish time."
},
"quoteId": {
"type": "string",
"description": "The post to quote: its URL, or its status ID on your own server. Needs a server running Mastodon 4.5 or later, otherwise publishing fails and nothing is posted."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost."
},
"sensitive": {
"type": "boolean",
"description": "Hides attached media behind a click (default false). No effect without media. Applies to every part of a thread."
}
},
"additionalProperties": {}
},
"snapchat": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Saved Story title (max 45 chars). Defaults to the first line of the caption, truncated."
},
"locale": {
"type": "string",
"description": "Spotlight locale, e.g. 'en_US'. Defaults to 'en_US'."
},
"saveToProfile": {
"type": "boolean",
"description": "Spotlight only. Default true; false sends skip_save_to_profile to Snap."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Saved Story title (max 45 chars). Defaults to the first line of the caption, truncated."
},
"locale": {
"type": "string",
"description": "Spotlight locale, e.g. 'en_US'. Defaults to 'en_US'."
},
"saveToProfile": {
"type": "boolean",
"description": "Spotlight only. Default true; false sends skip_save_to_profile to Snap."
}
},
"additionalProperties": {}
}
],
"description": "Snapchat options, nested under the BulkPublish channel id: { \"12\": { \"title\": \"My story\" } }. A flat object applies to every Snapchat channel on the post. Post types: story (default), saved_story, spotlight. Every Snapchat post requires exactly ONE image or video (vertical, story videos 5–60s, spotlight 6–60s video-only, saved_story videos not length-checked, max 1GB; a video outside its range is refused when the post is scheduled or published). The caption is NOT sent for plain stories — it is only the Spotlight description (160 chars max) and the Saved Story title fallback. First comments are not supported."
},
"telegram": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin after sending. If the bot lacks the right to pin the post still publishes and a warning is recorded."
},
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"quiz": {
"type": "boolean",
"description": "Default false."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 12 answers, each up to 100 characters."
},
"question": {
"type": "string",
"description": "1 to 300 characters."
},
"anonymous": {
"type": "boolean",
"description": "Default true."
},
"correctOption": {
"type": "number",
"description": "0-based index of the right answer; required when quiz is true."
},
"multipleAnswers": {
"type": "boolean",
"description": "Default false. Cannot be combined with quiz."
}
},
"description": "Sent as a poll after the message."
},
"silent": {
"type": "boolean",
"description": "Send without a notification sound."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 64 characters."
}
}
},
"description": "Link buttons under the message, up to 3."
},
"spoiler": {
"type": "boolean",
"description": "Hides a photo or video behind a spoiler."
},
"threadId": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
],
"description": "Forum topic to post into: digits only, up to 12."
},
"disablePreview": {
"type": "boolean",
"description": "Turns off the link preview."
},
"protectContent": {
"type": "boolean",
"description": "Recipients cannot forward or save the message."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin after sending. If the bot lacks the right to pin the post still publishes and a warning is recorded."
},
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"quiz": {
"type": "boolean",
"description": "Default false."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 12 answers, each up to 100 characters."
},
"question": {
"type": "string",
"description": "1 to 300 characters."
},
"anonymous": {
"type": "boolean",
"description": "Default true."
},
"correctOption": {
"type": "number",
"description": "0-based index of the right answer; required when quiz is true."
},
"multipleAnswers": {
"type": "boolean",
"description": "Default false. Cannot be combined with quiz."
}
},
"description": "Sent as a poll after the message."
},
"silent": {
"type": "boolean",
"description": "Send without a notification sound."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 64 characters."
}
}
},
"description": "Link buttons under the message, up to 3."
},
"spoiler": {
"type": "boolean",
"description": "Hides a photo or video behind a spoiler."
},
"threadId": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
],
"description": "Forum topic to post into: digits only, up to 12."
},
"disablePreview": {
"type": "boolean",
"description": "Turns off the link preview."
},
"protectContent": {
"type": "boolean",
"description": "Recipients cannot forward or save the message."
}
},
"additionalProperties": {}
}
],
"description": "Telegram options, nested under the BulkPublish channel id: { \"12\": { \"silent\": true } }. A flat object applies to every Telegram channel on the post. The destination chat is fixed when the channel is connected. Content is sent as plain text (no markdown). Text over the 1024-char caption limit is posted as a second message alongside captionless media. Attached GIFs, audio and other files are sent as an animation, an audio file or a document according to their type."
},
"instagram": {
"type": "object",
"properties": {
"coverUrl": {
"type": "string",
"description": "Cover image URL for a video or Reel. Takes precedence over thumbnailTimestamp: Instagram accepts one or the other and rejects a request carrying both, so only this one is forwarded when both are sent."
},
"userTags": {
"type": "array",
"items": {
"type": "object",
"required": [
"username"
],
"properties": {
"x": {
"type": "number",
"description": "Position on the photo, 0 to 1 from the left. Give x and y together or not at all."
},
"y": {
"type": "number",
"description": "Position on the photo, 0 to 1 from the top."
},
"username": {
"type": "string",
"description": "A public Instagram username, leading @ optional."
},
"mediaIndex": {
"type": "number",
"description": "Which attached media item the tag belongs to, counting from 0 in attachment order (default 0)."
}
}
},
"description": "People tagged in the post, up to 20 per photo or video. On a photo (and each photo of a carousel) a tag needs x and y or it is left out; on a Reel or video post people are tagged by username only and any position is ignored. Carousel videos and Stories carry no tags."
},
"trialReel": {
"type": "boolean",
"description": "Publish as a trial reel, shown to people who do not follow the account first. Only takes effect with postTypeOverrides.instagram of 'reel' — a 'feed_video' publishes as an ordinary reel and this is ignored, even though both use the same underlying reel container."
},
"locationId": {
"type": "string",
"description": "Digits only: the numeric ID of a Facebook Page that has a location. Applies to photos, videos, Reels and carousels, not Stories. Instagram refuses the post if it does not recognise the ID as a place."
},
"shareToFeed": {
"type": "boolean",
"description": "Reels only. false shows the Reel only in the Reels tab; true also shows it in the main feed. Omitted: Instagram's own default (feed and Reels tab)."
},
"shareToStory": {
"type": "boolean"
},
"collaborators": {
"type": "string",
"description": "Comma-separated Instagram usernames (no leading @) tagged as co-authors. Applies with postTypeOverrides.instagram of 'feed_photo', 'feed_video', 'reel' or 'carousel' — on a carousel the co-authors are set on the carousel itself, not on its individual items. Ignored on 'story', which has no co-author concept."
},
"graduationStrategy": {
"enum": [
"manual",
"auto"
],
"type": "string",
"description": "How a trial reel becomes a normal one: 'manual' (the creator releases it) or 'auto' (released automatically if it performs well). Default 'manual'. Ignored unless trialReel is true."
},
"thumbnailTimestamp": {
"type": "number",
"description": "Cover frame for a video or Reel, in seconds from the start. Applies to postTypeOverrides.instagram of 'feed_video' or 'reel'. Ignored when coverUrl is also set."
}
},
"additionalProperties": {}
},
"pinterest": {
"type": "object",
"properties": {
"link": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"coverImageUrl": {
"type": "string",
"description": "Cover image URL for video pins. Optional — server falls back to an attached image, then the video's auto-extracted poster frame."
},
"dominantColor": {
"type": "string",
"description": "Hex color e.g. #FF5733"
},
"boardSectionId": {
"type": "string",
"description": "Numeric ID of a section of the chosen board (list with get_channel_options and boardId). Send it beside its board, per channel or flat. Pin, video_pin and carousel. A flat value is ignored for a channel with its own boardId, and any section is ignored when no board was chosen."
},
"coverKeyFrameTime": {
"type": "number",
"description": "video_pin only: use the frame at this many seconds (whole number, 0 or more) as the cover. A time past the end uses the last frame; coverImageUrl wins when both are sent."
}
},
"additionalProperties": {}
}
},
"description": "Platform-specific settings, e.g. { \"youtube\": { \"title\": \"…\", \"privacyStatus\": \"public\" } }. Discord, Telegram, Tumblr and Snapchat nest their options under the BulkPublish channel id, e.g. { \"discord\": { \"12\": { \"channelId\": \"1090123456789012345\" } } }. Full per-platform option lists (polls, quotes, tags, drafts, settings) are on each platform key; bad values are refused with 400 VALIDATION_ERROR."
},
"autoPlugThreshold": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Optional (default 50). Likes needed before the auto-plug comment is posted."
},
"autoRepostEnabled": {
"type": "boolean",
"description": "Optional (default false). Automatically repost/reshare the post once it reaches autoRepostThreshold likes."
},
"postTypeOverrides": {
"type": "object",
"properties": {
"x": {
"enum": [
"tweet",
"video",
"thread",
"repost"
],
"type": "string"
},
"gmb": {
"enum": [
"standard",
"event",
"offer"
],
"type": "string"
},
"tiktok": {
"enum": [
"video",
"photo_slideshow"
],
"type": "string"
},
"tumblr": {
"enum": [
"post"
],
"type": "string"
},
"bluesky": {
"enum": [
"post",
"video",
"thread",
"repost"
],
"type": "string"
},
"discord": {
"enum": [
"post"
],
"type": "string"
},
"threads": {
"enum": [
"text",
"image",
"video",
"carousel",
"repost"
],
"type": "string"
},
"youtube": {
"enum": [
"video",
"short"
],
"type": "string"
},
"facebook": {
"enum": [
"post",
"video",
"reel",
"story",
"carousel"
],
"type": "string"
},
"linkedin": {
"enum": [
"post",
"multi_image",
"pdf_carousel",
"article",
"document",
"poll",
"reshare"
],
"type": "string",
"description": "document: one PDF, Word or PowerPoint file from the media library (exactly one document, no images or videos; title from platformSpecific.linkedin.documentTitle). poll: a question with 2-4 answers from platformSpecific.linkedin.poll (needs post text, no media). reshare: shares an existing LinkedIn post from platformSpecific.linkedin.reshareId (post text optional, no media)."
},
"mastodon": {
"enum": [
"post",
"thread",
"repost"
],
"type": "string"
},
"snapchat": {
"enum": [
"story",
"saved_story",
"spotlight"
],
"type": "string",
"description": "story (default): 1 image or video, caption NOT sent. saved_story: 1 image or video with a title. spotlight: video only, 6–60s, caption becomes the description. Story videos must be 5–60s; a video outside its range is refused when the post is scheduled or published. saved_story video length is not checked."
},
"telegram": {
"enum": [
"post"
],
"type": "string"
},
"instagram": {
"enum": [
"feed_photo",
"feed_video",
"reel",
"story",
"carousel"
],
"type": "string"
},
"pinterest": {
"enum": [
"pin",
"video_pin",
"carousel"
],
"type": "string"
}
},
"description": "Per-platform post type override. E.g. { \"instagram\": \"reel\", \"youtube\": \"short\" }. Video length is checked per type when the post is scheduled or published, and a video outside the range is refused: instagram reel/feed_video 3s–15min, story 3–60s; facebook reel 3–90s, story 3–60s; threads video/carousel up to 5min; linkedin 3s–30min; pinterest video_pin at least 4s; snapchat story 5–60s, spotlight 6–60s (saved_story not checked)."
},
"autoRepostThreshold": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Optional (default 100). Likes needed before the post is reposted."
},
"platformThreadParts": {
"type": "object",
"description": "Optional per-platform thread overrides, keyed by platform, e.g. { \"x\": [{ \"content\": \"Part 1\" }, { \"content\": \"Part 2\" }] }. Part content must be a plain string.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "array",
"items": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"description": "Thread part content."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Media files for this thread part."
}
}
}
}
},
"publishWhenApproved": {
"type": "boolean",
"description": "Optional (default false). Set true on a post that waits for approval when it should go out as soon as it is approved, even if that is after its scheduled time. This is how someone who needs approval says 'publish now': status 'scheduled', scheduledAt = now, requestApproval true (or a contributor key), publishWhenApproved true. An approval arriving more than 15 minutes late then publishes immediately; with false it is approved but returned to draft for a new time. Stored only when the post ends up approvalStatus 'pending'; otherwise saved as false."
},
"linkTrackingOverride": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"description": "Optional per-post override for link tracking (bulkpubli.sh). true forces links in this post to be shortened and their clicks counted, false forces them to publish as written, and null/omitted (the default) inherits the organization's Link Tracking setting. Shortening happens at publish time, per channel, so two accounts on the same platform get distinct codes; it is skipped for a channel when the rewrite would push the post past that platform's character limit (a short URL is 28 characters and can be longer than the link it replaces). Short links are part of the Pro and Business plans: on Free, links always publish as written and true has no effect."
},
"deleteMediaAfterPublish": {
"type": "boolean",
"description": "Optional (default false: media is kept in the library). Set true to delete the attached media once every channel has published, so it stops counting toward the storage limit. Forced to false when repeatSchedule is set."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"author": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who wrote the post: { id, name, image }. Null when that account is gone."
},
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "draft, scheduled, processing, published, partial or failed."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"approver": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who approved it: { id, name, image }. Null unless approvalStatus is approved."
},
"assignee": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who is expected to act on it next: { id, name, image }. Null when nobody is."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"mediaFiles": {
"anyOf": [
{
"type": "array",
"items": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "object",
"properties": {},
"additionalProperties": {}
}
]
}
},
{
"type": "null"
}
]
},
"publishedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"scheduledAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"postPlatforms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"platform": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"approvalStatus": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List posts with optional filters for status, search text, date range, channel, and label. Returns paginated results with platform statuses and metrics, ordered newest-first by publishedAt if the post is live, else scheduledAt, else createdAt. Use this when the user wants to browse, filter, or check the status of existing posts as raw data (not the visual dashboard).
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
Filter by post status.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search
Search post content (case-insensitive).
Clear enough to supply this argument.
page
Page number (default 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Results per page (default 20, max 500).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
channelId
Filter by channel ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
labelId
Filter by a single label ID. Prefer labelIds.
Clear enough to supply this argument.
labelIds
Filter by several label IDs (from list_labels). Combined per labelMode.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
labelMode
How labelIds combine: 'or' (default) matches posts with any of them, 'and' only posts with all of them.
Clear enough to supply this argument.
recurring
Set true to return only posts attached to a recurring schedule.
Clear enough to supply this argument.
from
Filter posts created on or after this ISO date.
Clear enough to supply this argument.
to
Filter posts created on or before this ISO date.
Clear enough to supply this argument.
scheduledFrom
Filter posts scheduled on or after this ISO date.
Clear enough to supply this argument.
scheduledTo
Filter posts scheduled on or before this ISO date.
Clear enough to supply this argument.
approvalStatus
Filter by team approval state (e.g. 'pending' for the approval queue).
Clear enough to supply this argument.
assignedTo
Filter by who the post is assigned to: a user id, 'me' for the caller, or 'unassigned'. Orthogonal to status — a post can be scheduled AND assigned.
Clear enough to supply this argument.
order
Direction of the timeline sort (published, else due, else created). 'desc' is the default and returns the most recent first. Use 'asc' to read what is coming NEXT — with a limit, 'desc' returns the posts scheduled furthest out, not the soonest.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get a single post by ID with full details including platform statuses, labels, media files, recurring schedule info, and metrics. For a thread post, `threadParts` holds the parts and `threadMediaFiles` resolves the media they reference: that media is NOT in `mediaFiles`, which carries only the media on the post itself. Use this when the user references one specific post by its ID.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post ID.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Publish a draft or scheduled post immediately. The post will be queued for publishing to all its target channels. Requires a role with post:publish — contributors get 403 APPROVAL_REQUIRED and must submit the post for approval instead (create/update with requestApproval, then a teammate approves). To 'publish now' with approval, create_post with status 'scheduled', scheduledAt = now, requestApproval true and publishWhenApproved true, so it goes out the moment it is approved. Publishing a pending/rejected post as an approver implicitly approves it. Use this when the user wants to publish an existing draft or scheduled post right now.
The description explains the capability, when to use it, and what to expect.
Inputs50/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postId
The post ID to publish.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Retry publishing a failed or partially failed post. Only retries the platforms that failed, not the ones that already succeeded. Platforms in status 'unconfirmed' (the publish request may have reached the platform but its response was lost — the post may already be live) are NOT retried unless republish is true; if the post has unconfirmed platforms and no failed ones, the call fails with a 400 and code UNCONFIRMED_REQUIRES_REPUBLISH — ask the user to check the account on the platform, and only pass republish: true after they confirm the post is not live. Use this when a post failed on some platforms and the user wants to retry just those.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
postId
The post ID to retry.
Clear enough to supply this argument.
republish
Explicit opt-in to also retry platforms in status 'unconfirmed'. Their publish may have already gone through, so this can DUPLICATE the post — only pass true after the user has checked the account and confirmed the post is not live. Defaults to false.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Approve a post awaiting team approval. Requires a role with post:approve (owner, admin, approver). Releases a post with approvalStatus 'pending': it publishes at its scheduled time, or immediately if that time passed less than 15 minutes ago. If the scheduled time passed more than 15 minutes ago, whenLate decides: 'publish' publishes it immediately (status 'publishing'); 'hold' approves it but returns it with status 'draft' (approvalStatus 'approved', scheduledAt unchanged) and the author is notified to choose a new time — tell the user it needs rescheduling. When whenLate is omitted it follows the post's publishWhenApproved: true means 'publish', false means 'hold'. If a late post's publishWhenApproved is false, ask the user whether to publish now or send it back before approving. The author is notified in-app either way. Approving sets publishWhenApproved to false. Pass the updatedAt of the version you showed the user as ifUnmodifiedSince, so an edit made since then is not approved unseen. Errors: 400 if the post is not awaiting approval, whenLate is not 'publish'/'hold' or ifUnmodifiedSince is not a timestamp, 403 if the role lacks post:approve, 404 if not found, 409 if the post changed since you loaded it (checked when ifUnmodifiedSince is sent) or is no longer awaiting approval — reload it with get_post and review again. Use this when the user (an owner/admin/approver) wants to approve a post awaiting team approval.
The description explains the capability, when to use it, and what to expect.
Inputs50/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post ID to approve.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
whenLate
Optional. Only matters when the post's scheduled time passed more than 15 minutes ago: 'publish' = publish now, 'hold' = approve and return it to draft for the author to pick a new time. Defaults to 'publish' when the post's publishWhenApproved is true, otherwise 'hold'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
ifUnmodifiedSince
Optional. The post's updatedAt (ISO 8601) as you last loaded it with get_post. The approval only lands on that version; if the post changed since, nothing is written and the call returns 409.
Resolve the mismatch between this description and its schema constraints.
{
"name": "approve_post",
"title": "Approve pending post",
"description": "Approve a post awaiting team approval. Requires a role with post:approve (owner, admin, approver). Releases a post with approvalStatus 'pending': it publishes at its scheduled time, or immediately if that time passed less than 15 minutes ago. If the scheduled time passed more than 15 minutes ago, whenLate decides: 'publish' publishes it immediately (status 'publishing'); 'hold' approves it but returns it with status 'draft' (approvalStatus 'approved', scheduledAt unchanged) and the author is notified to choose a new time — tell the user it needs rescheduling. When whenLate is omitted it follows the post's publishWhenApproved: true means 'publish', false means 'hold'. If a late post's publishWhenApproved is false, ask the user whether to publish now or send it back before approving. The author is notified in-app either way. Approving sets publishWhenApproved to false. Pass the updatedAt of the version you showed the user as ifUnmodifiedSince, so an edit made since then is not approved unseen. Errors: 400 if the post is not awaiting approval, whenLate is not 'publish'/'hold' or ifUnmodifiedSince is not a timestamp, 403 if the role lacks post:approve, 404 if not found, 409 if the post changed since you loaded it (checked when ifUnmodifiedSince is sent) or is no longer awaiting approval — reload it with get_post and review again. Use this when the user (an owner/admin/approver) wants to approve a post awaiting team approval.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID to approve."
},
"whenLate": {
"enum": [
"publish",
"hold"
],
"type": "string",
"description": "Optional. Only matters when the post's scheduled time passed more than 15 minutes ago: 'publish' = publish now, 'hold' = approve and return it to draft for the author to pick a new time. Defaults to 'publish' when the post's publishWhenApproved is true, otherwise 'hold'."
},
"ifUnmodifiedSince": {
"type": "string",
"description": "Optional. The post's updatedAt (ISO 8601) as you last loaded it with get_post. The approval only lands on that version; if the post changed since, nothing is written and the call returns 409."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"author": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who wrote the post: { id, name, image }. Null when that account is gone."
},
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "draft, scheduled, processing, published, partial or failed."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"approver": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who approved it: { id, name, image }. Null unless approvalStatus is approved."
},
"assignee": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who is expected to act on it next: { id, name, image }. Null when nobody is."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"mediaFiles": {
"anyOf": [
{
"type": "array",
"items": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "object",
"properties": {},
"additionalProperties": {}
}
]
}
},
{
"type": "null"
}
]
},
"publishedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"scheduledAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"postPlatforms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"platform": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"approvalStatus": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Reject a post awaiting team approval. Requires a role with post:approve. The post returns to draft with approvalStatus 'rejected' and the optional reason; the author is notified and can edit + reschedule to resubmit for approval. Rejecting sets publishWhenApproved to false. Pass the updatedAt you reviewed as ifUnmodifiedSince to refuse the rejection if the post changed since. Errors: 400 if the post is not awaiting approval or ifUnmodifiedSince is not a timestamp, 403 if the role lacks post:approve, 404 if not found, 409 if the post changed since you loaded it (checked when ifUnmodifiedSince is sent) or is no longer awaiting approval — reload it with get_post and review again. Use this when the user (an owner/admin/approver) wants to reject a post awaiting team approval, optionally with a reason.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post ID to reject.
Clear enough to supply this argument.
reason
Optional reason (max 2000 chars). Shown to the author (in-app notification + on the post).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
ifUnmodifiedSince
Optional. The post's updatedAt (ISO 8601) as you last loaded it with get_post. If the post changed since, nothing is written and the call returns 409.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Upload a media file (image, video or document) from a URL or local file path. The file is stored in BulkPublish for use in posts. Supported formats: JPEG, PNG, WebP, GIF, MP4, MOV, WebM, and documents (PDF, Word .doc/.docx, PowerPoint .ppt/.pptx). Max 100MB. A document has no thumbnail or preview and can only be published to LinkedIn, as a `document` post. Provide either url OR filePath, not both. Use this when the user provides an image, video or document to attach to a post.
Describe the returned information so the agent knows whether it will answer the request.
Inputs68/100
Explain the meaning of this value, not just its name.
url
Public URL of the media file to upload.
Clear enough to supply this argument.
filePath
Absolute path to a local file to upload (e.g. /Users/me/photo.png).
Clear enough to supply this argument.
filename
Optional filename. If omitted, derived from the URL or file path.
Clear enough to supply this argument.
file › download_url
Temporary download link for the file.
Clear enough to supply this argument.
file › file_id
The file's id.
Explain the meaning of this value, not just its name.
file › mime_type
The file's type, when known.
Explain the meaning of this value, not just its name.
{
"name": "upload_media",
"title": "Upload media",
"description": "Upload a media file (image, video or document) from a URL or local file path. The file is stored in BulkPublish for use in posts. Supported formats: JPEG, PNG, WebP, GIF, MP4, MOV, WebM, and documents (PDF, Word .doc/.docx, PowerPoint .ppt/.pptx). Max 100MB. A document has no thumbnail or preview and can only be published to LinkedIn, as a `document` post. Provide either url OR filePath, not both. Use this when the user provides an image, video or document to attach to a post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"url": {
"type": "string",
"description": "Public URL of the media file to upload."
},
"file": {
"type": "object",
"required": [
"download_url",
"file_id"
],
"properties": {
"file_id": {
"type": "string",
"description": "The file's id."
},
"file_name": {
"type": "string",
"description": "The file's name, when known."
},
"mime_type": {
"type": "string",
"description": "The file's type, when known."
},
"download_url": {
"type": "string",
"description": "Temporary download link for the file."
}
},
"description": "A file provided by the chat host. Leave unset and use url otherwise."
},
"filePath": {
"type": "string",
"description": "Absolute path to a local file to upload (e.g. /Users/me/photo.png)."
},
"filename": {
"type": "string",
"description": "Optional filename. If omitted, derived from the URL or file path."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"file": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"filename": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"mimeType": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"sizeBytes": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List uploaded media files with optional search and pagination. Returns file metadata including URLs, dimensions, and labels. Use this when the user wants a list of their uploaded media files.
The description explains the capability, when to use it, and what to expect.
Inputs81/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search
Search by filename.
Clear enough to supply this argument.
page
Page number (default 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Results per page (default 20, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
type
Filter by media kind: image, video or document (PDF, Word and PowerPoint files). Omit for all files. The response's `total` counts matches across all pages.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get an analytics summary for a date range. Returns total posts, status breakdown (published, failed, scheduled), per-platform stats, and daily post counts. Optional filters narrow every figure to matching posts; `compare` adds the equal-length previous window under `previous` (available for windows of 15 days or fewer — the 30-day statistics-retention cap applies). Use this when the user asks how their content performed overall, across channels and over a date range.
The description explains the capability, when to use it, and what to expect.
Inputs78/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
from
Start date in ISO format (e.g. 2025-01-01).
Clear enough to supply this argument.
to
End date in ISO format (e.g. 2025-01-31).
Clear enough to supply this argument.
channelIds
Comma-separated channel ids to include, e.g. "12,15".
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
platforms
Comma-separated platform keys to include, e.g. "x,linkedin".
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
labelIds
Comma-separated label ids; a post matches when it carries ANY of them.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postFormat
Only single posts or only threads.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
mediaType
By the post's first media file: text (no media), image or video.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
compare
Also return the previous equal-length window as `previous` / `previousWindow`.
Clear enough to supply this argument.
tz
IANA timezone (e.g. "Asia/Karachi") that sets where each day starts and ends and how daily counts are grouped. Defaults to UTC; pass the user's zone so 'today' and daily figures match their calendar.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
List the labels available for tagging posts and media, sorted by name. Returns at most 500 (the first 500 alphabetically). Use this when the user wants their post labels/tags.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
type
Filter by label type: "post" or "media". Returns all if omitted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Update an existing post. Can change content, schedule, media, labels, status, target channels, per-platform text, thread parts, assignee, recurring schedule, and platform-specific settings. Only draft, scheduled, failed, or partial posts can be edited; editing a failed post resets it to draft, a partial post stays partial. Set status to 'draft' or 'scheduled' to move the post between those states — scheduling a partial post re-queues only its failed channels; use publish_post to publish immediately. To add or remove a channel, send `channels` with the COMPLETE list the post should keep (read it from get_post first): channels left out are dropped from the post, new ones are added as pending, and the ones kept keep their publish state. Use this when the user wants to edit an existing post.
The description explains the capability, when to use it, and what to expect.
Inputs55/100
159 of 220 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
postId
The post ID to update.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
content
New post text content.
Clear enough to supply this argument.
channels › items › channelId
Channel ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
channels › items › platform
The channel's platform.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformContent › facebook
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › instagram
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › x
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › tiktok
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › youtube
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › threads
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › bluesky
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › pinterest
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › linkedin
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › mastodon
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › gmb
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › discord
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › telegram
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › tumblr
Not provided
Missing description. Explain what this value means and how to supply it.
platformContent › snapchat
Not provided
Missing description. Explain what this value means and how to supply it.
postFormat
Optional. 'thread' to turn the post into a multi-part thread (send threadParts too), 'post' for a single post.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
threadParts › items › content
Thread part content.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
threadParts › items › mediaFileIds
Media files for this thread part.
Clear enough to supply this argument.
assignedUserId
Optional. The member expected to act on this post next (a user id from the organization), or null to unassign. Omit to leave the assignment unchanged.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
recurringScheduleId
Optional. Attach the post to a recurring schedule by id, or null to detach it. Omit to leave it unchanged.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
Move the post between draft and scheduled. 'scheduled' requires a future scheduledAt (in this call or already stored) and at least one channel; 'draft' unschedules it. Any other value is rejected. Omit to leave the status unchanged. To publish immediately, use publish_post instead.
Clear enough to supply this argument.
scheduledAt
New ISO 8601 scheduled datetime.
Clear enough to supply this argument.
timezone
Timezone for scheduling.
Clear enough to supply this argument.
mediaFileIds
Replace attached media file IDs.
Clear enough to supply this argument.
labelIds
Replace label IDs on the post.
Clear enough to supply this argument.
postTypeOverrides › instagram
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › facebook
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › x
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › tiktok
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › youtube
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › threads
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › bluesky
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › linkedin
document: one PDF, Word or PowerPoint file from the media library (exactly one document, no images or videos; title from platformSpecific.linkedin.documentTitle). poll: a question with 2-4 answers from platformSpecific.linkedin.poll (needs post text, no media). reshare: shares an existing LinkedIn post from platformSpecific.linkedin.reshareId (post text optional, no media).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postTypeOverrides › pinterest
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › gmb
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › mastodon
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › discord
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › telegram
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › tumblr
Not provided
Missing description. Explain what this value means and how to supply it.
postTypeOverrides › snapchat
story (default): 1 image or video, caption NOT sent. saved_story: 1 image or video with a title. spotlight: video only, 6–60s, caption becomes the description. Story videos must be 5–60s; a video outside its range is refused when the post is scheduled or published. saved_story video length is not checked.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › title
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › privacyStatus
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › categoryId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › madeForKids
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › playlistId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › youtube › thumbnailUrl
Not provided
Missing description. Explain what this value means and how to supply it.
true discloses realistic altered or synthetic content. Video and short posts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › notifySubscribers
Only an explicit false changes anything: publishes without notifying subscribers.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › license
Default youtube; creativeCommon publishes under Creative Commons Attribution.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › embeddable
false stops other websites embedding the video.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › publicStatsViewable
false hides extended statistics on the watch page.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › defaultLanguage
Language of the title and description, e.g. 'en', 'pt-BR', 'zh-Hans'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › defaultAudioLanguage
Language spoken in the video, e.g. 'en'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › youtube › recordingDate
YYYY-MM-DD or an ISO 8601 date-time; a plain date is stored as midnight UTC.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › title
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › description
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › link
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › pinterest › dominantColor
Hex color e.g. #FF5733
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › coverImageUrl
Cover image URL for video pins. Optional — server falls back to an attached image, then the video's auto-extracted poster frame.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › boardSectionId
Numeric ID of a section of the chosen board (list with get_channel_options and boardId). Send it beside its board, per channel or flat. Pin, video_pin and carousel. A flat value is ignored for a channel with its own boardId, and any section is ignored when no board was chosen.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › pinterest › coverKeyFrameTime
video_pin only: use the frame at this many seconds (whole number, 0 or more) as the cover. A time past the end uses the last frame; coverImageUrl wins when both are sent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › gmb › ctaType
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › ctaUrl
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › eventTitle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › startDate
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › startTime
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › endDate
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › endTime
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › couponCode
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › redeemOnlineUrl
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › gmb › termsConditions
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › privacyLevel
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableDuet
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableStitch
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › disableComment
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › isAigc
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › brandContentToggle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › brandOrganicToggle
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › tiktok › thumbnailTimestamp
Cover frame for the video, in seconds from the start.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tiktok › sendToDrafts
Send a video or photo_slideshow post to the creator's TikTok drafts instead of publishing it (default false). privacyLevel is then not required, and the direct-post settings (privacyLevel, disableDuet, disableStitch, disableComment, isAigc, brandContentToggle, brandOrganicToggle, autoAddMusic, thumbnailTimestamp) are ignored. A video draft carries no caption; a photo draft sends it. Once delivered the destination becomes published with no platformUrl; if the creator posts it within about a week, platformPostId becomes the video id, platformUrl is filled in and analytics are collected.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tiktok › photoCoverIndex
photo_slideshow only: which image is the cover, a whole number 0 to 34 counting from 0 in attachment order (default 0). An index past the last image falls back to the first.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tiktok › autoAddMusic
Photo posts published directly only: lets TikTok add a recommended track (default false). Ignored with sendToDrafts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › replySettings
Who can reply: everyone, following, verified, subscribers or mentionedUsers. Applies to a single post and to the first post of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › repostId
With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › poll › options
2 to 4 choices, each 1 to 25 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › poll › durationMinutes
How long the poll stays open, whole minutes from 5 to 10080 (7 days).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › quoteId
The post to quote: its numeric ID or its x.com / twitter.com status URL. Cannot be combined with poll. On a thread it applies to the first post.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › communityId
Posts into an X Community: its numeric ID or its https://x.com/i/communities/<id> URL. The account must be a member.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › x › shareWithFollowers
With communityId, also shows the post to your followers (default false). Ignored without communityId.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › facebook › shareToStory
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › facebook › textFormatPresetId
Digits only (a Facebook background ID). Shows a short text post on a coloured background. Used only on a Page feed post with no photo, video or link card and at most 130 characters; anywhere else it is left out and the post publishes as plain text. If Facebook refuses the background the post is published once more without it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › facebook › thumbnailUrl
Cover image URL for a video or Reel. Facebook only accepts a cover once the video exists, so it is applied after the video publishes and appears a moment after the post; a cover that cannot be fetched or that Facebook rejects leaves the video published with Facebook's own chosen frame rather than failing the post.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › collaborators
Comma-separated Instagram usernames (no leading @) tagged as co-authors. Applies with postTypeOverrides.instagram of 'feed_photo', 'feed_video', 'reel' or 'carousel' — on a carousel the co-authors are set on the carousel itself, not on its individual items. Ignored on 'story', which has no co-author concept.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › shareToStory
Not provided
Missing description. Explain what this value means and how to supply it.
Which attached media item the tag belongs to, counting from 0 in attachment order (default 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › shareToFeed
Reels only. false shows the Reel only in the Reels tab; true also shows it in the main feed. Omitted: Instagram's own default (feed and Reels tab).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › locationId
Digits only: the numeric ID of a Facebook Page that has a location. Applies to photos, videos, Reels and carousels, not Stories. Instagram refuses the post if it does not recognise the ID as a place.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › trialReel
Publish as a trial reel, shown to people who do not follow the account first. Only takes effect with postTypeOverrides.instagram of 'reel' — a 'feed_video' publishes as an ordinary reel and this is ignored, even though both use the same underlying reel container.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › graduationStrategy
How a trial reel becomes a normal one: 'manual' (the creator releases it) or 'auto' (released automatically if it performs well). Default 'manual'. Ignored unless trialReel is true.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › thumbnailTimestamp
Cover frame for a video or Reel, in seconds from the start. Applies to postTypeOverrides.instagram of 'feed_video' or 'reel'. Ignored when coverUrl is also set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › instagram › coverUrl
Cover image URL for a video or Reel. Takes precedence over thumbnailTimestamp: Instagram accepts one or the other and rejects a request carrying both, so only this one is forwarded when both are sent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › quotePostId
Not provided
Missing description. Explain what this value means and how to supply it.
platformSpecific › threads › repostId
With postTypeOverrides.threads = 'repost': the numeric ID of the Threads post to repost (Threads links cannot be used; the ID of a post published through BulkPublish is in get_post's platforms[].platformPostId).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › topicTag
One topic tag for the post, without a leading '#'. Must not contain periods or ampersands.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › locationId
Numeric place ID from get_channel_options with a `q` search on a Threads channel. Only works once the channel has granted location tagging.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › replyControl
Who can reply (default everyone). parent_post_author_only means only you. Applies to the post itself, never to later replies in a thread; ignored on a repost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › pollOptions
2 to 4 poll choices, each 1 to 25 characters. Text-only posts: on an image, video or carousel post the poll is left out. In a thread it goes on the first part when that part has no media.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › threads › linkAttachment
An http(s) URL on a public host shown as the preview card on a text post; left out on other post types. Threads refuses a post with more than 5 links in total, and a link here that differs from every link in the text counts as one more.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › documentTitle
`document` posts only: the title shown above the document in the feed. Defaults to the file's name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › question
Up to 140 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › options
2 to 4 answers, each up to 30 characters; blank entries are ignored.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › poll › duration
Default THREE_DAYS.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › reshareId
Required for `reshare` posts: the post's LinkedIn link, or its urn:li:share:<id> / urn:li:ugcPost:<id> ID. Activity links (urn:li:activity:<id>) cannot be reshared.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › thumbnailUrl
Cover for a `post` that carries a video: a public http(s) link to an image of up to 10MB. A cover that cannot be fetched is skipped and LinkedIn picks the frame.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › visibility
Who can see the post (default PUBLIC). CONNECTIONS applies to personal profiles only; on a Page it is published as PUBLIC.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › linkedin › disableReshare
true stops other members resharing the post (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › repostId
With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › replyAllow
Who can reply. Omitted or [] means everyone; otherwise ['nobody'] or any mix of mention, following, follower ('nobody' cannot be combined). Set right after the post publishes; if Bluesky refuses it the post stays published without it. First post of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › allowQuotes
false stops other accounts quoting the post (default true). Set right after publishing, like replyAllow.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › quoteId
The post to quote: a bsky.app post link or an at:// URI (a bare ID is read as one of your own posts). Replaces a link card; with media attached both appear together. Publishing fails before anything is posted if the post cannot be found.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › langs
Up to 3 language codes such as 'en' or 'pt-BR'. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › bluesky › contentLabel
Adds a content warning. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › repostId
With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › options
2 to 4 choices, each 1 to 50 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › expiresIn
Seconds the poll stays open, 300 to 2629746.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › multiple
Voters may pick more than one choice (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › poll › hideTotals
Hide counts until the poll ends (default false).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › sensitive
Hides attached media behind a click (default false). No effect without media. Applies to every part of a thread.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › mastodon › quoteId
The post to quote: its URL, or its status ID on your own server. Needs a server running Mastodon 4.5 or later, otherwise publishing fails and nothing is posted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › discord › anyOf › 1 › silent
Suppress notifications for the message.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › blogName
Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › title
Rendered as a heading block above the body.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › tags
Tumblr tags, without the leading '#'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › link
Appended as a link block.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › sourceUrl
Attribution URL stored as the post's source.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › state
Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platformSpecific › tumblr › anyOf › 1 › slug
Up to 200 characters; lowercased and hyphenated into the permalink.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Spotlight only. Default true; false sends skip_save_to_profile to Snap.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
requestApproval
Optional (default false). Set true to hold a scheduled post for team approval (approvalStatus becomes 'pending'). Forced on server-side for API keys of roles without post:publish (contributors), regardless of this flag.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
publishWhenApproved
Optional. Set true to have the post go out as soon as it is approved, even after its scheduled time (see create_post). An explicit value is stored while the post waits for approval. Omitted, it is kept, except that sending a different scheduledAt clears it to false, and it is always false once the post is no longer approvalStatus 'pending'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
linkTrackingOverride
Optional per-post override for link tracking (bulkpubli.sh). true forces links in this post to be shortened and their clicks counted, false forces them to publish as written, and null clears the override so the post inherits the organization's Link Tracking setting again. Omit to leave it unchanged.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
ifUnmodifiedSince
Optional precondition: the post's updatedAt exactly as the last read returned it. The update is refused with 409 CONFLICT if a teammate has changed the post since, rather than overwriting their version. Pass it whenever you read a post before editing it; omit it to keep the previous last-write-wins behaviour.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "update_post",
"title": "Update post",
"description": "Update an existing post. Can change content, schedule, media, labels, status, target channels, per-platform text, thread parts, assignee, recurring schedule, and platform-specific settings. Only draft, scheduled, failed, or partial posts can be edited; editing a failed post resets it to draft, a partial post stays partial. Set status to 'draft' or 'scheduled' to move the post between those states — scheduling a partial post re-queues only its failed channels; use publish_post to publish immediately. To add or remove a channel, send `channels` with the COMPLETE list the post should keep (read it from get_post first): channels left out are dropped from the post, new ones are added as pending, and the ones kept keep their publish state. Use this when the user wants to edit an existing post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID to update."
},
"status": {
"enum": [
"draft",
"scheduled"
],
"type": "string",
"description": "Move the post between draft and scheduled. 'scheduled' requires a future scheduledAt (in this call or already stored) and at least one channel; 'draft' unschedules it. Any other value is rejected. Omit to leave the status unchanged. To publish immediately, use publish_post instead."
},
"content": {
"type": "string",
"description": "New post text content."
},
"channels": {
"type": "array",
"items": {
"type": "object",
"required": [
"channelId",
"platform"
],
"properties": {
"platform": {
"enum": [
"facebook",
"instagram",
"x",
"tiktok",
"youtube",
"threads",
"bluesky",
"pinterest",
"gmb",
"linkedin",
"mastodon",
"discord",
"telegram",
"tumblr",
"snapchat"
],
"type": "string",
"description": "The channel's platform."
},
"channelId": {
"type": "number",
"description": "Channel ID."
}
}
},
"minItems": 1,
"description": "Optional. The FULL list of channels the post should target after this update — not a diff, and at least one. Channels already on the post that you include keep their state (a published one is not re-published); channels you leave out are removed; new ones are added as pending. A channel the post has already gone out on must stay in the list: leaving it out is refused with CHANNEL_ALREADY_PUBLISHED and nothing is saved. Omit to leave the channels unchanged."
},
"labelIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Replace label IDs on the post."
},
"timezone": {
"type": "string",
"description": "Timezone for scheduling."
},
"postFormat": {
"enum": [
"post",
"thread"
],
"type": "string",
"description": "Optional. 'thread' to turn the post into a multi-part thread (send threadParts too), 'post' for a single post."
},
"scheduledAt": {
"type": "string",
"description": "New ISO 8601 scheduled datetime."
},
"threadParts": {
"type": "array",
"items": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"description": "Thread part content."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Media files for this thread part."
}
}
},
"description": "Optional. Replace the thread parts (at least 2 when postFormat is thread). Every part is measured against the character limit of every platform the post targets; an over-long part is rejected naming the part, platform and limit."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Replace attached media file IDs."
},
"assignedUserId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Optional. The member expected to act on this post next (a user id from the organization), or null to unassign. Omit to leave the assignment unchanged."
},
"platformContent": {
"type": "object",
"properties": {
"x": {
"type": "string"
},
"gmb": {
"type": "string"
},
"tiktok": {
"type": "string"
},
"tumblr": {
"type": "string"
},
"bluesky": {
"type": "string"
},
"discord": {
"type": "string"
},
"threads": {
"type": "string"
},
"youtube": {
"type": "string"
},
"facebook": {
"type": "string"
},
"linkedin": {
"type": "string"
},
"mastodon": {
"type": "string"
},
"snapchat": {
"type": "string"
},
"telegram": {
"type": "string"
},
"instagram": {
"type": "string"
},
"pinterest": {
"type": "string"
}
},
"description": "Optional per-platform text overrides, keyed by platform. Replaced wholesale, not merged: send every platform's override you want to keep, or omit to leave them unchanged."
},
"requestApproval": {
"type": "boolean",
"description": "Optional (default false). Set true to hold a scheduled post for team approval (approvalStatus becomes 'pending'). Forced on server-side for API keys of roles without post:publish (contributors), regardless of this flag."
},
"platformSpecific": {
"type": "object",
"properties": {
"x": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"options",
"durationMinutes"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 choices, each 1 to 25 characters."
},
"durationMinutes": {
"type": "number",
"description": "How long the poll stays open, whole minutes from 5 to 10080 (7 days)."
}
},
"description": "Adds a poll. Cannot be combined with media or quoteId. On a thread it goes on the first post."
},
"quoteId": {
"type": "string",
"description": "The post to quote: its numeric ID or its x.com / twitter.com status URL. Cannot be combined with poll. On a thread it applies to the first post."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet)."
},
"communityId": {
"type": "string",
"description": "Posts into an X Community: its numeric ID or its https://x.com/i/communities/<id> URL. The account must be a member."
},
"replySettings": {
"type": "string",
"description": "Who can reply: everyone, following, verified, subscribers or mentionedUsers. Applies to a single post and to the first post of a thread."
},
"shareWithFollowers": {
"type": "boolean",
"description": "With communityId, also shows the post to your followers (default false). Ignored without communityId."
}
},
"additionalProperties": {}
},
"gmb": {
"type": "object",
"properties": {
"ctaUrl": {
"type": "string"
},
"ctaType": {
"type": "string"
},
"endDate": {
"type": "string"
},
"endTime": {
"type": "string"
},
"startDate": {
"type": "string"
},
"startTime": {
"type": "string"
},
"couponCode": {
"type": "string"
},
"eventTitle": {
"type": "string"
},
"redeemOnlineUrl": {
"type": "string"
},
"termsConditions": {
"type": "string"
}
},
"additionalProperties": {}
},
"tiktok": {
"type": "object",
"properties": {
"isAigc": {
"type": "boolean"
},
"disableDuet": {
"type": "boolean"
},
"autoAddMusic": {
"type": "boolean",
"description": "Photo posts published directly only: lets TikTok add a recommended track (default false). Ignored with sendToDrafts."
},
"privacyLevel": {
"type": "string"
},
"sendToDrafts": {
"type": "boolean",
"description": "Send a video or photo_slideshow post to the creator's TikTok drafts instead of publishing it (default false). privacyLevel is then not required, and the direct-post settings (privacyLevel, disableDuet, disableStitch, disableComment, isAigc, brandContentToggle, brandOrganicToggle, autoAddMusic, thumbnailTimestamp) are ignored. A video draft carries no caption; a photo draft sends it. Once delivered the destination becomes published with no platformUrl; if the creator posts it within about a week, platformPostId becomes the video id, platformUrl is filled in and analytics are collected."
},
"disableStitch": {
"type": "boolean"
},
"disableComment": {
"type": "boolean"
},
"photoCoverIndex": {
"type": "number",
"description": "photo_slideshow only: which image is the cover, a whole number 0 to 34 counting from 0 in attachment order (default 0). An index past the last image falls back to the first."
},
"brandContentToggle": {
"type": "boolean"
},
"brandOrganicToggle": {
"type": "boolean"
},
"thumbnailTimestamp": {
"type": "number",
"description": "Cover frame for the video, in seconds from the start."
}
},
"additionalProperties": {}
},
"tumblr": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"link": {
"type": "string",
"description": "Appended as a link block."
},
"slug": {
"type": "string",
"description": "Up to 200 characters; lowercased and hyphenated into the permalink."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tumblr tags, without the leading '#'."
},
"state": {
"enum": [
"published",
"queue",
"draft",
"private"
],
"type": "string",
"description": "Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish."
},
"title": {
"type": "string",
"description": "Rendered as a heading block above the body."
},
"blogName": {
"type": "string",
"description": "Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options)."
},
"reblogUrl": {
"type": "string",
"description": "A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment."
},
"sourceUrl": {
"type": "string",
"description": "Attribution URL stored as the post's source."
},
"reblogInteraction": {
"enum": [
"everyone",
"noone"
],
"type": "string",
"description": "Who can reblog the post."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"link": {
"type": "string",
"description": "Appended as a link block."
},
"slug": {
"type": "string",
"description": "Up to 200 characters; lowercased and hyphenated into the permalink."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tumblr tags, without the leading '#'."
},
"state": {
"enum": [
"published",
"queue",
"draft",
"private"
],
"type": "string",
"description": "Default published. A scheduled post with published still goes out at its time; draft and private override that and the post is never made public by BulkPublish."
},
"title": {
"type": "string",
"description": "Rendered as a heading block above the body."
},
"blogName": {
"type": "string",
"description": "Which blog to publish to. Defaults to the blog the channel was connected as (list via get_channel_options)."
},
"reblogUrl": {
"type": "string",
"description": "A Tumblr post link (tumblr.com/<blog>/<id> or <blog>.tumblr.com/post/<id>): publishes a reblog of that post with your text as the comment."
},
"sourceUrl": {
"type": "string",
"description": "Attribution URL stored as the post's source."
},
"reblogInteraction": {
"enum": [
"everyone",
"noone"
],
"type": "string",
"description": "Who can reblog the post."
}
},
"additionalProperties": {}
}
],
"description": "Tumblr options, nested under the BulkPublish channel id: { \"12\": { \"blogName\": \"myblog\", \"tags\": [\"art\"] } } (tags: array of strings or one comma-separated string). A flat object applies to every Tumblr channel on the post. Up to 30 images OR exactly one video per post."
},
"bluesky": {
"type": "object",
"properties": {
"langs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 3 language codes such as 'en' or 'pt-BR'. Applies to every part of a thread."
},
"quoteId": {
"type": "string",
"description": "The post to quote: a bsky.app post link or an at:// URI (a bare ID is read as one of your own posts). Replaces a link card; with media attached both appear together. Publishing fails before anything is posted if the post cannot be found."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost."
},
"replyAllow": {
"type": "array",
"items": {
"enum": [
"nobody",
"mention",
"following",
"follower"
],
"type": "string"
},
"description": "Who can reply. Omitted or [] means everyone; otherwise ['nobody'] or any mix of mention, following, follower ('nobody' cannot be combined). Set right after the post publishes; if Bluesky refuses it the post stays published without it. First post of a thread."
},
"allowQuotes": {
"type": "boolean",
"description": "false stops other accounts quoting the post (default true). Set right after publishing, like replyAllow."
},
"contentLabel": {
"enum": [
"sexual",
"nudity",
"porn",
"graphic-media"
],
"type": "string",
"description": "Adds a content warning. Applies to every part of a thread."
}
},
"additionalProperties": {}
},
"discord": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin the message. If Discord refuses, the post stays published and a warning is recorded. The bot needs the Pin Messages permission."
},
"poll": {
"type": "object",
"required": [
"question",
"answers"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 10 answers, each up to 55 characters."
},
"question": {
"type": "string",
"description": "Up to 300 characters."
},
"multiselect": {
"type": "boolean"
},
"durationHours": {
"type": "number",
"description": "Whole hours 1 to 768 (default 24)."
}
},
"description": "A native poll. The bot needs the Send Polls permission."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 5 forum tag IDs (digits) for a forum channel; IDs come from get_channel_options."
},
"embed": {
"type": "object",
"properties": {
"color": {
"enum": [
"orange",
"blue",
"green",
"red",
"purple",
"gray"
],
"type": "string"
},
"title": {
"type": "string",
"description": "Up to 256 characters."
}
},
"description": "Send the text as a rich embed with the first image inside."
},
"silent": {
"type": "boolean",
"description": "Suppress notifications for the message."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 80 characters."
}
}
},
"description": "Link buttons, up to 5."
},
"channelId": {
"type": "string",
"description": "Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options."
},
"threadName": {
"type": "string",
"description": "Name for that thread, up to 100 characters."
},
"startThread": {
"type": "boolean",
"description": "Start a thread from the message (no effect on a forum channel)."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin the message. If Discord refuses, the post stays published and a warning is recorded. The bot needs the Pin Messages permission."
},
"poll": {
"type": "object",
"required": [
"question",
"answers"
],
"properties": {
"answers": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 10 answers, each up to 55 characters."
},
"question": {
"type": "string",
"description": "Up to 300 characters."
},
"multiselect": {
"type": "boolean"
},
"durationHours": {
"type": "number",
"description": "Whole hours 1 to 768 (default 24)."
}
},
"description": "A native poll. The bot needs the Send Polls permission."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Up to 5 forum tag IDs (digits) for a forum channel; IDs come from get_channel_options."
},
"embed": {
"type": "object",
"properties": {
"color": {
"enum": [
"orange",
"blue",
"green",
"red",
"purple",
"gray"
],
"type": "string"
},
"title": {
"type": "string",
"description": "Up to 256 characters."
}
},
"description": "Send the text as a rich embed with the first image inside."
},
"silent": {
"type": "boolean",
"description": "Suppress notifications for the message."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 80 characters."
}
}
},
"description": "Link buttons, up to 5."
},
"channelId": {
"type": "string",
"description": "Required. Target Discord text channel id (a snowflake) inside the connected server. NOT the BulkPublish channel id used as the outer key. List postable channels via get_channel_options."
},
"threadName": {
"type": "string",
"description": "Name for that thread, up to 100 characters."
},
"startThread": {
"type": "boolean",
"description": "Start a thread from the message (no effect on a forum channel)."
}
},
"additionalProperties": {}
}
],
"description": "Discord options, nested under the BulkPublish channel id: { \"12\": { \"channelId\": \"1090123456789012345\" } }. A flat object applies to every Discord channel on the post. The inner channelId is the target Discord text channel. Posting uses a global bot token, so failures are permission problems, never a reconnect issue."
},
"threads": {
"type": "object",
"properties": {
"repostId": {
"type": "string",
"description": "With postTypeOverrides.threads = 'repost': the numeric ID of the Threads post to repost (Threads links cannot be used; the ID of a post published through BulkPublish is in get_post's platforms[].platformPostId)."
},
"topicTag": {
"type": "string",
"description": "One topic tag for the post, without a leading '#'. Must not contain periods or ampersands."
},
"locationId": {
"type": "string",
"description": "Numeric place ID from get_channel_options with a `q` search on a Threads channel. Only works once the channel has granted location tagging."
},
"pollOptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 poll choices, each 1 to 25 characters. Text-only posts: on an image, video or carousel post the poll is left out. In a thread it goes on the first part when that part has no media."
},
"quotePostId": {
"type": "string"
},
"replyControl": {
"enum": [
"everyone",
"accounts_you_follow",
"mentioned_only",
"parent_post_author_only",
"followers_only"
],
"type": "string",
"description": "Who can reply (default everyone). parent_post_author_only means only you. Applies to the post itself, never to later replies in a thread; ignored on a repost."
},
"linkAttachment": {
"type": "string",
"description": "An http(s) URL on a public host shown as the preview card on a text post; left out on other post types. Threads refuses a post with more than 5 links in total, and a link here that differs from every link in the text counts as one more."
}
},
"additionalProperties": {}
},
"youtube": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"license": {
"enum": [
"youtube",
"creativeCommon"
],
"type": "string",
"description": "Default youtube; creativeCommon publishes under Creative Commons Attribution."
},
"categoryId": {
"type": "string"
},
"embeddable": {
"type": "boolean",
"description": "false stops other websites embedding the video."
},
"playlistId": {
"type": "string"
},
"madeForKids": {
"type": "boolean"
},
"thumbnailUrl": {
"type": "string"
},
"privacyStatus": {
"enum": [
"public",
"private",
"unlisted"
],
"type": "string"
},
"recordingDate": {
"type": "string",
"description": "YYYY-MM-DD or an ISO 8601 date-time; a plain date is stored as midnight UTC."
},
"defaultLanguage": {
"type": "string",
"description": "Language of the title and description, e.g. 'en', 'pt-BR', 'zh-Hans'."
},
"notifySubscribers": {
"type": "boolean",
"description": "Only an explicit false changes anything: publishes without notifying subscribers."
},
"publicStatsViewable": {
"type": "boolean",
"description": "false hides extended statistics on the watch page."
},
"defaultAudioLanguage": {
"type": "string",
"description": "Language spoken in the video, e.g. 'en'."
},
"containsSyntheticMedia": {
"type": "boolean",
"description": "true discloses realistic altered or synthetic content. Video and short posts."
}
},
"additionalProperties": {}
},
"facebook": {
"type": "object",
"properties": {
"shareToStory": {
"type": "boolean"
},
"thumbnailUrl": {
"type": "string",
"description": "Cover image URL for a video or Reel. Facebook only accepts a cover once the video exists, so it is applied after the video publishes and appears a moment after the post; a cover that cannot be fetched or that Facebook rejects leaves the video published with Facebook's own chosen frame rather than failing the post."
},
"textFormatPresetId": {
"type": "string",
"description": "Digits only (a Facebook background ID). Shows a short text post on a coloured background. Used only on a Page feed post with no photo, video or link card and at most 130 characters; anywhere else it is left out and the post publishes as plain text. If Facebook refuses the background the post is published once more without it."
}
},
"additionalProperties": {}
},
"linkedin": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 answers, each up to 30 characters; blank entries are ignored."
},
"duration": {
"enum": [
"ONE_DAY",
"THREE_DAYS",
"SEVEN_DAYS",
"FOURTEEN_DAYS"
],
"type": "string",
"description": "Default THREE_DAYS."
},
"question": {
"type": "string",
"description": "Up to 140 characters."
}
},
"description": "Required for `poll` posts, which also need post text and take no media."
},
"reshareId": {
"type": "string",
"description": "Required for `reshare` posts: the post's LinkedIn link, or its urn:li:share:<id> / urn:li:ugcPost:<id> ID. Activity links (urn:li:activity:<id>) cannot be reshared."
},
"visibility": {
"enum": [
"PUBLIC",
"CONNECTIONS",
"LOGGED_IN"
],
"type": "string",
"description": "Who can see the post (default PUBLIC). CONNECTIONS applies to personal profiles only; on a Page it is published as PUBLIC."
},
"thumbnailUrl": {
"type": "string",
"description": "Cover for a `post` that carries a video: a public http(s) link to an image of up to 10MB. A cover that cannot be fetched is skipped and LinkedIn picks the frame."
},
"documentTitle": {
"type": "string",
"description": "`document` posts only: the title shown above the document in the feed. Defaults to the file's name."
},
"disableReshare": {
"type": "boolean",
"description": "true stops other members resharing the post (default false)."
}
},
"additionalProperties": {}
},
"mastodon": {
"type": "object",
"properties": {
"poll": {
"type": "object",
"required": [
"options",
"expiresIn"
],
"properties": {
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 4 choices, each 1 to 50 characters."
},
"multiple": {
"type": "boolean",
"description": "Voters may pick more than one choice (default false)."
},
"expiresIn": {
"type": "number",
"description": "Seconds the poll stays open, 300 to 2629746."
},
"hideTotals": {
"type": "boolean",
"description": "Hide counts until the poll ends (default false)."
}
},
"description": "Adds a poll. Cannot be combined with media. First post of a thread. A server with tighter limits refuses it at publish time."
},
"quoteId": {
"type": "string",
"description": "The post to quote: its URL, or its status ID on your own server. Needs a server running Mastodon 4.5 or later, otherwise publishing fails and nothing is posted."
},
"repostId": {
"type": "string",
"description": "With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost."
},
"sensitive": {
"type": "boolean",
"description": "Hides attached media behind a click (default false). No effect without media. Applies to every part of a thread."
}
},
"additionalProperties": {}
},
"snapchat": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Saved Story title (max 45 chars). Defaults to the first line of the caption, truncated."
},
"locale": {
"type": "string",
"description": "Spotlight locale, e.g. 'en_US'. Defaults to 'en_US'."
},
"saveToProfile": {
"type": "boolean",
"description": "Spotlight only. Default true; false sends skip_save_to_profile to Snap."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Saved Story title (max 45 chars). Defaults to the first line of the caption, truncated."
},
"locale": {
"type": "string",
"description": "Spotlight locale, e.g. 'en_US'. Defaults to 'en_US'."
},
"saveToProfile": {
"type": "boolean",
"description": "Spotlight only. Default true; false sends skip_save_to_profile to Snap."
}
},
"additionalProperties": {}
}
],
"description": "Snapchat options, nested under the BulkPublish channel id: { \"12\": { \"title\": \"My story\" } }. A flat object applies to every Snapchat channel on the post. Post types: story (default), saved_story, spotlight. Every Snapchat post requires exactly ONE image or video (vertical, story videos 5–60s, spotlight 6–60s video-only, saved_story videos not length-checked, max 1GB; a video outside its range is refused when the post is scheduled or published). The caption is NOT sent for plain stories — it is only the Spotlight description (160 chars max) and the Saved Story title fallback. First comments are not supported."
},
"telegram": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin after sending. If the bot lacks the right to pin the post still publishes and a warning is recorded."
},
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"quiz": {
"type": "boolean",
"description": "Default false."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 12 answers, each up to 100 characters."
},
"question": {
"type": "string",
"description": "1 to 300 characters."
},
"anonymous": {
"type": "boolean",
"description": "Default true."
},
"correctOption": {
"type": "number",
"description": "0-based index of the right answer; required when quiz is true."
},
"multipleAnswers": {
"type": "boolean",
"description": "Default false. Cannot be combined with quiz."
}
},
"description": "Sent as a poll after the message."
},
"silent": {
"type": "boolean",
"description": "Send without a notification sound."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 64 characters."
}
}
},
"description": "Link buttons under the message, up to 3."
},
"spoiler": {
"type": "boolean",
"description": "Hides a photo or video behind a spoiler."
},
"threadId": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
],
"description": "Forum topic to post into: digits only, up to 12."
},
"disablePreview": {
"type": "boolean",
"description": "Turns off the link preview."
},
"protectContent": {
"type": "boolean",
"description": "Recipients cannot forward or save the message."
}
},
"additionalProperties": {}
}
},
{
"type": "object",
"properties": {
"pin": {
"type": "boolean",
"description": "Pin after sending. If the bot lacks the right to pin the post still publishes and a warning is recorded."
},
"poll": {
"type": "object",
"required": [
"question",
"options"
],
"properties": {
"quiz": {
"type": "boolean",
"description": "Default false."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "2 to 12 answers, each up to 100 characters."
},
"question": {
"type": "string",
"description": "1 to 300 characters."
},
"anonymous": {
"type": "boolean",
"description": "Default true."
},
"correctOption": {
"type": "number",
"description": "0-based index of the right answer; required when quiz is true."
},
"multipleAnswers": {
"type": "boolean",
"description": "Default false. Cannot be combined with quiz."
}
},
"description": "Sent as a poll after the message."
},
"silent": {
"type": "boolean",
"description": "Send without a notification sound."
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "http(s) link."
},
"label": {
"type": "string",
"description": "Up to 64 characters."
}
}
},
"description": "Link buttons under the message, up to 3."
},
"spoiler": {
"type": "boolean",
"description": "Hides a photo or video behind a spoiler."
},
"threadId": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
],
"description": "Forum topic to post into: digits only, up to 12."
},
"disablePreview": {
"type": "boolean",
"description": "Turns off the link preview."
},
"protectContent": {
"type": "boolean",
"description": "Recipients cannot forward or save the message."
}
},
"additionalProperties": {}
}
],
"description": "Telegram options, nested under the BulkPublish channel id: { \"12\": { \"silent\": true } }. A flat object applies to every Telegram channel on the post. The destination chat is fixed when the channel is connected. Content is sent as plain text (no markdown). Text over the 1024-char caption limit is posted as a second message alongside captionless media. Attached GIFs, audio and other files are sent as an animation, an audio file or a document according to their type."
},
"instagram": {
"type": "object",
"properties": {
"coverUrl": {
"type": "string",
"description": "Cover image URL for a video or Reel. Takes precedence over thumbnailTimestamp: Instagram accepts one or the other and rejects a request carrying both, so only this one is forwarded when both are sent."
},
"userTags": {
"type": "array",
"items": {
"type": "object",
"required": [
"username"
],
"properties": {
"x": {
"type": "number",
"description": "Position on the photo, 0 to 1 from the left. Give x and y together or not at all."
},
"y": {
"type": "number",
"description": "Position on the photo, 0 to 1 from the top."
},
"username": {
"type": "string",
"description": "A public Instagram username, leading @ optional."
},
"mediaIndex": {
"type": "number",
"description": "Which attached media item the tag belongs to, counting from 0 in attachment order (default 0)."
}
}
},
"description": "People tagged in the post, up to 20 per photo or video. On a photo (and each photo of a carousel) a tag needs x and y or it is left out; on a Reel or video post people are tagged by username only and any position is ignored. Carousel videos and Stories carry no tags."
},
"trialReel": {
"type": "boolean",
"description": "Publish as a trial reel, shown to people who do not follow the account first. Only takes effect with postTypeOverrides.instagram of 'reel' — a 'feed_video' publishes as an ordinary reel and this is ignored, even though both use the same underlying reel container."
},
"locationId": {
"type": "string",
"description": "Digits only: the numeric ID of a Facebook Page that has a location. Applies to photos, videos, Reels and carousels, not Stories. Instagram refuses the post if it does not recognise the ID as a place."
},
"shareToFeed": {
"type": "boolean",
"description": "Reels only. false shows the Reel only in the Reels tab; true also shows it in the main feed. Omitted: Instagram's own default (feed and Reels tab)."
},
"shareToStory": {
"type": "boolean"
},
"collaborators": {
"type": "string",
"description": "Comma-separated Instagram usernames (no leading @) tagged as co-authors. Applies with postTypeOverrides.instagram of 'feed_photo', 'feed_video', 'reel' or 'carousel' — on a carousel the co-authors are set on the carousel itself, not on its individual items. Ignored on 'story', which has no co-author concept."
},
"graduationStrategy": {
"enum": [
"manual",
"auto"
],
"type": "string",
"description": "How a trial reel becomes a normal one: 'manual' (the creator releases it) or 'auto' (released automatically if it performs well). Default 'manual'. Ignored unless trialReel is true."
},
"thumbnailTimestamp": {
"type": "number",
"description": "Cover frame for a video or Reel, in seconds from the start. Applies to postTypeOverrides.instagram of 'feed_video' or 'reel'. Ignored when coverUrl is also set."
}
},
"additionalProperties": {}
},
"pinterest": {
"type": "object",
"properties": {
"link": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"coverImageUrl": {
"type": "string",
"description": "Cover image URL for video pins. Optional — server falls back to an attached image, then the video's auto-extracted poster frame."
},
"dominantColor": {
"type": "string",
"description": "Hex color e.g. #FF5733"
},
"boardSectionId": {
"type": "string",
"description": "Numeric ID of a section of the chosen board (list with get_channel_options and boardId). Send it beside its board, per channel or flat. Pin, video_pin and carousel. A flat value is ignored for a channel with its own boardId, and any section is ignored when no board was chosen."
},
"coverKeyFrameTime": {
"type": "number",
"description": "video_pin only: use the frame at this many seconds (whole number, 0 or more) as the cover. A time past the end uses the last frame; coverImageUrl wins when both are sent."
}
},
"additionalProperties": {}
}
},
"description": "Platform-specific settings, e.g. { \"youtube\": { \"title\": \"…\", \"privacyStatus\": \"public\" } }. Discord, Telegram, Tumblr and Snapchat nest their options under the BulkPublish channel id, e.g. { \"discord\": { \"12\": { \"channelId\": \"1090123456789012345\" } } }. Full per-platform option lists (polls, quotes, tags, drafts, settings) are on each platform key; bad values are refused with 400 VALIDATION_ERROR."
},
"ifUnmodifiedSince": {
"type": "string",
"description": "Optional precondition: the post's updatedAt exactly as the last read returned it. The update is refused with 409 CONFLICT if a teammate has changed the post since, rather than overwriting their version. Pass it whenever you read a post before editing it; omit it to keep the previous last-write-wins behaviour."
},
"postTypeOverrides": {
"type": "object",
"properties": {
"x": {
"enum": [
"tweet",
"video",
"thread",
"repost"
],
"type": "string"
},
"gmb": {
"enum": [
"standard",
"event",
"offer"
],
"type": "string"
},
"tiktok": {
"enum": [
"video",
"photo_slideshow"
],
"type": "string"
},
"tumblr": {
"enum": [
"post"
],
"type": "string"
},
"bluesky": {
"enum": [
"post",
"video",
"thread",
"repost"
],
"type": "string"
},
"discord": {
"enum": [
"post"
],
"type": "string"
},
"threads": {
"enum": [
"text",
"image",
"video",
"carousel",
"repost"
],
"type": "string"
},
"youtube": {
"enum": [
"video",
"short"
],
"type": "string"
},
"facebook": {
"enum": [
"post",
"video",
"reel",
"story",
"carousel"
],
"type": "string"
},
"linkedin": {
"enum": [
"post",
"multi_image",
"pdf_carousel",
"article",
"document",
"poll",
"reshare"
],
"type": "string",
"description": "document: one PDF, Word or PowerPoint file from the media library (exactly one document, no images or videos; title from platformSpecific.linkedin.documentTitle). poll: a question with 2-4 answers from platformSpecific.linkedin.poll (needs post text, no media). reshare: shares an existing LinkedIn post from platformSpecific.linkedin.reshareId (post text optional, no media)."
},
"mastodon": {
"enum": [
"post",
"thread",
"repost"
],
"type": "string"
},
"snapchat": {
"enum": [
"story",
"saved_story",
"spotlight"
],
"type": "string",
"description": "story (default): 1 image or video, caption NOT sent. saved_story: 1 image or video with a title. spotlight: video only, 6–60s, caption becomes the description. Story videos must be 5–60s; a video outside its range is refused when the post is scheduled or published. saved_story video length is not checked."
},
"telegram": {
"enum": [
"post"
],
"type": "string"
},
"instagram": {
"enum": [
"feed_photo",
"feed_video",
"reel",
"story",
"carousel"
],
"type": "string"
},
"pinterest": {
"enum": [
"pin",
"video_pin",
"carousel"
],
"type": "string"
}
},
"description": "Per-platform post type override. E.g. { \"instagram\": \"reel\", \"youtube\": \"short\" }. Video length is checked per type when the post is scheduled or published, and a video outside the range is refused: instagram reel/feed_video 3s–15min, story 3–60s; facebook reel 3–90s, story 3–60s; threads video/carousel up to 5min; linkedin 3s–30min; pinterest video_pin at least 4s; snapchat story 5–60s, spotlight 6–60s (saved_story not checked)."
},
"publishWhenApproved": {
"type": "boolean",
"description": "Optional. Set true to have the post go out as soon as it is approved, even after its scheduled time (see create_post). An explicit value is stored while the post waits for approval. Omitted, it is kept, except that sending a different scheduledAt clears it to false, and it is always false once the post is no longer approvalStatus 'pending'."
},
"recurringScheduleId": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"description": "Optional. Attach the post to a recurring schedule by id, or null to detach it. Omit to leave it unchanged."
},
"linkTrackingOverride": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"description": "Optional per-post override for link tracking (bulkpubli.sh). true forces links in this post to be shortened and their clicks counted, false forces them to publish as written, and null clears the override so the post inherits the organization's Link Tracking setting again. Omit to leave it unchanged."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"author": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who wrote the post: { id, name, image }. Null when that account is gone."
},
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "draft, scheduled, processing, published, partial or failed."
},
"content": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"approver": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who approved it: { id, name, image }. Null unless approvalStatus is approved."
},
"assignee": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
],
"description": "Who is expected to act on it next: { id, name, image }. Null when nobody is."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"createdAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"mediaFiles": {
"anyOf": [
{
"type": "array",
"items": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "object",
"properties": {},
"additionalProperties": {}
}
]
}
},
{
"type": "null"
}
]
},
"publishedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"scheduledAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"postPlatforms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"platform": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"approvalStatus": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Delete a post by ID. Any post can be deleted except one that is publishing right now (409 PUBLISH_IN_PROGRESS; wait for it to finish). Deleting removes the post from BulkPublish only: a published post stays live on the platforms, and its stats here are removed with it. Deleting a post made by a repeat schedule also switches that schedule off. Use this when the user wants to permanently remove a post.
The description explains the capability, when to use it, and what to expect.
Inputs50/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postId
The post ID to delete.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
{
"name": "delete_post",
"title": "Delete post",
"description": "Delete a post by ID. Any post can be deleted except one that is publishing right now (409 PUBLISH_IN_PROGRESS; wait for it to finish). Deleting removes the post from BulkPublish only: a published post stays live on the platforms, and its stats here are removed with it. Deleting a post made by a repeat schedule also switches that schedule off. Use this when the user wants to permanently remove a post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID to delete."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get engagement metrics for a published post. Returns likes, comments, shares, impressions, and other platform-specific metrics. IMPORTANT: every platform entry carries `metricsSupported` and `supportedMetrics` — a metric key NOT in `supportedMetrics` is stored as 0 because that platform's API has no such field, so report it as unavailable rather than as zero. X reports impressions/likes/comments/shares/saves (bookmarks); Bluesky and Mastodon report no impressions; Pinterest reports no reach; YouTube reports no shares or reach; Discord reports likes (reaction counts) and comments (thread replies); TikTok reports reach, saves and clicks only for accounts that have granted TikTok insights. An Instagram story reports only impressions, reach and comments (story replies). Google Business, Telegram, Tumblr and LinkedIn personal profiles report nothing readable at all, and an X post comes back with `metricsSupported: false` until its channel turns on X metrics sync. Each platform entry also carries `linkClicks` (summed in `totals.linkClicks`): clicks on bulkpubli.sh short links in this post, measured by BulkPublish rather than reported by the platform. It sits OUTSIDE `latest` and is distinct from the platform's own `clicks` — one visit can register in both, so never add them together. It is therefore available even for the platforms that report nothing, and `supportedMetrics` always includes it. Bot and link-preview traffic is excluded; it is 0 for organizations without Link Tracking enabled. Use this when the user asks how a specific post performed (likes, views, engagement).
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post ID to get metrics for.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "get_post_metrics",
"title": "Get post metrics",
"description": "Get engagement metrics for a published post. Returns likes, comments, shares, impressions, and other platform-specific metrics. IMPORTANT: every platform entry carries `metricsSupported` and `supportedMetrics` — a metric key NOT in `supportedMetrics` is stored as 0 because that platform's API has no such field, so report it as unavailable rather than as zero. X reports impressions/likes/comments/shares/saves (bookmarks); Bluesky and Mastodon report no impressions; Pinterest reports no reach; YouTube reports no shares or reach; Discord reports likes (reaction counts) and comments (thread replies); TikTok reports reach, saves and clicks only for accounts that have granted TikTok insights. An Instagram story reports only impressions, reach and comments (story replies). Google Business, Telegram, Tumblr and LinkedIn personal profiles report nothing readable at all, and an X post comes back with `metricsSupported: false` until its channel turns on X metrics sync. Each platform entry also carries `linkClicks` (summed in `totals.linkClicks`): clicks on bulkpubli.sh short links in this post, measured by BulkPublish rather than reported by the platform. It sits OUTSIDE `latest` and is distinct from the platform's own `clicks` — one visit can register in both, so never add them together. It is therefore available even for the platforms that report nothing, and `supportedMetrics` always includes it. Bot and link-preview traffic is excluded; it is 0 for organizations without Link Tracking enabled. Use this when the user asks how a specific post performed (likes, views, engagement).",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID to get metrics for."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"postId": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"totals": {
"anyOf": [
{
"type": "object",
"properties": {},
"additionalProperties": {}
},
{
"type": "null"
}
]
},
"platforms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"platform": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Get the organization's next available queue slot. Useful for finding the next optimal scheduling time. Use this when the user asks when the next available scheduling slot is, or wants a post moved to the top or bottom of the queue (then update_post with the returned scheduledAt).
Describe the returned information so the agent knows whether it will answer the request.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
timezone
IANA timezone for the slot calculation (e.g. "America/New_York"). Defaults to UTC.
Clear enough to supply this argument.
position
"next" (default): the next free slot. "end": the slot after the last pending scheduled post, i.e. the bottom of the queue.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
excludePostId
When the slot is for rescheduling an existing post, its ID — so its current slot is not counted as booked.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"dayLabel": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Human label, e.g. \"Today\" or \"Wed, Feb 14\"."
},
"scheduledAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "ISO timestamp of the next free slot."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "get_queue_slot",
"title": "Get next queue slot",
"description": "Get the organization's next available queue slot. Useful for finding the next optimal scheduling time. Use this when the user asks when the next available scheduling slot is, or wants a post moved to the top or bottom of the queue (then update_post with the returned scheduledAt).",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"position": {
"enum": [
"next",
"end"
],
"type": "string",
"description": "\"next\" (default): the next free slot. \"end\": the slot after the last pending scheduled post, i.e. the bottom of the queue."
},
"timezone": {
"type": "string",
"description": "IANA timezone for the slot calculation (e.g. \"America/New_York\"). Defaults to UTC."
},
"excludePostId": {
"type": "number",
"description": "When the slot is for rescheduling an existing post, its ID — so its current slot is not counted as booked."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"dayLabel": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Human label, e.g. \"Today\" or \"Wed, Feb 14\"."
},
"scheduledAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "ISO timestamp of the next free slot."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Get platform-specific options for a channel: Pinterest boards (or, with boardId, that board's sections), YouTube playlists, Tumblr blogs, Discord text channels, Threads location search. Use this when you need a platform's valid post types before creating a post for it.
Describe the returned information so the agent knows whether it will answer the request.
Inputs50/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
channelId
The channel ID to get options for.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
q
Search term. Threads: place search for platformSpecific.threads.locationId (returns { unavailable: true } until the channel has granted location tagging).
Clear enough to supply this argument.
boardId
Pinterest only: numeric board ID. Returns that board's sections ({ type: 'sections', items: [{ id, name }] }) for platformSpecific.pinterest.boardSectionId, instead of the boards. Non-numeric values return 400.
Resolve the mismatch between this description and its schema constraints.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Change a connected channel's sync settings. Both switches apply to X channels only, where every read is billed, and each is off until turned on: metricsSyncEnabled turns on analytics sync (at most once every 7 days) and the list of people who liked a post; inboxSyncEnabled turns on direct messages and replies to the channel's posts. Send at least one. On a channel of any other platform the call succeeds but changes nothing. Needs a role that can manage channels (owner, admin, approver). Does not connect, reconnect or remove a channel. Use this when the user wants to turn analytics sync or direct-message/reply reading on or off for an X channel.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Input documentation gives an agent enough context to populate the arguments.
channelId
The channel ID (from list_channels).
Clear enough to supply this argument.
metricsSyncEnabled
X only. Turn analytics sync and liker lists on or off. Omit to leave unchanged.
Clear enough to supply this argument.
inboxSyncEnabled
X only. Turn reading direct messages and replies on or off. Omit to leave unchanged.
{
"name": "update_channel",
"title": "Update channel sync settings",
"description": "Change a connected channel's sync settings. Both switches apply to X channels only, where every read is billed, and each is off until turned on: metricsSyncEnabled turns on analytics sync (at most once every 7 days) and the list of people who liked a post; inboxSyncEnabled turns on direct messages and replies to the channel's posts. Send at least one. On a channel of any other platform the call succeeds but changes nothing. Needs a role that can manage channels (owner, admin, approver). Does not connect, reconnect or remove a channel. Use this when the user wants to turn analytics sync or direct-message/reply reading on or off for an X channel.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"channelId"
],
"properties": {
"channelId": {
"type": "number",
"description": "The channel ID (from list_channels)."
},
"inboxSyncEnabled": {
"type": "boolean",
"description": "X only. Turn reading direct messages and replies on or off. Omit to leave unchanged."
},
"metricsSyncEnabled": {
"type": "boolean",
"description": "X only. Turn analytics sync and liker lists on or off. Omit to leave unchanged."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Open an interactive composer to draft or schedule a social media post. Shows the user's connected channels to pick from and pre-fills any provided text. The user finishes in the UI; on submit it creates the post via create_post. Use this when the user wants to compose a post interactively in a UI — prefer this over create_post when they'd review before posting.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Input documentation gives an agent enough context to populate the arguments.
content
Optional initial text to pre-fill the composer with.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Open an interactive analytics dashboard for a date range — totals, status breakdown, per-platform stats, and daily post counts. Use this when the user wants an interactive analytics dashboard — prefer over get_analytics for a visual view.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from
Start date (ISO, e.g. 2025-01-01). Defaults to 30 days ago.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Open an interactive list of posts with their status, schedule, and channels. Optionally filter by status. Use this when the user wants to see their posts as an interactive dashboard — prefer over list_posts for a visual view.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
Filter by post status.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description76/100
Open an interactive view of connected social channels with platform, account, and connection/token status. Use this when the user wants an interactive view of their connected channels.
Describe the returned information so the agent knows whether it will answer the request.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Reserve a presigned upload URL for a direct browser upload (used by the composer UI). For scripted uploads use upload_media instead. Use this when you need a presigned URL for a large direct upload (advanced; prefer upload_media for normal files).
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description78/100
Record an uploaded file as a media file after the browser PUT (pairs with create_media_upload; used by the composer UI). Use this when a presigned direct upload finished and the file must be registered (advanced).
Describe the returned information so the agent knows whether it will answer the request.
Inputs86/100
Input documentation gives an agent enough context to populate the arguments.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List Inbox conversations: direct messages, reviews and comment threads across the connected channels, newest activity first. Each conversation has its platform, kind (dm, review or comment), the other person, unread count, a preview of the last message, and canReply with replyNotice saying why a reply cannot be sent now. Internal team notes are not included. Results are paged: pass nextCursor back as cursor for the next page. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user asks about their direct messages, reviews or comment threads, or what is waiting for a reply.
The description explains the capability, when to use it, and what to expect.
Inputs72/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
open (default), archived or snoozed.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
kind
Only direct messages, reviews or comment threads. Omit for all.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
platforms
Only these platforms, e.g. ["instagram", "facebook"].
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
channelId
Only this channel.
Explain the meaning of this value, not just its name.
assigned
me, unassigned, or a teammate's user id.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
q
Search the person's name and handle and the message text (2 to 100 characters).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
nextCursor from the previous page.
Clear enough to supply this argument.
limit
Page size, 1 to 100 (default 50).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get the messages of one Inbox conversation: the newest 500, oldest first, each with its direction (in from the other person, out sent by the workspace), text, attachments and time. Reading does not mark the conversation read. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to read one Inbox conversation in full.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
{
"name": "get_conversation",
"title": "Get Inbox conversation",
"description": "Get the messages of one Inbox conversation: the newest 500, oldest first, each with its direction (in from the other person, out sent by the workspace), text, attachments and time. Reading does not mark the conversation read. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to read one Inbox conversation in full.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"conversationId"
],
"properties": {
"conversationId": {
"type": "number",
"description": "The conversation id from list_conversations."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"messages": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
},
"text": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"sentAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"direction": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "in (from the other person) or out (sent by the workspace)."
}
},
"additionalProperties": {}
}
},
{
"type": "null"
}
]
},
"conversationId": {
"anyOf": [
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Send a reply in an Inbox conversation. The message goes to the person on the platform right away, from the channel the conversation belongs to, and it cannot be unsent. Send text (up to 4,000 characters), up to 4 media library files, or both; reviews and comment threads take text only. Facebook Messenger and Instagram accept a reply only within 24 hours of the person's last message; after that the call is refused. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to answer a direct message, review or comment thread in their Inbox.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
conversationId
The conversation id from list_conversations.
Clear enough to supply this argument.
text
The reply text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
mediaIds
Media library file ids to attach (direct messages only).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
replyToMessageId
Comment threads only: the id of the incoming message to answer. Defaults to the newest one from the other person.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"messageId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The platform's id for the sent message."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "reply_to_conversation",
"title": "Reply in Inbox conversation",
"description": "Send a reply in an Inbox conversation. The message goes to the person on the platform right away, from the channel the conversation belongs to, and it cannot be unsent. Send text (up to 4,000 characters), up to 4 media library files, or both; reviews and comment threads take text only. Facebook Messenger and Instagram accept a reply only within 24 hours of the person's last message; after that the call is refused. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to answer a direct message, review or comment thread in their Inbox.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"conversationId"
],
"properties": {
"text": {
"type": "string",
"maxLength": 4000,
"description": "The reply text."
},
"mediaIds": {
"type": "array",
"items": {
"type": "number"
},
"maxItems": 4,
"description": "Media library file ids to attach (direct messages only)."
},
"conversationId": {
"type": "number",
"description": "The conversation id from list_conversations."
},
"replyToMessageId": {
"type": "number",
"description": "Comment threads only: the id of the incoming message to answer. Defaults to the newest one from the other person."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"messageId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The platform's id for the sent message."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Change how the workspace handles one Inbox conversation: mark it read or unread, archive or reopen it, snooze it until a time (at most 90 days out), or assign it to a teammate, who is notified. Nothing is sent to the other person and nothing changes on the platform. Send at least one field. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to mark a conversation read or unread, archive or reopen it, snooze it, or assign it to a teammate.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
conversationId
The conversation id from list_conversations.
Clear enough to supply this argument.
read
true marks it read, false unread.
Clear enough to supply this argument.
status
archived archives it, open reopens it. Either clears a snooze.
Clear enough to supply this argument.
snoozedUntil
ISO timestamp in the future to snooze until; null unsnoozes.
Clear enough to supply this argument.
assignedUserId
A workspace member's user id; null unassigns.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
{
"name": "update_conversation",
"title": "Update Inbox conversation",
"description": "Change how the workspace handles one Inbox conversation: mark it read or unread, archive or reopen it, snooze it until a time (at most 90 days out), or assign it to a teammate, who is notified. Nothing is sent to the other person and nothing changes on the platform. Send at least one field. The Inbox is part of the Pro and Business plans; on other plans, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to mark a conversation read or unread, archive or reopen it, snooze it, or assign it to a teammate.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"conversationId"
],
"properties": {
"read": {
"type": "boolean",
"description": "true marks it read, false unread."
},
"status": {
"enum": [
"open",
"archived"
],
"type": "string",
"description": "archived archives it, open reopens it. Either clears a snooze."
},
"snoozedUntil": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "ISO timestamp in the future to snooze until; null unsnoozes."
},
"assignedUserId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "A workspace member's user id; null unassigns."
},
"conversationId": {
"type": "number",
"description": "The conversation id from list_conversations."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
List the comments and reactions on one published post, per channel, read from each platform. Each channel's entry has its postPlatformId and each comment its id, which reply_to_comment and moderate_comment take, plus commentActions listing the actions that channel supports. Some platforms have no comment access (TikTok, Pinterest, Google Business, Telegram, Snapchat) and say so in a notice. Use this when the user asks who commented on one of their published posts, or needs a comment's id to reply to or moderate it.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
commentsLimit
Max comments per channel (default 25, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
reactionsLimit
Max reactors (people who liked or reacted) per channel (default 25, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Reply to a comment on one of the workspace's published posts. The reply is posted publicly on the platform right away, as the channel the post was published to, and it cannot be taken back from here. Up to 2,000 characters. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. Comment replies are on every plan except Free; on Free, or before they are available to the account, the call is refused with a message saying so. Use this when the user wants to answer a comment on one of their published posts.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postId
The post id.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postPlatformId
The channel's postPlatformId from list_post_comments.
Clear enough to supply this argument.
commentId
The comment's id from list_post_comments.
Clear enough to supply this argument.
text
The reply text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
rootCommentId
When replying to a reply: the thread's top-level comment id (Instagram and YouTube).
Explain what happens when this optional value is omitted.
{
"name": "reply_to_comment",
"title": "Reply to comment",
"description": "Reply to a comment on one of the workspace's published posts. The reply is posted publicly on the platform right away, as the channel the post was published to, and it cannot be taken back from here. Up to 2,000 characters. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. Comment replies are on every plan except Free; on Free, or before they are available to the account, the call is refused with a message saying so. Use this when the user wants to answer a comment on one of their published posts.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId",
"postPlatformId",
"commentId",
"text"
],
"properties": {
"text": {
"type": "string",
"maxLength": 2000,
"description": "The reply text."
},
"postId": {
"type": "number",
"description": "The post id."
},
"commentId": {
"type": "string",
"description": "The comment's id from list_post_comments."
},
"rootCommentId": {
"type": "string",
"description": "When replying to a reply: the thread's top-level comment id (Instagram and YouTube)."
},
"postPlatformId": {
"type": "number",
"description": "The channel's postPlatformId from list_post_comments."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"replyId": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"accountName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
Shorten the title to an action and subject; move usage details into the description.
Description92/100
Like, unlike, hide, unhide or delete a comment on one of the workspace's published posts, on the platform, as the channel the post was published to. Likes and hides can be undone; delete is permanent and needs a role that can publish. Hiding or deleting also removes the comment from the Inbox. Which actions a channel supports is in its commentActions from list_post_comments (Threads supports hide and unhide; Facebook supports hide, unhide and delete). A comment hidden on Threads or Facebook comes back with hidden: true. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. Replying to and moderating comments is on every plan except Free; on Free, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to like, hide or delete a comment on one of their published posts.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postId
The post id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postPlatformId
The channel's postPlatformId from list_post_comments.
Clear enough to supply this argument.
commentId
The comment's id from list_post_comments.
Clear enough to supply this argument.
action
What to do with the comment.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "moderate_comment",
"title": "Like, hide or delete comment",
"description": "Like, unlike, hide, unhide or delete a comment on one of the workspace's published posts, on the platform, as the channel the post was published to. Likes and hides can be undone; delete is permanent and needs a role that can publish. Hiding or deleting also removes the comment from the Inbox. Which actions a channel supports is in its commentActions from list_post_comments (Threads supports hide and unhide; Facebook supports hide, unhide and delete). A comment hidden on Threads or Facebook comes back with hidden: true. If the channel's connection has stopped working, the call is refused and the channel needs reconnecting from the Channels page. Replying to and moderating comments is on every plan except Free; on Free, or before it is available to the account, the call is refused with a message saying so. Use this when the user wants to like, hide or delete a comment on one of their published posts.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId",
"postPlatformId",
"commentId",
"action"
],
"properties": {
"action": {
"enum": [
"like",
"unlike",
"hide",
"unhide",
"delete"
],
"type": "string",
"description": "What to do with the comment."
},
"postId": {
"type": "number",
"description": "The post id."
},
"commentId": {
"type": "string",
"description": "The comment's id from list_post_comments."
},
"postPlatformId": {
"type": "number",
"description": "The channel's postPlatformId from list_post_comments."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"action": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"success": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Get an analytics summary for a date range
02List mediaList uploaded media files with optional search and pagination.
03Analytics dashboardOpen an interactive analytics dashboard for a date range — totals, status breakdown, per-platform stats, and daily post counts.
04View postsOpen an interactive list of posts with their status, schedule, and channels.
05List channelsList all connected social media channels (X/Twitter, Instagram, LinkedIn, Facebook, TikTok, etc.).
Want to run these tasks against your MCP server with us?
bulkpublish setup, tools, quality score, publishing readiness, and alternatives.
How do I add bulkpublish to Claude, ChatGPT, or Cursor?
Add bulkpublish to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://mcp.bulkpublish.com/mcp.
Is bulkpublish MCP ready for ChatGPT and Claude?
As of November 10, 2026, bulkpublish scores 88/100 on Manufact's MCP publishing checklist. The scan does not yet meet ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is bulkpublish's MCP tool documentation?
As of November 10, 2026, bulkpublish scores 86/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 32 of 32 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to bulkpublish?
As of November 10, 2026, alternatives to bulkpublish in marketing-seo on the Manufact MCP leaderboard include Refluenced, The Prompting Company MCP, Buzzfy, Indexing Dispatch, and Brave URL Submitter.
How can bulkpublish improve its MCP documentation?
get_channel_options is the lowest-scoring reviewed tool at 75/100. Clarify units, where to obtain this value, or conventions not already expressed in the schema. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.