Skip to main content
Glama

create_and_publish_post

Destructive

Create a new post and publish it immediately (no scheduling). Same media rules, channel IDs, and workspace selection rule as create_post apply (only one workspace → use it; multiple workspaces with no named one → ask first; named workspace → use and remember; mention workspace name on success). linkedin (personal profile) and linkedin_page (company page) are independent channels.

Pinterest board (auto-default to first board): If Pinterest is in channels and pinterest.board_id is NOT provided, do NOT block on asking — and do NOT skip Pinterest. Call get_account on the Pinterest account, take the FIRST board from the returned boards list, and pass its id as pinterest.board_id. In your reply, mention which board you used (e.g. "Published to your 'Marketing' board on Pinterest — let me know if you'd prefer a different one.") so the user can redirect. If the user named a specific board in the request, match it (case-insensitive) against the list and use that one instead.

X threads: For a chained X thread, pass x.thread_parts (2–25 { text } parts, each <= 280 chars). Do NOT split into "1/", "2/" inside content — that posts a single tweet, not a thread.

X posts containing a link: X treats a post whose text contains a link written with http:// or https:// as a link post (a bare domain or a www. link does not count). Link posts on X are a feature the organisation enables on its OmniSocials account. When it is not enabled, the request is refused up front with an x_feature_not_enabled error, or the X target alone fails while the other platforms still publish: tell the user, offer to post without the link or without X, and do not retry as is. Never remove a user's link without asking them.

Input Schema

