All view resources are readable and use ui:// with a supported MCP Apps HTML MIME type
Tool invocation metadata present
6 tool(s) missing openai/toolInvocation metadata
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: 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 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.
Description95/100
List every social platform BulkPublish supports and whether it is currently available. Check this before telling a user they can connect a platform or scheduling a post to one: a platform in state 'off' rejects post creation with a 403 PLATFORM_DISABLED error and holds any already-scheduled posts until it is re-enabled, and one in state 'connect_off' cannot accept new connections although existing channels keep publishing. Disabled platforms are still listed, with enabled=false and a reason. A platform may also carry a 'variants' object keyed by channel accountType for sub-platforms gated on their own: LinkedIn reports variants.organization for company pages (a separate LinkedIn app with its own review), while the platform-level state covers personal profiles — so pages can be paused while personal-profile posting is live. A variant is never more permissive than its parent, and when a variant blocks a write the 403 PLATFORM_DISABLED error carries an accountType field naming it. Use this when the user asks which platforms are supported or available, or a connect/publish attempt failed with PLATFORM_DISABLED.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_platforms",
"title": "List platforms",
"description": "List every social platform BulkPublish supports and whether it is currently available. Check this before telling a user they can connect a platform or scheduling a post to one: a platform in state 'off' rejects post creation with a 403 PLATFORM_DISABLED error and holds any already-scheduled posts until it is re-enabled, and one in state 'connect_off' cannot accept new connections although existing channels keep publishing. Disabled platforms are still listed, with enabled=false and a reason. A platform may also carry a 'variants' object keyed by channel accountType for sub-platforms gated on their own: LinkedIn reports variants.organization for company pages (a separate LinkedIn app with its own review), while the platform-level state covers personal profiles — so pages can be paused while personal-profile posting is live. A variant is never more permissive than its parent, and when a variant blocks a write the 403 PLATFORM_DISABLED error carries an accountType field naming it. Use this when the user asks which platforms are supported or available, or a connect/publish attempt failed with PLATFORM_DISABLED.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
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.
Inputs56/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; search_mentions on a LinkedIn channel returns ready-made Page tokens. 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.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
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.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
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.
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.
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; search_mentions on a LinkedIn channel returns ready-made Page tokens. 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.
Inputs92/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).
Clear enough to supply this argument.
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.
Description97/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.
Inputs50/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.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/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.
Description92/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.
Inputs75/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
postId
The post ID to retry.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
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.
Inputs83/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.
{
"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.
Description80/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.
Inputs71/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.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
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).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
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.
Description89/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.
Description81/100
List the organization's saved hashtag groups — named sets of hashtags to drop into a post. Use this when the user wants their saved hashtag sets, or you need hashtags to add to a post.
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.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_hashtag_groups",
"title": "List hashtag groups",
"description": "List the organization's saved hashtag groups — named sets of hashtags to drop into a post. Use this when the user wants their saved hashtag sets, or you need hashtags to add to a post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Save a named set of hashtags (1-30) for reuse in posts. Hashtags may be given with or without the leading '#'; letters, digits and underscores only. Up to 100 groups per organization. Use this when the user wants to save a set of hashtags for reuse.
Describe the returned information so the agent knows whether it will answer the request.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Group name, unique per organization.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
hashtags
Hashtags, e.g. ["launch", "#newproduct"].
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_hashtag_group",
"title": "Create hashtag group",
"description": "Save a named set of hashtags (1-30) for reuse in posts. Hashtags may be given with or without the leading '#'; letters, digits and underscores only. Up to 100 groups per organization. Use this when the user wants to save a set of hashtags for reuse.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"hashtags"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"description": "Group name, unique per organization."
},
"hashtags": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 30,
"minItems": 1,
"description": "Hashtags, e.g. [\"launch\", \"#newproduct\"]."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description79/100
Rename a hashtag group and/or replace its hashtags (partial update — at least one field is required). Use this when the user wants to rename a hashtag group or change its hashtags.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs58/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
groupId
The hashtag group ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
name
New name.
Explain the meaning of this value, not just its name.
hashtags
Replacement hashtag list.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_hashtag_group",
"title": "Update hashtag group",
"description": "Rename a hashtag group and/or replace its hashtags (partial update — at least one field is required). Use this when the user wants to rename a hashtag group or change its hashtags.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"groupId"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"description": "New name."
},
"groupId": {
"type": "number",
"description": "The hashtag group ID."
},
"hashtags": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 30,
"minItems": 1,
"description": "Replacement hashtag list."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_hashtag_group",
"title": "Delete hashtag group",
"description": "Delete a saved hashtag group. Posts that already contain its hashtags are untouched. Use this when the user wants to remove a saved hashtag group.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"groupId"
],
"properties": {
"groupId": {
"type": "number",
"description": "The hashtag group ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
List the organization's saved post templates — reusable text to start a new post from. Filter by kind to get saved first-comment snippets instead of captions. Use this when the user wants their saved post templates, or wants to start a post from one.
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.
kind
Which kind of saved text to list. Defaults to caption.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_templates",
"title": "List post templates",
"description": "List the organization's saved post templates — reusable text to start a new post from. Filter by kind to get saved first-comment snippets instead of captions. Use this when the user wants their saved post templates, or wants to start a post from one.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"kind": {
"enum": [
"caption",
"first_comment"
],
"type": "string",
"description": "Which kind of saved text to list. Defaults to caption."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Save post text as a named template for reuse (text only; media and channels belong to the post). Up to 200 per organization per kind (captions and first-comment snippets each have their own 200); names are unique per kind, so a caption and a first-comment snippet can share a name. Use this when the user wants to save post text for reuse.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Template name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
content
Template text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
kind
What the text is for: a post caption, or a first-comment reply. Defaults to caption.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_template",
"title": "Create post template",
"description": "Save post text as a named template for reuse (text only; media and channels belong to the post). Up to 200 per organization per kind (captions and first-comment snippets each have their own 200); names are unique per kind, so a caption and a first-comment snippet can share a name. Use this when the user wants to save post text for reuse.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"content"
],
"properties": {
"kind": {
"enum": [
"caption",
"first_comment"
],
"type": "string",
"description": "What the text is for: a post caption, or a first-comment reply. Defaults to caption."
},
"name": {
"type": "string",
"maxLength": 100,
"description": "Template name."
},
"content": {
"type": "string",
"maxLength": 10000,
"description": "Template text."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description74/100
Rename a template and/or replace its text (partial update — at least one field is required). Use this when the user wants to rename a template or change its text.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs17/100
1 of 3 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
templateId
The template ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
name
Not provided
Missing description. Explain what this value means and how to supply it.
content
Not provided
Missing description. Explain what this value means and how to supply it.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_template",
"title": "Update post template",
"description": "Rename a template and/or replace its text (partial update — at least one field is required). Use this when the user wants to rename a template or change its text.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"templateId"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100
},
"content": {
"type": "string",
"maxLength": 10000
},
"templateId": {
"type": "number",
"description": "The template ID."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_template",
"title": "Delete post template",
"description": "Delete a saved post template. Use this when the user wants to remove a saved template.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"templateId"
],
"properties": {
"templateId": {
"type": "number",
"description": "The template ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List calendar notes (free text pinned to a day — campaigns, holidays, 'no posts this week'; they never publish) in a date range of at most a year. Returns at most 1000 notes, earliest first; narrow the range to see more. Use this when the user asks what is noted on the content calendar for a period (campaigns, holidays, reminders).
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.
from
Start date, YYYY-MM-DD (inclusive).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End date, YYYY-MM-DD (inclusive).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_calendar_notes",
"title": "List calendar notes",
"description": "List calendar notes (free text pinned to a day — campaigns, holidays, 'no posts this week'; they never publish) in a date range of at most a year. Returns at most 1000 notes, earliest first; narrow the range to see more. Use this when the user asks what is noted on the content calendar for a period (campaigns, holidays, reminders).",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"description": "End date, YYYY-MM-DD (inclusive)."
},
"from": {
"type": "string",
"description": "Start date, YYYY-MM-DD (inclusive)."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Pin a note to a day on the content calendar. Not a post: nothing is published. A workspace may keep up to 5000 notes (400 LIMIT_REACHED beyond that). Use this when the user wants to pin a note, reminder or campaign marker to a calendar day without creating a post.
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.
date
Calendar date, YYYY-MM-DD.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
body
Note text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
color
Six-digit hex colour, default #F59E0B.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_calendar_note",
"title": "Create calendar note",
"description": "Pin a note to a day on the content calendar. Not a post: nothing is published. A workspace may keep up to 5000 notes (400 LIMIT_REACHED beyond that). Use this when the user wants to pin a note, reminder or campaign marker to a calendar day without creating a post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"date",
"body"
],
"properties": {
"body": {
"type": "string",
"maxLength": 2000,
"description": "Note text."
},
"date": {
"type": "string",
"description": "Calendar date, YYYY-MM-DD."
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$",
"description": "Six-digit hex colour, default #F59E0B."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Change a calendar note's day, text and/or colour (partial update — at least one field is required). Use this when the user wants to move, reword or recolour a calendar note.
The description explains the capability, when to use it, and what to expect.
Inputs38/100
2 of 4 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
noteId
The note ID.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
date
New date, YYYY-MM-DD.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
body
Not provided
Missing description. Explain what this value means and how to supply it.
color
Not provided
Missing description. Explain what this value means and how to supply it.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create (or fetch) a post's read-only review link that anyone can open without signing in — for client approval outside the app. Returns { shareToken, url, created }. regenerate=true mints a new link and kills the old one. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants a link a client or colleague can open to review a post without an account.
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.
regenerate
Mint a new token, invalidating the previous link.
Explain what happens when this optional value is omitted.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "share_post",
"title": "Create post review link",
"description": "Create (or fetch) a post's read-only review link that anyone can open without signing in — for client approval outside the app. Returns { shareToken, url, created }. regenerate=true mints a new link and kills the old one. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants a link a client or colleague can open to review a post without an account.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID."
},
"regenerate": {
"type": "boolean",
"description": "Mint a new token, invalidating the previous link."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Revoke a post's review link so the URL stops working. Idempotent. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a shared review link from working.
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.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "unshare_post",
"title": "Revoke post review link",
"description": "Revoke a post's review link so the URL stops working. Idempotent. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a shared review link from working.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
List the organization's client review links (batch review links), newest first, with how many posts each one covers. Paged: returns { reviewLinks, page, limit, total }, 50 per page by default (max 100); `total` counts every link, so request the next page while page × limit < total. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to see the client review links they have created for batches of posts.
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.
page
Page number (default 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Links per page (default 50, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_review_links",
"title": "List client review links",
"description": "List the organization's client review links (batch review links), newest first, with how many posts each one covers. Paged: returns { reviewLinks, page, limit, total }, 50 per page by default (max 100); `total` counts every link, so request the next page while page × limit < total. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to see the client review links they have created for batches of posts.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"page": {
"type": "number",
"description": "Page number (default 1)."
},
"limit": {
"type": "number",
"description": "Links per page (default 50, max 100)."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create a read-only review link covering several posts at once — the multi-post counterpart of share_post. Anyone with the link can open it without signing in. Every postId must belong to the organization. Unlike share_post this is never regenerated in place: each call mints a new link and a new token, even for the same posts. Returns { reviewLink, url }. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants one link a client can open to review several posts at once, e.g. a week's worth of scheduled content, instead of sharing each post separately.
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.
postIds
Post IDs to cover, up to 50 per link.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Optional label shown only to your team (e.g. the client's name) — never shown on the public page.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_review_link",
"title": "Create client review link",
"description": "Create a read-only review link covering several posts at once — the multi-post counterpart of share_post. Anyone with the link can open it without signing in. Every postId must belong to the organization. Unlike share_post this is never regenerated in place: each call mints a new link and a new token, even for the same posts. Returns { reviewLink, url }. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants one link a client can open to review several posts at once, e.g. a week's worth of scheduled content, instead of sharing each post separately.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postIds"
],
"properties": {
"name": {
"type": "string",
"maxLength": 150,
"description": "Optional label shown only to your team (e.g. the client's name) — never shown on the public page."
},
"postIds": {
"type": "array",
"items": {
"type": "number"
},
"maxItems": 50,
"minItems": 1,
"description": "Post IDs to cover, up to 50 per link."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Revoke a client review link. The posts it covered are untouched. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a batch review link from working. The posts it covered are unaffected.
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.
reviewLinkId
The review link ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_review_link",
"title": "Revoke client review link",
"description": "Revoke a client review link. The posts it covered are untouched. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a batch review link from working. The posts it covered are unaffected.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"reviewLinkId"
],
"properties": {
"reviewLinkId": {
"type": "number",
"description": "The review link ID."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List the organization's client-connect links, newest first — one-time links a client can open, with no BulkPublish account, to connect their own platform account. Paged: returns { clientConnectLinks, page, limit, total }, 50 per page by default (max 100); `total` counts every link, so request the next page while page × limit < total. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to see the client-connect links they have created and whether each has been used yet.
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.
page
Page number (default 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Links per page (default 50, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_client_connect_links",
"title": "List client connect links",
"description": "List the organization's client-connect links, newest first — one-time links a client can open, with no BulkPublish account, to connect their own platform account. Paged: returns { clientConnectLinks, page, limit, total }, 50 per page by default (max 100); `total` counts every link, so request the next page while page × limit < total. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to see the client-connect links they have created and whether each has been used yet.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"page": {
"type": "number",
"description": "Page number (default 1)."
},
"limit": {
"type": "number",
"description": "Links per page (default 50, max 100)."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Create a one-time link a client can open, with no BulkPublish account of their own, to connect one of their platform accounts into this organization. The client picks which platform when they open it — only these are supported (telegram asks for a bot token instead of a plain sign-in, and stays a manual connect by your own team): bluesky, facebook, instagram, x, tiktok, youtube, threads, pinterest, gmb, linkedin, mastodon, discord, tumblr, snapchat. For bluesky, the client enters their handle and approves access on Bluesky; they are never asked for a password. For facebook, the client signs in to Facebook and then picks which one of their Pages to connect. For mastodon, they first enter the address of the server their account is on. Expires in 7 days or the moment an account is connected through it, whichever comes first — creating again always makes a new link. Returns { clientConnectLink, url }. The url is shown only this once: it cannot be recovered later, so save it when you get it. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user (an agency) wants a client to connect their own platform account without giving the agency their login, and without the client needing a BulkPublish account.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
name
Your own label for the client (e.g. "Acme Corp"). Never shown to the client — only applied to the resulting channel so you can tell whose account it is.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_client_connect_link",
"title": "Create client connect link",
"description": "Create a one-time link a client can open, with no BulkPublish account of their own, to connect one of their platform accounts into this organization. The client picks which platform when they open it — only these are supported (telegram asks for a bot token instead of a plain sign-in, and stays a manual connect by your own team): bluesky, facebook, instagram, x, tiktok, youtube, threads, pinterest, gmb, linkedin, mastodon, discord, tumblr, snapchat. For bluesky, the client enters their handle and approves access on Bluesky; they are never asked for a password. For facebook, the client signs in to Facebook and then picks which one of their Pages to connect. For mastodon, they first enter the address of the server their account is on. Expires in 7 days or the moment an account is connected through it, whichever comes first — creating again always makes a new link. Returns { clientConnectLink, url }. The url is shown only this once: it cannot be recovered later, so save it when you get it. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user (an agency) wants a client to connect their own platform account without giving the agency their login, and without the client needing a BulkPublish account.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 150,
"description": "Your own label for the client (e.g. \"Acme Corp\"). Never shown to the client — only applied to the resulting channel so you can tell whose account it is."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Revoke a client-connect link before it has been used. Idempotent; an account it already connected is untouched. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a client-connect link from working before it has been used. Any account it already connected is unaffected.
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.
clientConnectLinkId
The client-connect link ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_client_connect_link",
"title": "Revoke client connect link",
"description": "Revoke a client-connect link before it has been used. Idempotent; an account it already connected is untouched. Pro and Business only: on the single-seat Free and Lifetime plans this answers 403 FEATURE_DISABLED with the plan and an upgrade hint. Use this when the user wants to stop a client-connect link from working before it has been used. Any account it already connected is unaffected.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"clientConnectLinkId"
],
"properties": {
"clientConnectLinkId": {
"type": "number",
"description": "The client-connect link ID."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Set a media file's alt text (accessibility description). It belongs to the file, so one value covers every post that reuses it, and is sent to Instagram, LinkedIn, X, Bluesky, Tumblr and Discord. Pass an empty string to clear. Use this when the user wants to add or change an image's alt text / accessibility description.
The description explains the capability, when to use it, and what to expect.
Inputs63/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
mediaId
The media file ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
altText
Description of the image for people who cannot see it. Empty string clears it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_media",
"title": "Set media alt text",
"description": "Set a media file's alt text (accessibility description). It belongs to the file, so one value covers every post that reuses it, and is sent to Instagram, LinkedIn, X, Bluesky, Tumblr and Discord. Pass an empty string to clear. Use this when the user wants to add or change an image's alt text / accessibility description.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mediaId",
"altText"
],
"properties": {
"altText": {
"type": "string",
"maxLength": 1000,
"description": "Description of the image for people who cannot see it. Empty string clears it."
},
"mediaId": {
"type": "number",
"description": "The media file ID."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Check current account usage. Returns daily/monthly post counts, scheduled post counts, channel counts, and media storage usage. Also returns channelSlots — purchased extra channel slots ($2.99/month each, available on every plan; a seat-based subscription whose unused slots are auto-canceled before renewal): each active slot raises the effective total channel limit by one and allows one channel above the per-platform cap; per-slot autoRenews says whether it renews or lapses at expiresAt. Use this when the user asks about plan limits or current usage.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_quota_usage",
"title": "Get quota usage",
"description": "Check current account usage. Returns daily/monthly post counts, scheduled post counts, channel counts, and media storage usage. Also returns channelSlots — purchased extra channel slots ($2.99/month each, available on every plan; a seat-based subscription whose unused slots are auto-canceled before renewal): each active slot raises the effective total channel limit by one and allows one channel above the per-platform cap; per-slot autoRenews says whether it renews or lapses at expiresAt. Use this when the user asks about plan limits or current usage.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
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.
Inputs56/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).
Clear enough to supply this argument.
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.
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.
Inputs82/100
Input documentation gives an agent enough context to populate the arguments.
{
"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
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "publish_story",
"title": "Publish story",
"description": "Publish a post as a story on Facebook or Instagram. Use this when the user wants to post an Instagram/Facebook story.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postId",
"platform"
],
"properties": {
"postId": {
"type": "number",
"description": "The post ID to publish as a story."
},
"platform": {
"enum": [
"facebook",
"instagram"
],
"type": "string",
"description": "Platform to publish the story on."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description76/100
Perform a bulk action on multiple posts. Supports deleting, retrying, or rescheduling up to 100 posts at once. Use this when the user wants to delete, retry, or reschedule many posts in a single request.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
action
Bulk action: "delete", "retry", or "reschedule".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
postIds
Array of post IDs to perform the action on, at most 100 per call. Split a larger selection into batches of 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scheduledAt
New ISO 8601 datetime. Required when action is "reschedule".
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "bulk_posts",
"title": "Bulk post actions",
"description": "Perform a bulk action on multiple posts. Supports deleting, retrying, or rescheduling up to 100 posts at once. Use this when the user wants to delete, retry, or reschedule many posts in a single request.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"action",
"postIds"
],
"properties": {
"action": {
"enum": [
"delete",
"retry",
"reschedule"
],
"type": "string",
"description": "Bulk action: \"delete\", \"retry\", or \"reschedule\"."
},
"postIds": {
"type": "array",
"items": {
"type": "number"
},
"maxItems": 100,
"minItems": 1,
"description": "Array of post IDs to perform the action on, at most 100 per call. Split a larger selection into batches of 100."
},
"scheduledAt": {
"type": "string",
"description": "New ISO 8601 datetime. Required when action is \"reschedule\"."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/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.
Description97/100
Check the health status of a connected channel. Returns token validity, connection status, and any issues. Use this when the user asks whether a channel's connection/token is healthy.
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.
channelId
The channel ID to check health for.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_channel_health",
"title": "Get channel health",
"description": "Check the health status of a connected channel. Returns token validity, connection status, and any issues. Use this when the user asks whether a channel's connection/token is healthy.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"channelId"
],
"properties": {
"channelId": {
"type": "number",
"description": "The channel ID to check health for."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description80/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.
Description87/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.
Inputs91/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.
Description84/100
Search for @mention suggestions on a channel (X, Bluesky, Mastodon, LinkedIn). On LinkedIn the query is a Page's URL slug (exact match), each result's handle is a ready-to-paste @[Name](urn:li:organization:ID) token, and vanityName is the slug it matched — check it against the Page you meant before using the token, since a display name alone is ambiguous. Use this when you need @mention suggestions from a connected channel while drafting a post.
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 search mentions on.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
query
Search query for the mention lookup.
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "search_mentions",
"title": "Search mentions",
"description": "Search for @mention suggestions on a channel (X, Bluesky, Mastodon, LinkedIn). On LinkedIn the query is a Page's URL slug (exact match), each result's handle is a ready-to-paste @[Name](urn:li:organization:ID) token, and vanityName is the slug it matched — check it against the Page you meant before using the token, since a display name alone is ambiguous. Use this when you need @mention suggestions from a connected channel while drafting a post.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"channelId",
"query"
],
"properties": {
"query": {
"type": "string",
"description": "Search query for the mention lookup."
},
"channelId": {
"type": "number",
"description": "The channel ID to search mentions on."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get details of a single media file by ID. Returns metadata, URL, dimensions, and labels. Use this when the user references one specific media file by ID.
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.
mediaId
The media file ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_media",
"title": "Get media file",
"description": "Get details of a single media file by ID. Returns metadata, URL, dimensions, and labels. Use this when the user references one specific media file by ID.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mediaId"
],
"properties": {
"mediaId": {
"type": "number",
"description": "The media file ID."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_media",
"title": "Delete media",
"description": "Delete a media file by ID. Removes the file from storage and detaches it from any posts. Use this when the user wants to delete a media file.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mediaId"
],
"properties": {
"mediaId": {
"type": "number",
"description": "The media file ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_label",
"title": "Update label",
"description": "Update an existing label's name or color. Use this when the user wants to rename or recolor a label.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"labelId"
],
"properties": {
"name": {
"type": "string",
"description": "New label name."
},
"color": {
"type": "string",
"description": "New hex color code (e.g. \"#ef4444\")."
},
"labelId": {
"type": "number",
"description": "The label ID to update."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_label",
"title": "Delete label",
"description": "Delete a label by ID. Removes the label from all associated posts or media. Use this when the user wants to delete a label.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"labelId"
],
"properties": {
"labelId": {
"type": "number",
"description": "The label ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List recurring post schedules, newest first (at most 500; a workspace with more gets the 500 most recently created). Returns schedule name, frequency/timeOfDay timing fields, target channels, active status, and nextRunAt. These schedules also appear in the web app: managed on the Repeat Posts page, with upcoming runs shown on the Calendar. Use this when the user wants their recurring posting schedules.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_schedules",
"title": "List recurring schedules",
"description": "List recurring post schedules, newest first (at most 500; a workspace with more gets the 500 most recently created). Returns schedule name, frequency/timeOfDay timing fields, target channels, active status, and nextRunAt. These schedules also appear in the web app: managed on the Repeat Posts page, with upcoming runs shown on the Calendar. Use this when the user wants their recurring posting schedules.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Create a new recurring post schedule. Posts are automatically created and published on the chosen frequency. The schedule is visible in the web app (Repeat Posts page, with upcoming runs on the Calendar); a post record exists only once an occurrence fires, carrying recurringScheduleId. Use this when the user wants a recurring posting schedule.
Describe the returned information so the agent knows whether it will answer the request.
Inputs84/100
Explain the meaning of this value, not just its name.
name
Schedule name.
Explain the meaning of this value, not just its name.
channelIds
Array of channel IDs to post to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
frequency
How often the schedule runs.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
timeOfDay
Time of day to post, 24h "HH:MM" (e.g. "09:00").
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dayOfWeek
Day of week (0=Sunday..6=Saturday). Required for weekly/biweekly.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dayOfMonth
Day of month (1-31). Required for monthly.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
contentTemplate
Post content template. Defaults to empty.
Clear enough to supply this argument.
mediaFileIds
Media file IDs re-used for every generated post.
Clear enough to supply this argument.
timezone
IANA timezone (e.g. "America/New_York"). Defaults to UTC.
Clear enough to supply this argument.
isActive
Whether the schedule starts active. Defaults to true.
Clear enough to supply this argument.
requireApproval
Hold every occurrence this schedule generates for team approval — each generated post lands with approvalStatus 'pending' and does not publish until an approver releases it via approve_post. Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_schedule",
"title": "Create recurring schedule",
"description": "Create a new recurring post schedule. Posts are automatically created and published on the chosen frequency. The schedule is visible in the web app (Repeat Posts page, with upcoming runs on the Calendar); a post record exists only once an occurrence fires, carrying recurringScheduleId. Use this when the user wants a recurring posting schedule.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"channelIds",
"frequency",
"timeOfDay"
],
"properties": {
"name": {
"type": "string",
"description": "Schedule name."
},
"isActive": {
"type": "boolean",
"description": "Whether the schedule starts active. Defaults to true."
},
"timezone": {
"type": "string",
"description": "IANA timezone (e.g. \"America/New_York\"). Defaults to UTC."
},
"dayOfWeek": {
"type": "number",
"maximum": 6,
"minimum": 0,
"description": "Day of week (0=Sunday..6=Saturday). Required for weekly/biweekly."
},
"frequency": {
"enum": [
"daily",
"weekly",
"biweekly",
"monthly"
],
"type": "string",
"description": "How often the schedule runs."
},
"timeOfDay": {
"type": "string",
"description": "Time of day to post, 24h \"HH:MM\" (e.g. \"09:00\")."
},
"channelIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Array of channel IDs to post to."
},
"dayOfMonth": {
"type": "number",
"maximum": 31,
"minimum": 1,
"description": "Day of month (1-31). Required for monthly."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Media file IDs re-used for every generated post."
},
"contentTemplate": {
"type": "string",
"description": "Post content template. Defaults to empty."
},
"requireApproval": {
"type": "boolean",
"description": "Hold every occurrence this schedule generates for team approval — each generated post lands with approvalStatus 'pending' and does not publish until an approver releases it via approve_post. Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Update an existing recurring schedule. Can change name, content template, frequency/timing, timezone, media, or active status. The next run time is recomputed by the server when timing changes. Use this when the user wants to change a recurring schedule.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scheduleId
The schedule ID to update.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
New schedule name.
Explain the meaning of this value, not just its name.
contentTemplate
New post content template.
Explain the meaning of this value, not just its name.
frequency
New frequency.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
timeOfDay
New time of day, 24h "HH:MM".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dayOfWeek
New day of week (0=Sunday..6=Saturday) for weekly/biweekly.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dayOfMonth
New day of month (1-31) for monthly.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
mediaFileIds
Replace the media file IDs used for generated posts.
Clear enough to supply this argument.
timezone
New IANA timezone.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
isActive
Enable or disable the schedule.
Clear enough to supply this argument.
requireApproval
Hold every future occurrence this schedule generates for team approval — each generated post lands with approvalStatus 'pending' and does not publish until an approver releases it via approve_post. Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_schedule",
"title": "Update recurring schedule",
"description": "Update an existing recurring schedule. Can change name, content template, frequency/timing, timezone, media, or active status. The next run time is recomputed by the server when timing changes. Use this when the user wants to change a recurring schedule.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"scheduleId"
],
"properties": {
"name": {
"type": "string",
"description": "New schedule name."
},
"isActive": {
"type": "boolean",
"description": "Enable or disable the schedule."
},
"timezone": {
"type": "string",
"description": "New IANA timezone."
},
"dayOfWeek": {
"type": "number",
"maximum": 6,
"minimum": 0,
"description": "New day of week (0=Sunday..6=Saturday) for weekly/biweekly."
},
"frequency": {
"enum": [
"daily",
"weekly",
"biweekly",
"monthly"
],
"type": "string",
"description": "New frequency."
},
"timeOfDay": {
"type": "string",
"description": "New time of day, 24h \"HH:MM\"."
},
"dayOfMonth": {
"type": "number",
"maximum": 31,
"minimum": 1,
"description": "New day of month (1-31) for monthly."
},
"scheduleId": {
"type": "number",
"description": "The schedule ID to update."
},
"mediaFileIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Replace the media file IDs used for generated posts."
},
"contentTemplate": {
"type": "string",
"description": "New post content template."
},
"requireApproval": {
"type": "boolean",
"description": "Hold every future occurrence this schedule generates for team approval — each generated post lands with approvalStatus 'pending' and does not publish until an approver releases it via approve_post. Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_schedule",
"title": "Delete recurring schedule",
"description": "Delete a recurring schedule by ID. Stops all future posts from this schedule. Use this when the user wants to stop and delete a recurring schedule.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"scheduleId"
],
"properties": {
"scheduleId": {
"type": "number",
"description": "The schedule ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List saved channel sets — named channel groupings for one-click multi-channel targeting. Returns id, name, and channelIds for each set, ordered by name. Use this when the user wants their saved channel groups (channel sets).
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_channel_sets",
"title": "List channel sets",
"description": "List saved channel sets — named channel groupings for one-click multi-channel targeting. Returns id, name, and channelIds for each set, ordered by name. Use this when the user wants their saved channel groups (channel sets).",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Create a channel set — a saved channel grouping for one-click multi-channel targeting. Names are unique per organization (a duplicate fails with a 409, code DUPLICATE_NAME); an organization can have up to 50 sets. Use this when the user wants to save a group of channels for one-click targeting.
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.
name
Set name (max 100 chars, unique per organization).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
channelIds
IDs of channels in your organization (at least 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_channel_set",
"title": "Create channel set",
"description": "Create a channel set — a saved channel grouping for one-click multi-channel targeting. Names are unique per organization (a duplicate fails with a 409, code DUPLICATE_NAME); an organization can have up to 50 sets. Use this when the user wants to save a group of channels for one-click targeting.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"channelIds"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"description": "Set name (max 100 chars, unique per organization)."
},
"channelIds": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 1,
"description": "IDs of channels in your organization (at least 1)."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
Update a channel set's name and/or channels (partial update — at least one field is required). A name that collides with another set fails with a 409, code DUPLICATE_NAME. Use this when the user wants to rename a channel set or change its channels.
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.
setId
The channel set ID to update.
Clear enough to supply this argument.
name
New set name (max 100 chars, unique per organization).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
channelIds
Replacement channel IDs (at least 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_channel_set",
"title": "Update channel set",
"description": "Update a channel set's name and/or channels (partial update — at least one field is required). A name that collides with another set fails with a 409, code DUPLICATE_NAME. Use this when the user wants to rename a channel set or change its channels.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"setId"
],
"properties": {
"name": {
"type": "string",
"maxLength": 100,
"description": "New set name (max 100 chars, unique per organization)."
},
"setId": {
"type": "number",
"description": "The channel set ID to update."
},
"channelIds": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 1,
"description": "Replacement channel IDs (at least 1)."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "delete_channel_set",
"title": "Delete channel set",
"description": "Delete a channel set by ID. Does not affect the channels themselves. Use this when the user wants to remove a saved channel set.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"setId"
],
"properties": {
"setId": {
"type": "number",
"description": "The channel set ID to delete."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List RSS autopost feeds — RSS/Atom feeds, checked on a schedule set by the plan (every 60 minutes on Free and Lifetime, 30 on Pro, 15 on Business), whose new items automatically become posts. Returns name, feedUrl, channelIds, mode, fieldMapping (how items are rendered into posts; null = default), enabled, lastCheckedAt, and lastError for each feed. Use this when the user wants their RSS autopost feeds.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_rss_feeds",
"title": "List RSS feeds",
"description": "List RSS autopost feeds — RSS/Atom feeds, checked on a schedule set by the plan (every 60 minutes on Free and Lifetime, 30 on Pro, 15 on Business), whose new items automatically become posts. Returns name, feedUrl, channelIds, mode, fieldMapping (how items are rendered into posts; null = default), enabled, lastCheckedAt, and lastError for each feed. Use this when the user wants their RSS autopost feeds.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Add an RSS autopost feed. The feed is checked on a schedule set by the plan (every 60 minutes on Free and Lifetime, 30 on Pro, 15 on Business) and new items become posts on the chosen channels. The server validates that feedUrl is a reachable public RSS 2.0 or Atom feed. The number of feeds is capped by plan (Free 1, Lifetime 3, Pro 10, Business 50); one more is refused with 403 QUOTA_EXCEEDED. mode 'publish' needs a paid plan or Lifetime (403 FEATURE_DISABLED on Free). Use this when the user wants new items from an RSS/Atom feed to become posts automatically.
The description explains the capability, when to use it, and what to expect.
Inputs60/100
11 of 15 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
name
Feed name (max 100 chars).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
feedUrl
Public RSS 2.0 or Atom feed URL.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
channelIds
IDs of channels new items are posted to (at least 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
mode
draft = new items become draft posts for review (the default); publish = auto-published.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fieldMapping › template
Caption template (default "{title}\n\n{link}"). Standard tokens: {title} {link} {description} {content} {author} {categories} {feedName}. Any extra leaf field on the feed item also works as {fieldName} (lowercased localName). A line whose tokens all render empty is dropped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fieldMapping › mediaField
Which item enclosure to import and attach: none (default), image, video, or auto (video if present, else image). The file is re-hosted to the media library.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fieldMapping › articleImage
Where to get a picture when the item has no usable enclosure. when_needed (default) takes one from the article the item links to, but only when a channel on the feed is on a platform that cannot publish without an image; always takes one whenever the item has none; never leaves those items without media. Candidates in order: the article's share image, a picture embedded in the item, then the largest pictures on the page; the first that imports cleanly and measures at least 200x200 wins, at most four are tried. Post-level like mediaField, so the picture reaches every channel of the feed. Image-required channels (Instagram, Pinterest, Snapchat) are skipped only when this finds nothing too; the video-only platforms (TikTok, YouTube) are always skipped for items with no video.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fieldMapping › stripHtml
Strip HTML tags/entities from item text. Default true.
Clear enough to supply this argument.
fieldMapping › truncate
When rendered text exceeds the platform char limit: smart (default) trims at a word boundary keeping a trailing link line; hard cuts at the limit; skip drops that channel for the item.
Clear enough to supply this argument.
fieldMapping › hashtags
Appended after the rendered template.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Missing description. Explain what this value means and how to supply it.
requireApproval
Hold items auto-published from this feed for team approval — each generated post lands with approvalStatus 'pending' and waits for approve_post. Only meaningful when mode is 'publish' (draft items never publish on their own, and a feed force-demoted to draft by the plan gate stays ungated). Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_rss_feed",
"title": "Add RSS feed",
"description": "Add an RSS autopost feed. The feed is checked on a schedule set by the plan (every 60 minutes on Free and Lifetime, 30 on Pro, 15 on Business) and new items become posts on the chosen channels. The server validates that feedUrl is a reachable public RSS 2.0 or Atom feed. The number of feeds is capped by plan (Free 1, Lifetime 3, Pro 10, Business 50); one more is refused with 403 QUOTA_EXCEEDED. mode 'publish' needs a paid plan or Lifetime (403 FEATURE_DISABLED on Free). Use this when the user wants new items from an RSS/Atom feed to become posts automatically.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"feedUrl",
"channelIds"
],
"properties": {
"mode": {
"enum": [
"draft",
"publish"
],
"type": "string",
"description": "draft = new items become draft posts for review (the default); publish = auto-published."
},
"name": {
"type": "string",
"maxLength": 100,
"description": "Feed name (max 100 chars)."
},
"feedUrl": {
"type": "string",
"description": "Public RSS 2.0 or Atom feed URL."
},
"channelIds": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 1,
"description": "IDs of channels new items are posted to (at least 1)."
},
"fieldMapping": {
"type": "object",
"required": [
"template"
],
"properties": {
"hashtags": {
"type": "string",
"maxLength": 500,
"description": "Appended after the rendered template."
},
"template": {
"type": "string",
"maxLength": 2000,
"description": "Caption template (default \"{title}\\n\\n{link}\"). Standard tokens: {title} {link} {description} {content} {author} {categories} {feedName}. Any extra leaf field on the feed item also works as {fieldName} (lowercased localName). A line whose tokens all render empty is dropped."
},
"truncate": {
"enum": [
"smart",
"hard",
"skip"
],
"type": "string",
"description": "When rendered text exceeds the platform char limit: smart (default) trims at a word boundary keeping a trailing link line; hard cuts at the limit; skip drops that channel for the item."
},
"stripHtml": {
"type": "boolean",
"description": "Strip HTML tags/entities from item text. Default true."
},
"mediaField": {
"enum": [
"none",
"image",
"video",
"auto"
],
"type": "string",
"description": "Which item enclosure to import and attach: none (default), image, video, or auto (video if present, else image). The file is re-hosted to the media library."
},
"articleImage": {
"enum": [
"when_needed",
"always",
"never"
],
"type": "string",
"description": "Where to get a picture when the item has no usable enclosure. when_needed (default) takes one from the article the item links to, but only when a channel on the feed is on a platform that cannot publish without an image; always takes one whenever the item has none; never leaves those items without media. Candidates in order: the article's share image, a picture embedded in the item, then the largest pictures on the page; the first that imports cleanly and measures at least 200x200 wins, at most four are tried. Post-level like mediaField, so the picture reaches every channel of the feed. Image-required channels (Instagram, Pinterest, Snapchat) are skipped only when this finds nothing too; the video-only platforms (TikTok, YouTube) are always skipped for items with no video."
},
"channelOverrides": {
"type": "object",
"description": "Per-channel text overrides keyed by channel id (as a string). Media selection cannot be overridden per channel; channels on the same platform share one rendered text.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"hashtags": {
"type": "string",
"maxLength": 500
},
"template": {
"type": "string",
"maxLength": 2000
},
"truncate": {
"enum": [
"smart",
"hard",
"skip"
],
"type": "string"
},
"stripHtml": {
"type": "boolean"
}
}
}
}
},
"description": "Field mapping controlling how each feed item becomes a post."
},
"requireApproval": {
"type": "boolean",
"description": "Hold items auto-published from this feed for team approval — each generated post lands with approvalStatus 'pending' and waits for approve_post. Only meaningful when mode is 'publish' (draft items never publish on their own, and a feed force-demoted to draft by the plan gate stays ungated). Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Update an RSS autopost feed (partial update). Note: changing feedUrl re-baselines the feed — its check state resets and only items published after the change are posted, so the new feed's backlog is not flooded. Use this when the user wants to change, pause, or re-point an RSS autopost feed.
The description explains the capability, when to use it, and what to expect.
Inputs69/100
13 of 17 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
feedId
The RSS feed ID to update.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
New feed name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
feedUrl
New feed URL. Changing it re-baselines the feed (only items newer than the change are posted).
Clear enough to supply this argument.
channelIds
Replacement channel IDs (at least 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
mode
draft = new items become drafts for review; publish = auto-published.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fieldMapping › anyOf › 0 › template
Caption template (default "{title}\n\n{link}"). Standard tokens: {title} {link} {description} {content} {author} {categories} {feedName}. Any extra leaf field on the feed item also works as {fieldName} (lowercased localName). A line whose tokens all render empty is dropped.
Clear enough to supply this argument.
fieldMapping › anyOf › 0 › mediaField
Which item enclosure to import and attach: none (default), image, video, or auto (video if present, else image). The file is re-hosted to the media library.
Clear enough to supply this argument.
fieldMapping › anyOf › 0 › articleImage
Where to get a picture when the item has no usable enclosure. when_needed (default) takes one from the article the item links to, but only when a channel on the feed is on a platform that cannot publish without an image; always takes one whenever the item has none; never leaves those items without media. Candidates in order: the article's share image, a picture embedded in the item, then the largest pictures on the page; the first that imports cleanly and measures at least 200x200 wins, at most four are tried. Post-level like mediaField, so the picture reaches every channel of the feed. Image-required channels (Instagram, Pinterest, Snapchat) are skipped only when this finds nothing too; the video-only platforms (TikTok, YouTube) are always skipped for items with no video.
Clear enough to supply this argument.
fieldMapping › anyOf › 0 › stripHtml
Strip HTML tags/entities from item text. Default true.
Clear enough to supply this argument.
fieldMapping › anyOf › 0 › truncate
When rendered text exceeds the platform char limit: smart (default) trims at a word boundary keeping a trailing link line; hard cuts at the limit; skip drops that channel for the item.
Clear enough to supply this argument.
fieldMapping › anyOf › 0 › hashtags
Appended after the rendered template.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Missing description. Explain what this value means and how to supply it.
enabled
Enable or disable polling of this feed.
Clear enough to supply this argument.
requireApproval
Hold items auto-published from this feed for team approval — each generated post lands with approvalStatus 'pending' and waits for approve_post. Only meaningful when mode is 'publish' (draft items never publish on their own, and a feed force-demoted to draft by the plan gate stays ungated). Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_rss_feed",
"title": "Update RSS feed",
"description": "Update an RSS autopost feed (partial update). Note: changing feedUrl re-baselines the feed — its check state resets and only items published after the change are posted, so the new feed's backlog is not flooded. Use this when the user wants to change, pause, or re-point an RSS autopost feed.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"feedId"
],
"properties": {
"mode": {
"enum": [
"draft",
"publish"
],
"type": "string",
"description": "draft = new items become drafts for review; publish = auto-published."
},
"name": {
"type": "string",
"maxLength": 100,
"description": "New feed name."
},
"feedId": {
"type": "number",
"description": "The RSS feed ID to update."
},
"enabled": {
"type": "boolean",
"description": "Enable or disable polling of this feed."
},
"feedUrl": {
"type": "string",
"description": "New feed URL. Changing it re-baselines the feed (only items newer than the change are posted)."
},
"channelIds": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 1,
"description": "Replacement channel IDs (at least 1)."
},
"fieldMapping": {
"anyOf": [
{
"type": "object",
"required": [
"template"
],
"properties": {
"hashtags": {
"type": "string",
"maxLength": 500,
"description": "Appended after the rendered template."
},
"template": {
"type": "string",
"maxLength": 2000,
"description": "Caption template (default \"{title}\\n\\n{link}\"). Standard tokens: {title} {link} {description} {content} {author} {categories} {feedName}. Any extra leaf field on the feed item also works as {fieldName} (lowercased localName). A line whose tokens all render empty is dropped."
},
"truncate": {
"enum": [
"smart",
"hard",
"skip"
],
"type": "string",
"description": "When rendered text exceeds the platform char limit: smart (default) trims at a word boundary keeping a trailing link line; hard cuts at the limit; skip drops that channel for the item."
},
"stripHtml": {
"type": "boolean",
"description": "Strip HTML tags/entities from item text. Default true."
},
"mediaField": {
"enum": [
"none",
"image",
"video",
"auto"
],
"type": "string",
"description": "Which item enclosure to import and attach: none (default), image, video, or auto (video if present, else image). The file is re-hosted to the media library."
},
"articleImage": {
"enum": [
"when_needed",
"always",
"never"
],
"type": "string",
"description": "Where to get a picture when the item has no usable enclosure. when_needed (default) takes one from the article the item links to, but only when a channel on the feed is on a platform that cannot publish without an image; always takes one whenever the item has none; never leaves those items without media. Candidates in order: the article's share image, a picture embedded in the item, then the largest pictures on the page; the first that imports cleanly and measures at least 200x200 wins, at most four are tried. Post-level like mediaField, so the picture reaches every channel of the feed. Image-required channels (Instagram, Pinterest, Snapchat) are skipped only when this finds nothing too; the video-only platforms (TikTok, YouTube) are always skipped for items with no video."
},
"channelOverrides": {
"type": "object",
"description": "Per-channel text overrides keyed by channel id (as a string). Media selection cannot be overridden per channel; channels on the same platform share one rendered text.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "object",
"properties": {
"hashtags": {
"type": "string",
"maxLength": 500
},
"template": {
"type": "string",
"maxLength": 2000
},
"truncate": {
"enum": [
"smart",
"hard",
"skip"
],
"type": "string"
},
"stripHtml": {
"type": "boolean"
}
}
}
}
},
"description": "Field mapping controlling how each feed item becomes a post."
},
{
"type": "null"
}
],
"description": "New field mapping; pass null to clear back to the built-in default."
},
"requireApproval": {
"type": "boolean",
"description": "Hold items auto-published from this feed for team approval — each generated post lands with approvalStatus 'pending' and waits for approve_post. Only meaningful when mode is 'publish' (draft items never publish on their own, and a feed force-demoted to draft by the plan gate stays ungated). Defaults to false. Forced to true for API keys whose role cannot publish (contributors), regardless of what is sent here and on every update, so reporting it as off would be wrong."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Delete an RSS autopost feed by ID. Stops polling; already-created posts are kept. Use this when the user wants to stop and remove an RSS autopost feed.
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.
feedId
The RSS feed ID to delete.
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.
Description99/100
Start a chunked (multipart) direct-to-storage upload for large media — videos up to 1GB, images up to 100MB. Returns r2Key, uploadId, the fixed partSize (10485760 bytes = 10MB), and one presigned PUT URL per part (valid 3600s). PUT each 10MB slice to its URL, collect each response's ETag header, then call complete_multipart_upload. For ordinary files prefer upload_media. Use this when a file is too large for a single upload (e.g. a video over 100MB, up to 1GB) and must be sent in 10MB chunks.
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.
contentType
File MIME type, e.g. video/mp4 or image/png.
Clear enough to supply this argument.
sizeBytes
Exact file size in bytes. Videos up to 1GB; images up to 100MB.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_multipart_upload",
"title": "Start chunked media upload",
"description": "Start a chunked (multipart) direct-to-storage upload for large media — videos up to 1GB, images up to 100MB. Returns r2Key, uploadId, the fixed partSize (10485760 bytes = 10MB), and one presigned PUT URL per part (valid 3600s). PUT each 10MB slice to its URL, collect each response's ETag header, then call complete_multipart_upload. For ordinary files prefer upload_media. Use this when a file is too large for a single upload (e.g. a video over 100MB, up to 1GB) and must be sent in 10MB chunks.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"contentType",
"sizeBytes"
],
"properties": {
"sizeBytes": {
"type": "number",
"description": "Exact file size in bytes. Videos up to 1GB; images up to 100MB."
},
"contentType": {
"type": "string",
"description": "File MIME type, e.g. video/mp4 or image/png."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Complete a chunked upload: the server assembles the uploaded parts, verifies the stored object (existence, size, magic bytes, storage quota) and records the media file — same verification and response shape as finalize_media_upload. A failed assembly automatically aborts the upload. Use this when all parts of a chunked upload are PUT and their ETags collected.
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.
r2Key
The r2Key returned by create_multipart_upload.
Clear enough to supply this argument.
uploadId
The uploadId returned by create_multipart_upload.
Clear enough to supply this argument.
parts › items › partNumber
1-based part number.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parts › items › etag
ETag response header from the part PUT.
Clear enough to supply this argument.
fileName
Original file name.
Clear enough to supply this argument.
mimeType
File MIME type.
Clear enough to supply this argument.
sizeBytes
File size in bytes.
Clear enough to supply this argument.
width
Pixel width (images/video).
Clear enough to supply this argument.
height
Pixel height (images/video).
Clear enough to supply this argument.
duration
Duration in seconds (video).
Explain what happens when this optional value is omitted.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Abort an in-progress chunked upload and permanently free its stored parts. Use only when the upload should be cancelled; do not use this after all parts have been uploaded if you intend to complete the upload. This action cannot be undone. Use this when a chunked upload should be cancelled and its stored parts freed.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Input documentation gives an agent enough context to populate the arguments.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "abort_multipart_upload",
"title": "Abort chunked media upload",
"description": "Abort an in-progress chunked upload and permanently free its stored parts. Use only when the upload should be cancelled; do not use this after all parts have been uploaded if you intend to complete the upload. This action cannot be undone. Use this when a chunked upload should be cancelled and its stored parts freed.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"r2Key",
"uploadId"
],
"properties": {
"r2Key": {
"type": "string",
"description": "The r2Key returned by create_multipart_upload."
},
"uploadId": {
"type": "string",
"description": "The uploadId returned by create_multipart_upload."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/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.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
from
Start date (ISO, e.g. 2025-01-01). Defaults to 30 days ago.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/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.
Inputs84/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.
Description77/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.
Description84/100
Open an interactive view of current account usage — daily/monthly post counts, channel counts, and media storage. Use this when the user wants a visual view of their plan usage.
The description explains the capability, when to use it, and what to expect.
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.
Inputs85/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.
Description96/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.
Inputs78/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.
Clear enough to supply this argument.
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.
Description97/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.
Inputs93/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.
Description89/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.
Description91/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.
Description91/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.
05View mediaOpen an interactive gallery of uploaded media files with thumbnails and metadata.
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/full.
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 82/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 80 of 80 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?
update_template is the lowest-scoring reviewed tool at 59/100. No output schema is declared. Add one for structured results so clients can interpret returned fields. 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.