NameRequiredDescriptionDefault
xNoX (Twitter) options: thread mode via `thread_parts`, a poll via `poll`.
typeNo
tiktokNoTikTok options
blueskyNoBluesky options, including thread mode via `thread_parts`.
contentYesPost caption. String or object with platform keys for per-channel captions: { "default": "fallback", "linkedin": "long", "threads": "short" }. Prefer one call per topic.
discordNoDiscord options. The post goes to the connected Discord channel through its webhook and shows the webhook's name and picture. Text up to 2,000 chars. Up to 10 images, GIFs and videos per message (they may mix); a video or GIF over Discord's 20 MB file limit is sent as a link in the text. No Stories; a 'reel' is sent as one video message.
threadsNoThreads options: thread mode via `thread_parts`, location tag via `location_id`, a poll via `poll`, the topic via `topic_tag`.
youtubeNoYouTube Shorts options. Only applies when type is 'reel' and youtube is among the selected channels. A custom Shorts thumbnail is set with the top-level `video_cover` (a `youtube` override for a YouTube-only image); it shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (Partner Program channels first, since July 2026), other channels show a frame from the video.
channelsNoArray of channel IDs to post to (e.g. linkedin, linkedin_page, instagram).
facebookNoFacebook options
link_urlNoURL to share as a rich preview card on platforms that support link-share posts (LinkedIn and Facebook). Renders as a tile with thumbnail/title/description instead of plain text. Ignored on platforms that don't support link shares, and ignored on posts that already have media attached (media wins).
linkedinNoLinkedIn Profile options
mastodonNoMastodon options: thread mode via `thread_parts`, a poll via `poll`.
telegramNoTelegram options. Text up to 4,096 chars; with media, text over 1,024 chars is sent as a reply under the media. Up to 10 photos and videos per album, videos up to 50 MB, no Stories. A 'reel' is sent as a video message.
instagramNoInstagram options
media_fitNoImage fit per channel, for feed images (type 'post') whose ratio is outside what a channel shows uncropped: { instagram: 'auto' | 'crop' | 'keep', pinterest: ... }. 'auto' (the default when omitted) takes the channel's rule: Instagram crops a tall (9:16) or wide image to 4:5 / 1.91:1 around the subject (Instagram cuts it to that window anyway, and Meta cannot boost a feed post outside it); Pinterest keeps a Pin taller than 2:3 and only reports it. 'crop' / 'keep' force it for that channel. Every decision comes back in the response `warnings` with code `image_fit` (relay it). The crop is a separate file for that channel only; 'default' and the other channels keep the original. On update_post, media_fit alone (no media) re-decides the stored images: 'keep' gives the original back, 'crop' crops an image that was kept.
media_idsNo
pinterestNo
user_tagsNoInstagram only. Tag public accounts at x/y positions on a PHOTO (not video/reels/stories). For a single image omit image_index; for a carousel, set image_index to the slide each tag belongs to. Private/non-existent usernames are rejected at publish time. Ignored by other platforms.
link_titleNoOptional title for the link-share preview. LinkedIn uses this when set; Facebook ignores it and fetches OG metadata server-side. Omit to let LinkedIn auto-fetch the page title.
media_urlsNoExternal image/video/PDF URLs — flat array or per-platform object. Max 10 total (Pinterest: max 5 images per carousel pin), each file ≤ 100 MB. Entries are URL strings or { url, alt } objects (alt = accessibility description, delivered to Mastodon/Bluesky/X/Pinterest/Instagram (images)/LinkedIn (images)). For larger files (up to 1 GB): upload_media with method 'url' first, then pass the returned media id in `media`.
hashtag_setNoName of a saved hashtag set (from list_hashtag_sets, matched case-insensitively) to apply to this post. The set's tags are merged in once at create time; tags already present in a caption are skipped. When the user says something like 'add my usual hashtags', check list_hashtag_sets first. Instagram's 5-hashtag cap is enforced with a clear error (hashtag_limit_exceeded).
location_idNoInstagram only. Facebook Place ID for a single physical venue (with a street address) to tag the post's location. Find it via the location search in the OmniSocials dashboard. Ignored by other platforms.
video_coverNoVideo thumbnail for a post whose media is ONE video. Applied on Instagram (feed videos and reels), Facebook (feed videos and reels), LinkedIn Profile and Page, TikTok, Pinterest and YouTube Shorts. YouTube Shorts: the cover shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (rolling out since July 2026, Partner Program channels first); on other channels YouTube stores it as the default thumbnail but shows a frame from the video on Shorts. Say that it depends on the channel; do not promise it. TikTok only takes a frame: a 'custom' cover is skipped there, so add a tiktok override with type 'frame' when the user wants a specific TikTok frame. The per-platform reel fields (instagram.thumb_offset / cover_url, tiktok.video_cover_timestamp_ms, pinterest.video_cover) keep working and win over the base cover for their platform. get_post reads it back as `video_cover`.
collaboratorsNoInstagram only. Up to 3 public Instagram usernames to invite as co-authors (the 'Collab' feature). Works on image, carousel, and reel posts — NOT Stories. Invited users get an invite in the Instagram app; once they accept, the post also appears on their profile and feed. A leading '@' is stripped; usernames are case-insensitive. Private or non-existent usernames are rejected by Instagram at publish time. Ignored by other platforms.
linkedin_pageNoLinkedIn Company Page options
linkedin_pollNoNon-sponsored LinkedIn poll(s) — independent per channel, keyed by `linkedin` (personal profile) / `linkedin_page` (company page). A poll is mutually exclusive with media and a link share on that channel's post — a poll takes priority over both at publish time. Still requires `content.linkedin` (or `content.default`) as that channel's caption; the poll itself only carries the question/options/duration. On update_post, set a channel's key to `null` to clear that channel's poll and revert it to a normal post — send the full desired state for both channels, since the whole object replaces wholesale.
google_businessNoGoogle Business Profile options. Use to publish EVENT or OFFER posts, attach a CTA button, or both. Shape mirrors Google's LocalPost resource (see https://developers.google.com/my-business/reference/rest/v4/accounts.locations.localPosts#LocalPost). Google Business caption rules (enforced at scheduling — text that violates these will return a `validation_error` 400 before the post is saved): • Phone numbers in the caption are rejected — use a CALL button instead. • Inline URLs / bare domains / emails are rejected — use LEARN_MORE / BOOK / SHOP / SIGN_UP / ORDER buttons instead. • Caption max 1500 characters. • Media is optional (text-only posts are allowed). If attached: exactly one JPEG/PNG/WebP image (no video, no carousels). • The workspace must have a Google Business location selected (Settings → Organisation → Workspaces → Google Business) before scheduling — otherwise returns a 400.
link_descriptionNoOptional description for the link-share preview. LinkedIn uses this when set; Facebook auto-fetches the OG description.
hashtag_placementNoWhere the set's tags land. caption_append (default): appended to each target caption after a blank line. first_comment: posted as the auto first comment on Instagram/Facebook/LinkedIn/LinkedIn Page/YouTube/TikTok (TikTok only when the workspace enabled TikTok comments) (keeps hashtags out of the caption — appended after any explicit first_comment); platforms without a comment API fall back to caption_append. Stories always use captions.
hashtag_platformsNoOptional subset of the post's channels to apply the hashtag set to (e.g. ["instagram", "tiktok"]). Defaults to all selected channels.
link_thumbnail_urlNoOptional thumbnail image URL for the preview card. Currently applied on Facebook; reserved for LinkedIn.
comment_dm_automationNoComment-to-DM automation on this post: when somebody comments one of trigger.keywords on the post once it is live on Instagram or the Facebook Page, the account DMs them actions.dm.text once (on Facebook the DM lands in Messenger), and optionally posts one of actions.public_reply.variations under the comment. Instagram or Facebook must be in channels; platforms picks which ones get it. Show the user the keywords and the exact DM text before creating it. The created automations come back as comment_dm_automation on the post (automations lists the id of each channel); manage them later with update_automation / get_automation_activity.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / mastodon / description
      Previous value: -"Mastodon options, including thread mode via `thread_parts`."New value: +"Mastodon options: thread mode via `thread_parts`, a poll via `poll`."
    • addedInput schema / properties / mastodon / properties / poll
      Added value: +{
      +  "anyOf": [
      +    {
      +      "properties": {
      +        "expires_in": {
      +          "description": "How long the poll runs, in seconds, within the instance's range (Mastodon's defaults: 5 minutes to 1 month). Default 86400 (one day).",
      +          "maximum": 9007199254740991,
      +          "minimum": 300,
      +          "type": "integer"
      +        },
      +        "hide_totals": {
      +          "description": "Hide the vote counts until the poll ends.",
      +          "type": "boolean"
      +        },
      +        "multiple": {
      +          "description": "Allow several answers per person.",
      +          "type": "boolean"
      +        },
      +        "options": {
      +          "description": "The answer options, all different; count and length within the instance's limits (Mastodon's defaults: 4 options of 50 characters).",
      +          "items": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "minItems": 2,
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "options"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Attach a poll to the status; the status text is the question. No media on Mastodon together with a poll. On a thread the poll goes on the first status. On update_post, null removes it."
      +}
    • changedInput schema / properties / threads / description
      Previous value: -"Threads options: thread mode via `thread_parts`, location tag via `location_id`."New value: +"Threads options: thread mode via `thread_parts`, location tag via `location_id`, a poll via `poll`, the topic via `topic_tag`."
    • addedInput schema / properties / threads / properties / poll
      Added value: +{
      +  "anyOf": [
      +    {
      +      "properties": {
      +        "options": {
      +          "description": "2 to 4 answer options of 1 to 25 characters, all different.",
      +          "items": {
      +            "maxLength": 25,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 4,
      +          "minItems": 2,
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "options"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Attach a poll to the post; the post text is the question. Threads closes the poll 24 hours after it is published (no duration). Polls go on text-only posts: no media on Threads together with a poll. On a thread the poll goes on the first post. On update_post, null removes it."
      +}
    • addedInput schema / properties / threads / properties / topic_tag
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 50,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The topic of the post on Threads, one per post, e.g. \"Build in public\". Unlike a #tag in the text it can hold spaces. 1 to 50 characters, no period (.) and no ampersand (&); a leading # is dropped. On a multi-post thread the topic goes on the first post. On update_post, pass null to remove it."
      +}
    • changedInput schema / properties / x / description
      Previous value: -"X (Twitter) options, including thread mode via `thread_parts`."New value: +"X (Twitter) options: thread mode via `thread_parts`, a poll via `poll`."
    • addedInput schema / properties / x / properties / poll
      Added value: +{
      +  "anyOf": [
      +    {
      +      "properties": {
      +        "duration_minutes": {
      +          "description": "How long the poll runs, in minutes (5 to 10080 = 7 days). Default 1440 (one day).",
      +          "maximum": 10080,
      +          "minimum": 5,
      +          "type": "integer"
      +        },
      +        "options": {
      +          "description": "2 to 4 answer options of up to 25 characters, all different.",
      +          "items": {
      +            "maxLength": 25,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 4,
      +          "minItems": 2,
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "options"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Attach a poll to the tweet; the tweet text is the question. No media on X together with a poll. On a thread the poll goes on the first tweet. On update_post, null removes it."
      +}
  2. Changed10 schema fields changed
    • removedInput schema / properties / comment_dm_automation / properties / limits / properties / stop_at / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / comment_dm_automation / properties / limits / properties / stop_at / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedInput schema / properties / discord / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "allow_mentions": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "true lets @everyone, @here, role and user mentions in the text notify people. Off by default: mentions show as text and ping nobody. Only turn it on when the user asks to ping."
      -      },
      -      "buttons": {
      -        "anyOf": [
      -          {
      -            "items": {
      -              "properties": {
      -                "text": {
      -                  "description": "Button label (1 to 80 chars).",
      -                  "maxLength": 80,
      -                  "type": "string"
      -                },
      -                "url": {
      -                  "description": "Link the button opens: https:// or http://.",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "text",
      -                "url"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 5,
      -            "type": "array"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Up to 5 link buttons in one row under the message. Not with a poll."
      -      },
      -      "link_preview": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "false hides the previews of the links in the text (shown by default)."
      -      },
      -      "poll": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "duration_hours": {
      -                "description": "Hours the poll stays open (1 to 768, 32 days). Default 24.",
      -                "maximum": 768,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "multiple": {
      -                "description": "Allow several answers per person.",
      -                "type": "boolean"
      -              },
      -              "options": {
      -                "description": "2 to 10 answer options of up to 55 chars, all different.",
      -                "items": {
      -                  "maxLength": 55,
      -                  "type": "string"
      -                },
      -                "maxItems": 10,
      -                "minItems": 2,
      -                "type": "array"
      -              }
      -            },
      -            "required": [
      -              "options"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "A native Discord poll. The post text is the question (max 300 chars). No media and no buttons with a poll. On update_post, null removes it."
      -      },
      -      "silent": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Send without a push or desktop notification (Discord's @silent)."
      -      },
      -      "spoiler": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Blur every image and video until someone clicks it."
      -      },
      -      "thread_name": {
      -        "anyOf": [
      -          {
      -            "maxLength": 100,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "The post title in a forum or media channel, where Discord requires one (max 100 chars). Only for those channels: a text channel takes none, so the post goes out there without it (warning thread_name_ignored)."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "allow_mentions": {
      +        "description": "true lets @everyone, @here, role and user mentions in the text notify people. Off by default: mentions show as text and ping nobody. Only turn it on when the user asks to ping.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "buttons": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "properties": {
      +                "text": {
      +                  "description": "Button label (1 to 80 chars).",
      +                  "maxLength": 80,
      +                  "type": "string"
      +                },
      +                "url": {
      +                  "description": "Link the button opens: https:// or http://.",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "text",
      +                "url"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 5,
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Up to 5 link buttons in one row under the message. Not with a poll."
      +      },
      +      "link_preview": {
      +        "description": "false hides the previews of the links in the text (shown by default).",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "poll": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "duration_hours": {
      +                "description": "Hours the poll stays open (1 to 768, 32 days). Default 24.",
      +                "maximum": 768,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "multiple": {
      +                "description": "Allow several answers per person.",
      +                "type": "boolean"
      +              },
      +              "options": {
      +                "description": "2 to 10 answer options of up to 55 chars, all different.",
      +                "items": {
      +                  "maxLength": 55,
      +                  "type": "string"
      +                },
      +                "maxItems": 10,
      +                "minItems": 2,
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "options"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "A native Discord poll. The post text is the question (max 300 chars). No media and no buttons with a poll. On update_post, null removes it."
      +      },
      +      "silent": {
      +        "description": "Send without a push or desktop notification (Discord's @silent).",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "spoiler": {
      +        "description": "Blur every image and video until someone clicks it.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "thread_name": {
      +        "anyOf": [
      +          {
      +            "maxLength": 100,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The post title in a forum or media channel, where Discord requires one (max 100 chars). Only for those channels: a text channel takes none, so the post goes out there without it (warning thread_name_ignored)."
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedInput schema / properties / linkedin / properties / carousel_as_images / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / linkedin / properties / carousel_as_images / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
    • removedInput schema / properties / linkedin_page / properties / carousel_as_images / anyOf
      Removed value: -[
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / linkedin_page / properties / carousel_as_images / type
      Added value: +[
      +  "boolean",
      +  "null"
      +]
    • changedInput schema / properties / telegram / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "buttons": {
      -        "anyOf": [
      -          {
      -            "items": {
      -              "properties": {
      -                "text": {
      -                  "description": "Button label (max 64 chars).",
      -                  "maxLength": 64,
      -                  "type": "string"
      -                },
      -                "url": {
      -                  "description": "Link the button opens: https://, http:// or tg://.",
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "text",
      -                "url"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 3,
      -            "type": "array"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Up to 3 link buttons under the post, one per row. Not on an album (2+ media) or a poll."
      -      },
      -      "caption_above_media": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Show the text above the media instead of below."
      -      },
      -      "first_comment": {
      -        "description": "A reply the bot sends under the post right after it is published.",
      -        "maxLength": 4096,
      -        "type": "string"
      -      },
      -      "link_preview": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "false hides the link preview of a text-only post (shown by default)."
      -      },
      -      "pin": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Pin the post in the chat after it is sent. Needs the bot's Edit messages right in a channel (Pin messages in a group); without it the post is sent unpinned."
      -      },
      -      "poll": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "multiple": {
      -                "description": "Allow several answers per person.",
      -                "type": "boolean"
      -              },
      -              "open_period": {
      -                "description": "Seconds the poll stays open (5 s to about 30 days). Omit to keep it open.",
      -                "maximum": 2628000,
      -                "minimum": 5,
      -                "type": "integer"
      -              },
      -              "options": {
      -                "description": "2 to 12 answer options of up to 100 chars, all different.",
      -                "items": {
      -                  "maxLength": 100,
      -                  "type": "string"
      -                },
      -                "maxItems": 12,
      -                "minItems": 2,
      -                "type": "array"
      -              }
      -            },
      -            "required": [
      -              "options"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "A native Telegram poll. The post text is the question (max 300 chars). No media with a poll. On update_post, null removes it."
      -      },
      -      "protect_content": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Stop forwarding and saving of the post in Telegram apps."
      -      },
      -      "silent": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Send without a notification sound."
      -      },
      -      "spoiler": {
      -        "anyOf": [
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Blur the photos and videos until someone taps them."
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "buttons": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "properties": {
      +                "text": {
      +                  "description": "Button label (max 64 chars).",
      +                  "maxLength": 64,
      +                  "type": "string"
      +                },
      +                "url": {
      +                  "description": "Link the button opens: https://, http:// or tg://.",
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "text",
      +                "url"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 3,
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Up to 3 link buttons under the post, one per row. Not on an album (2+ media) or a poll."
      +      },
      +      "caption_above_media": {
      +        "description": "Show the text above the media instead of below.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "first_comment": {
      +        "description": "A reply the bot sends under the post right after it is published.",
      +        "maxLength": 4096,
      +        "type": "string"
      +      },
      +      "link_preview": {
      +        "description": "false hides the link preview of a text-only post (shown by default).",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "pin": {
      +        "description": "Pin the post in the chat after it is sent. Needs the bot's Edit messages right in a channel (Pin messages in a group); without it the post is sent unpinned.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "poll": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "multiple": {
      +                "description": "Allow several answers per person.",
      +                "type": "boolean"
      +              },
      +              "open_period": {
      +                "description": "Seconds the poll stays open (5 s to about 30 days). Omit to keep it open.",
      +                "maximum": 2628000,
      +                "minimum": 5,
      +                "type": "integer"
      +              },
      +              "options": {
      +                "description": "2 to 12 answer options of up to 100 chars, all different.",
      +                "items": {
      +                  "maxLength": 100,
      +                  "type": "string"
      +                },
      +                "maxItems": 12,
      +                "minItems": 2,
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "options"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "A native Telegram poll. The post text is the question (max 300 chars). No media with a poll. On update_post, null removes it."
      +      },
      +      "protect_content": {
      +        "description": "Stop forwarding and saving of the post in Telegram apps.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "silent": {
      +        "description": "Send without a notification sound.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "spoiler": {
      +        "description": "Blur the photos and videos until someone taps them.",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedInput schema / properties / threads / properties / location_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / threads / properties / location_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  3. Changed3 schema fields changed
    • changedInput schema / properties / comment_dm_automation / description
      Previous value: -"Comment-to-DM automation on this post: when somebody comments one of trigger.keywords on the post once it is live on Instagram, the account DMs them actions.dm.text once, and optionally posts one of actions.public_reply.variations under the comment. Instagram must be in channels. Show the user the keywords and the exact DM text before creating it. The created automation comes back as comment_dm_automation on the post; manage it later with update_automation / get_automation_activity."New value: +"Comment-to-DM automation on this post: when somebody comments one of trigger.keywords on the post once it is live on Instagram or the Facebook Page, the account DMs them actions.dm.text once (on Facebook the DM lands in Messenger), and optionally posts one of actions.public_reply.variations under the comment. Instagram or Facebook must be in channels; platforms picks which ones get it. Show the user the keywords and the exact DM text before creating it. The created automations come back as comment_dm_automation on the post (automations lists the id of each channel); manage them later with update_automation / get_automation_activity."
    • addedInput schema / properties / comment_dm_automation / properties / platforms
      Added value: +{
      +  "description": "The channels that get the automation: 'instagram', 'facebook' (the Facebook Page; the DM lands in Messenger) or both. One automation per channel, each with the same keywords, DM, public reply and limits. Each one must be in channels. Omit it for one automation: Instagram when the post goes there, else Facebook.",
      +  "items": {
      +    "enum": [
      +      "instagram",
      +      "facebook"
      +    ],
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedInput schema / properties / discord
      Added value: +{
      +  "anyOf": [
      +    {
      +      "properties": {
      +        "allow_mentions": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "true lets @everyone, @here, role and user mentions in the text notify people. Off by default: mentions show as text and ping nobody. Only turn it on when the user asks to ping."
      +        },
      +        "buttons": {
      +          "anyOf": [
      +            {
      +              "items": {
      +                "properties": {
      +                  "text": {
      +                    "description": "Button label (1 to 80 chars).",
      +                    "maxLength": 80,
      +                    "type": "string"
      +                  },
      +                  "url": {
      +                    "description": "Link the button opens: https:// or http://.",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "text",
      +                  "url"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 5,
      +              "type": "array"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Up to 5 link buttons in one row under the message. Not with a poll."
      +        },
      +        "link_preview": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "false hides the previews of the links in the text (shown by default)."
      +        },
      +        "poll": {
      +          "anyOf": [
      +            {
      +              "properties": {
      +                "duration_hours": {
      +                  "description": "Hours the poll stays open (1 to 768, 32 days). Default 24.",
      +                  "maximum": 768,
      +                  "minimum": 1,
      +                  "type": "integer"
      +                },
      +                "multiple": {
      +                  "description": "Allow several answers per person.",
      +                  "type": "boolean"
      +                },
      +                "options": {
      +                  "description": "2 to 10 answer options of up to 55 chars, all different.",
      +                  "items": {
      +                    "maxLength": 55,
      +                    "type": "string"
      +                  },
      +                  "maxItems": 10,
      +                  "minItems": 2,
      +                  "type": "array"
      +                }
      +              },
      +              "required": [
      +                "options"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "A native Discord poll. The post text is the question (max 300 chars). No media and no buttons with a poll. On update_post, null removes it."
      +        },
      +        "silent": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Send without a push or desktop notification (Discord's @silent)."
      +        },
      +        "spoiler": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Blur every image and video until someone clicks it."
      +        },
      +        "thread_name": {
      +          "anyOf": [
      +            {
      +              "maxLength": 100,
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "The post title in a forum or media channel, where Discord requires one (max 100 chars). Only for those channels: a text channel takes none, so the post goes out there without it (warning thread_name_ignored)."
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Discord options. The post goes to the connected Discord channel through its webhook and shows the webhook's name and picture. Text up to 2,000 chars. Up to 10 images, GIFs and videos per message (they may mix); a video or GIF over Discord's 20 MB file limit is sent as a link in the text. No Stories; a 'reel' is sent as one video message."
      +}
  4. Changed1 schema field changed
    • changedInput schema / properties / bluesky / properties / thread_parts / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "properties": {
      -        "media_ids": {
      -          "description": "Per-post media as Library IDs from upload_media (max 4) — bare IDs or { id, alt } objects. A part is one video OR up to 4 images.",
      -          "items": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "properties": {
      -                  "alt": {
      -                    "description": "Accessibility description (alt text) for this media item, shown to screen-reader users (max 1500 chars). Applied on Mastodon, Bluesky, X, Pinterest, Instagram (images and carousel image slides — not Reels/Stories) and LinkedIn (images only — not video or documents). Describe what the image shows; strongly valued by the Mastodon/Bluesky communities.",
      -                    "maxLength": 1500,
      -                    "type": "string"
      -                  },
      -                  "id": {
      -                    "description": "Library media ID from upload_media",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "id"
      -                ],
      -                "type": "object"
      -              }
      -            ]
      -          },
      -          "maxItems": 4,
      -          "type": "array"
      -        },
      -        "media_urls": {
      -          "description": "Per-post media as external URLs (max 4) — URL strings or { url, alt } objects. A part is one video OR up to 4 images.",
      -          "items": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "properties": {
      -                  "alt": {
      -                    "description": "Accessibility description (alt text) for this media item, shown to screen-reader users (max 1500 chars). Applied on Mastodon, Bluesky, X, Pinterest, Instagram (images and carousel image slides — not Reels/Stories) and LinkedIn (images only — not video or documents). Describe what the image shows; strongly valued by the Mastodon/Bluesky communities.",
      -                    "maxLength": 1500,
      -                    "type": "string"
      -                  },
      -                  "url": {
      -                    "description": "External media URL",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "url"
      -                ],
      -                "type": "object"
      -              }
      -            ]
      -          },
      -          "maxItems": 4,
      -          "type": "array"
      -        },
      -        "text": {
      -          "description": "Post text (≤ 300 chars, counted as graphemes — one emoji = 1)",
      -          "type": "string"
      -        }
      -      },
      -      "required": [
      -        "text"
      -      ],
      -      "type": "object"
      -    },
      -    "maxItems": 25,
      -    "minItems": 2,
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "properties": {
      +        "media_ids": {
      +          "description": "Per-post media as Library IDs from upload_media (max 10) — bare IDs or { id, alt } objects. A part is one video OR up to 10 images (5 or more post as a gallery).",
      +          "items": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "properties": {
      +                  "alt": {
      +                    "description": "Accessibility description (alt text) for this media item, shown to screen-reader users (max 1500 chars). Applied on Mastodon, Bluesky, X, Pinterest, Instagram (images and carousel image slides — not Reels/Stories) and LinkedIn (images only — not video or documents). Describe what the image shows; strongly valued by the Mastodon/Bluesky communities.",
      +                    "maxLength": 1500,
      +                    "type": "string"
      +                  },
      +                  "id": {
      +                    "description": "Library media ID from upload_media",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "id"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "maxItems": 10,
      +          "type": "array"
      +        },
      +        "media_urls": {
      +          "description": "Per-post media as external URLs (max 10) — URL strings or { url, alt } objects. A part is one video OR up to 10 images (5 or more post as a gallery).",
      +          "items": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "properties": {
      +                  "alt": {
      +                    "description": "Accessibility description (alt text) for this media item, shown to screen-reader users (max 1500 chars). Applied on Mastodon, Bluesky, X, Pinterest, Instagram (images and carousel image slides — not Reels/Stories) and LinkedIn (images only — not video or documents). Describe what the image shows; strongly valued by the Mastodon/Bluesky communities.",
      +                    "maxLength": 1500,
      +                    "type": "string"
      +                  },
      +                  "url": {
      +                    "description": "External media URL",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "url"
      +                ],
      +                "type": "object"
      +              }
      +            ]
      +          },
      +          "maxItems": 10,
      +          "type": "array"
      +        },
      +        "text": {
      +          "description": "Post text (≤ 300 chars, counted as graphemes — one emoji = 1)",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "text"
      +      ],
      +      "type": "object"
      +    },
      +    "maxItems": 25,
      +    "minItems": 2,
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  5. Changed2 schema fields changed
    • changedInput schema / properties / hashtag_set / description
      Previous value: -"Name of a saved hashtag set (from list_hashtag_sets, matched case-insensitively) to apply to this post. The set's tags are merged in once at create time; tags already present in a caption are skipped. When the user says something like 'add my usual hashtags', check list_hashtag_sets first. Instagram's 30-hashtag cap is enforced with a clear error (hashtag_limit_exceeded)."New value: +"Name of a saved hashtag set (from list_hashtag_sets, matched case-insensitively) to apply to this post. The set's tags are merged in once at create time; tags already present in a caption are skipped. When the user says something like 'add my usual hashtags', check list_hashtag_sets first. Instagram's 5-hashtag cap is enforced with a clear error (hashtag_limit_exceeded)."
    • addedInput schema / properties / telegram
      Added value: +{
      +  "anyOf": [
      +    {
      +      "properties": {
      +        "buttons": {
      +          "anyOf": [
      +            {
      +              "items": {
      +                "properties": {
      +                  "text": {
      +                    "description": "Button label (max 64 chars).",
      +                    "maxLength": 64,
      +                    "type": "string"
      +                  },
      +                  "url": {
      +                    "description": "Link the button opens: https://, http:// or tg://.",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "text",
      +                  "url"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 3,
      +              "type": "array"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Up to 3 link buttons under the post, one per row. Not on an album (2+ media) or a poll."
      +        },
      +        "caption_above_media": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Show the text above the media instead of below."
      +        },
      +        "first_comment": {
      +          "description": "A reply the bot sends under the post right after it is published.",
      +          "maxLength": 4096,
      +          "type": "string"
      +        },
      +        "link_preview": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "false hides the link preview of a text-only post (shown by default)."
      +        },
      +        "pin": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Pin the post in the chat after it is sent. Needs the bot's Edit messages right in a channel (Pin messages in a group); without it the post is sent unpinned."
      +        },
      +        "poll": {
      +          "anyOf": [
      +            {
      +              "properties": {
      +                "multiple": {
      +                  "description": "Allow several answers per person.",
      +                  "type": "boolean"
      +                },
      +                "open_period": {
      +                  "description": "Seconds the poll stays open (5 s to about 30 days). Omit to keep it open.",
      +                  "maximum": 2628000,
      +                  "minimum": 5,
      +                  "type": "integer"
      +                },
      +                "options": {
      +                  "description": "2 to 12 answer options of up to 100 chars, all different.",
      +                  "items": {
      +                    "maxLength": 100,
      +                    "type": "string"
      +                  },
      +                  "maxItems": 12,
      +                  "minItems": 2,
      +                  "type": "array"
      +                }
      +              },
      +              "required": [
      +                "options"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "A native Telegram poll. The post text is the question (max 300 chars). No media with a poll. On update_post, null removes it."
      +        },
      +        "protect_content": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Stop forwarding and saving of the post in Telegram apps."
      +        },
      +        "silent": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Send without a notification sound."
      +        },
      +        "spoiler": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Blur the photos and videos until someone taps them."
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Telegram options. Text up to 4,096 chars; with media, text over 1,024 chars is sent as a reply under the media. Up to 10 photos and videos per album, videos up to 50 MB, no Stories. A 'reel' is sent as a video message."
      +}
  6. Changed1 schema field changed
    • changedInput schema / properties / pinterest / properties / product_tags / description
      Previous value: -"Products to tag on the Pin, so people can shop the items in the image. Up to 24 product Pins of the connected Pinterest account, each as a Pin ID string or a Pin link (https://www.pinterest.com/pin/<id>/). Get the IDs with list_pinterest_products. Only the account's own product Pins can be tagged (public, with a link on a website the account claimed on Pinterest); products of other merchants cannot. The tags are added right after the Pin is published; a product Pinterest refuses never fails the post, and get_post shows the outcome (product_tags_result). On update_post the pinterest object replaces the stored one, so leave product_tags out to remove the tags."New value: +"Product Pins to tag on the Pin (Pinterest shows the tagged items on the image). Up to 24 product Pins of the connected Pinterest account, each as a Pin ID string or a Pin link (https://www.pinterest.com/pin/<id>/). Get the IDs with list_pinterest_products. Only the account's own product Pins can be tagged (public, with a link on a website the account claimed on Pinterest); products of other merchants cannot. The tags are added right after the Pin is published; a product Pinterest refuses never fails the post, and get_post shows the outcome (product_tags_result). On update_post the pinterest object replaces the stored one, so leave product_tags out to remove the tags."
  7. Changed4 schema fields changed
    • addedInput schema / properties / comment_dm_automation
      Added value: +{
      +  "description": "Comment-to-DM automation on this post: when somebody comments one of trigger.keywords on the post once it is live on Instagram, the account DMs them actions.dm.text once, and optionally posts one of actions.public_reply.variations under the comment. Instagram must be in channels. Show the user the keywords and the exact DM text before creating it. The created automation comes back as comment_dm_automation on the post; manage it later with update_automation / get_automation_activity.",
      +  "properties": {
      +    "actions": {
      +      "properties": {
      +        "dm": {
      +          "properties": {
      +            "text": {
      +              "description": "The DM the person receives, once (max 1000 characters). Confirm the text with the user: it goes out in their name.",
      +              "maxLength": 1000,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "text"
      +          ],
      +          "type": "object"
      +        },
      +        "public_reply": {
      +          "properties": {
      +            "enabled": {
      +              "type": "boolean"
      +            },
      +            "variations": {
      +              "description": "Public replies posted under the comment, one picked at random per comment.",
      +              "items": {
      +                "maxLength": 300,
      +                "type": "string"
      +              },
      +              "maxItems": 10,
      +              "type": "array"
      +            }
      +          },
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "dm"
      +      ],
      +      "type": "object"
      +    },
      +    "limits": {
      +      "properties": {
      +        "max_sends": {
      +          "anyOf": [
      +            {
      +              "exclusiveMinimum": 0,
      +              "maximum": 9007199254740991,
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Stop after this many DMs."
      +        },
      +        "stop_at": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Stop at this time (ISO 8601)."
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "trigger": {
      +      "properties": {
      +        "keywords": {
      +          "description": "Keywords that start the automation, matched case-insensitively (up to 20). Required unless match is 'any'.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "maxItems": 20,
      +          "type": "array"
      +        },
      +        "match": {
      +          "description": "word (default): the keyword stands on its own. contains: anywhere in the comment. any: every comment (ask the user first).",
      +          "enum": [
      +            "word",
      +            "contains",
      +            "any"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "actions"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / google_business / properties / event / description
      Previous value: -"Required when topic_type is EVENT."New value: +"Required when topic_type is EVENT or OFFER. For an OFFER, the title is the offer's name and the schedule its validity period (Google rejects an offer without it)."
    • addedInput schema / properties / media_fit
      Added value: +{
      +  "additionalProperties": {
      +    "enum": [
      +      "auto",
      +      "crop",
      +      "keep"
      +    ],
      +    "type": "string"
      +  },
      +  "description": "Image fit per channel, for feed images (type 'post') whose ratio is outside what a channel shows uncropped: { instagram: 'auto' | 'crop' | 'keep', pinterest: ... }. 'auto' (the default when omitted) takes the channel's rule: Instagram crops a tall (9:16) or wide image to 4:5 / 1.91:1 around the subject (Instagram cuts it to that window anyway, and Meta cannot boost a feed post outside it); Pinterest keeps a Pin taller than 2:3 and only reports it. 'crop' / 'keep' force it for that channel. Every decision comes back in the response `warnings` with code `image_fit` (relay it). The crop is a separate file for that channel only; 'default' and the other channels keep the original. On update_post, media_fit alone (no media) re-decides the stored images: 'keep' gives the original back, 'crop' crops an image that was kept.",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / youtube / properties / title / description
      Previous value: -"Short title shown on YouTube. Falls back to \"YouTube Short\" when omitted."New value: +"Short title shown on YouTube (max 100 characters). When omitted, the first line of the caption is used; \"YouTube Short\" only when there is no caption either."
  8. Changed1 schema field changed
    • addedInput schema / properties / pinterest / properties / product_tags
      Added value: +{
      +  "description": "Products to tag on the Pin, so people can shop the items in the image. Up to 24 product Pins of the connected Pinterest account, each as a Pin ID string or a Pin link (https://www.pinterest.com/pin/<id>/). Get the IDs with list_pinterest_products. Only the account's own product Pins can be tagged (public, with a link on a website the account claimed on Pinterest); products of other merchants cannot. The tags are added right after the Pin is published; a product Pinterest refuses never fails the post, and get_post shows the outcome (product_tags_result). On update_post the pinterest object replaces the stored one, so leave product_tags out to remove the tags.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 24,
      +  "type": "array"
      +}
  9. Changed5 schema fields changed
    • addedInput schema / properties / facebook / properties / cover_url
      Added value: +{
      +  "description": "Custom thumbnail image URL (JPEG/PNG, max 10 MB). Used with thumbnail_type 'from-library'.",
      +  "type": "string"
      +}
    • addedInput schema / properties / facebook / properties / thumb_offset
      Added value: +{
      +  "description": "Frame timestamp in MILLISECONDS from the start of the video (e.g. 3000 = 0:03). Used with thumbnail_type 'from-video'.",
      +  "type": "number"
      +}
    • addedInput schema / properties / facebook / properties / thumbnail_type
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "from-video",
      +        "from-library"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Video thumbnail for Facebook feed videos and reels: 'from-video' uses the frame at thumb_offset, 'from-library' uploads the image at cover_url. Applied after the video is live; a thumbnail failure never fails the post. On update_post, null removes the Facebook override."
      +}
    • addedInput schema / properties / video_cover
      Added value: +{
      +  "description": "Video thumbnail for a post whose media is ONE video. Applied on Instagram (feed videos and reels), Facebook (feed videos and reels), LinkedIn Profile and Page, TikTok, Pinterest and YouTube Shorts. YouTube Shorts: the cover shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (rolling out since July 2026, Partner Program channels first); on other channels YouTube stores it as the default thumbnail but shows a frame from the video on Shorts. Say that it depends on the channel; do not promise it. TikTok only takes a frame: a 'custom' cover is skipped there, so add a tiktok override with type 'frame' when the user wants a specific TikTok frame. The per-platform reel fields (instagram.thumb_offset / cover_url, tiktok.video_cover_timestamp_ms, pinterest.video_cover) keep working and win over the base cover for their platform. get_post reads it back as `video_cover`.",
      +  "properties": {
      +    "cover_url": {
      +      "description": "Public image URL, JPEG or PNG (type 'custom').",
      +      "type": "string"
      +    },
      +    "overrides": {
      +      "additionalProperties": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "cover_url": {
      +                "description": "Public image URL, JPEG or PNG (type 'custom').",
      +                "type": "string"
      +              },
      +              "thumb_offset": {
      +                "description": "Milliseconds into the video (type 'frame'). 3000 = 0:03.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "type": {
      +                "description": "'frame' uses the video frame at thumb_offset; 'custom' uploads the image at cover_url.",
      +                "enum": [
      +                  "frame",
      +                  "custom"
      +                ],
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "description": "Per-platform overrides keyed by platform id (instagram, facebook, linkedin, linkedin_page, tiktok, pinterest, youtube). An override wins over the base cover for that platform.",
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "thumb_offset": {
      +      "description": "Milliseconds into the video (type 'frame'). 3000 = 0:03.",
      +      "maximum": 9007199254740991,
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "type": {
      +      "description": "'frame' uses the video frame at thumb_offset; 'custom' uploads the image at cover_url.",
      +      "enum": [
      +        "frame",
      +        "custom"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "type"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / youtube / description
      Previous value: -"YouTube Shorts options. Only applies when type is 'reel' and youtube is among the selected channels."New value: +"YouTube Shorts options. Only applies when type is 'reel' and youtube is among the selected channels. A custom Shorts thumbnail is set with the top-level `video_cover` (a `youtube` override for a YouTube-only image); it shows on Shorts only on channels where YouTube has enabled custom Shorts thumbnails (Partner Program channels first, since July 2026), other channels show a frame from the video."
  10. First observed

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag this as non-read-only, destructive, and open-world, but the description adds substantial operational context: workspace-asking rules, Pinterest auto-default behavior, X link-post failure handling, and the instruction not to retry or remove links without asking. These are exactly the kind of publish-time behavioral traits an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is long and dense, but front-loads the core purpose and uses bold headers to separate exceptional cases. Most sentences earn their place given the tool's complexity, though some workspace/media rule repetition could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 33-parameter nested publishing tool with no output schema, the description covers the most error-prone scenarios and references create_post for shared media/workspace rules. It is nearly complete, but the lack of explicit draft/schedule/publish routing against create_post and publish_post leaves a meaningful contextual gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 91%, so the schema carries most parameter documentation. The description still adds meaningful cross-parameter semantics for tricky cases like pinterest.board_id fallback, linkedin vs linkedin_page independence, x.thread_parts behavior, and link-post handling.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource and scope: 'Create a new post and publish it immediately (no scheduling).' This clearly distinguishes it from a scheduling/draft workflow, though it does not explicitly distinguish it from siblings like publish_post or create_post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for immediate publishing and extensive scenario guidance for Pinterest, X threads, links, and workspace selection. It does not explicitly name create_post or publish_post as alternatives for scheduled or existing posts, leaving that routing inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources