Skip to main content
Glama

Update post

update_post
DestructiveIdempotent

Update an existing post. Can change content, schedule, media, labels, status, 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. Use this when the user wants to edit an existing post.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
postIdYesThe post ID to update.
statusNoMove 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.
contentNoNew post text content.
labelIdsNoReplace label IDs on the post.
timezoneNoTimezone for scheduling.
scheduledAtNoNew ISO 8601 scheduled datetime.
mediaFileIdsNoReplace attached media file IDs.
requestApprovalNoOptional (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.
platformSpecificNoPlatform-specific settings, e.g. { "youtube": { "title": "…", "privacyStatus": "public" } }. Reddit, Discord, Tumblr and Snapchat nest their options under the BulkPublish channel id, e.g. { "reddit": { "12": { "subreddit": "webdev" } } }. Telegram takes no options.
ifUnmodifiedSinceNoOptional 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.
postTypeOverridesNoPer-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).
publishWhenApprovedNoOptional. 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'.
linkTrackingOverrideNoOptional 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.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNo
authorNoWho wrote the post: { id, name, image }. Null when that account is gone.
labelsNo
statusNodraft, scheduled, processing, published, partial or failed.
contentNo
approverNoWho approved it: { id, name, image }. Null unless approvalStatus is approved.
assigneeNoWho is expected to act on it next: { id, name, image }. Null when nobody is.
timezoneNo
createdAtNo
mediaFilesNo
publishedAtNo
scheduledAtNo
postPlatformsNo
approvalStatusNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / platformSpecific / properties / snapchat / description
      Previous value: -"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, videos 5–60s, spotlight 6–60s video-only, max 1GB). 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."New value: +"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."
    • changedInput schema / properties / postTypeOverrides / description
      Previous value: -"Per-platform post type override. E.g. { \"instagram\": \"reel\", \"youtube\": \"short\" }."New value: +"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)."
    • changedInput schema / properties / postTypeOverrides / properties / snapchat / description
      Previous value: -"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."New value: +"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."
  2. Changed23 schema fields changed
    • addedInput schema / properties / ifUnmodifiedSince
      Added value: +{
      +  "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.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / bluesky / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.bluesky = 'repost': the bsky.app post URL (or at:// URI) to repost.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / facebook / properties / thumbnailUrl
      Added value: +{
      +  "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.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / collaborators / description
      Added value: +"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."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / coverUrl
      Added value: +{
      +  "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.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / graduationStrategy / description
      Added value: +"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."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / thumbnailTimestamp / description
      Added value: +"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."
    • addedInput schema / properties / platformSpecific / properties / instagram / properties / trialReel / description
      Added value: +"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."
    • addedInput schema / properties / platformSpecific / properties / mastodon / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.mastodon = 'repost': the status URL or ID to boost.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / locationId
      Added value: +{
      +  "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.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / repostId
      Added value: +{
      +  "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).",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / threads / properties / topicTag
      Added value: +{
      +  "description": "One topic tag for the post, without a leading '#'. Must not contain periods or ampersands.",
      +  "type": "string"
      +}
    • addedInput schema / properties / platformSpecific / properties / tiktok / properties / thumbnailTimestamp / description
      Added value: +"Cover frame for the video, in seconds from the start."
    • changedInput schema / properties / platformSpecific / properties / tumblr / description
      Previous value: -"Tumblr options, nested under the BulkPublish channel id: { \"12\": { \"blogName\": \"myblog\", \"tags\": [\"art\"] } }. A flat object applies to every Tumblr channel on the post. Up to 30 images OR exactly one video per post."New value: +"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."
    • addedInput schema / properties / platformSpecific / properties / x / properties / repostId
      Added value: +{
      +  "description": "With postTypeOverrides.x = 'repost': the X post URL or ID to repost (retweet).",
      +  "type": "string"
      +}
    • changedInput schema / properties / postTypeOverrides / properties / bluesky / enum
      Previous value: -[
      -  "post",
      -  "video"
      -]New value: +[
      +  "post",
      +  "video",
      +  "thread",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / mastodon / enum
      Previous value: -[
      -  "post"
      -]New value: +[
      +  "post",
      +  "thread",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / threads / enum
      Previous value: -[
      -  "text",
      -  "image",
      -  "video",
      -  "carousel"
      -]New value: +[
      +  "text",
      +  "image",
      +  "video",
      +  "carousel",
      +  "repost"
      +]
    • changedInput schema / properties / postTypeOverrides / properties / x / enum
      Previous value: -[
      -  "tweet",
      -  "video",
      -  "thread"
      -]New value: +[
      +  "tweet",
      +  "video",
      +  "thread",
      +  "repost"
      +]
    • addedInput schema / properties / publishWhenApproved
      Added value: +{
      +  "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'.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / approver
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who approved it: { id, name, image }. Null unless approvalStatus is approved."
      +}
    • addedOutput schema / properties / assignee
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who is expected to act on it next: { id, name, image }. Null when nobody is."
      +}
    • addedOutput schema / properties / author
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {},
      +      "properties": {},
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Who wrote the post: { id, name, image }. Null when that account is gone."
      +}
  3. Changed1 schema field changed
    • changedOutput schema / properties / mediaFiles / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": {},
      -      "properties": {},
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "anyOf": [
      +        {
      +          "type": "number"
      +        },
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        }
      +      ]
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  4. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "approvalStatus": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "content": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "createdAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "id": {
      +      "anyOf": [
      +        {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "string"
      +            }
      +          ]
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "labels": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "mediaFiles": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "postPlatforms": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "additionalProperties": {},
      +            "properties": {
      +              "platform": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "status": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "publishedAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "scheduledAt": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "status": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "draft, scheduled, processing, published, partial or failed."
      +    },
      +    "timezone": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
  5. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Annotations declare destructive/openWorld/idempotent, but the description adds concrete behavior beyond them: a failed post is reset to draft, a partial post stays partial, scheduling a partial post re-queues only its failed channels, and approval can be forced server-side for contributor API keys. These are non-obvious side effects an agent must know before mutating.

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?

Front-loaded with the core action and constraints; each sentence carries a distinct rule. The trailing 'Use this when the user wants to edit an existing post' is mild filler that restates the opening.

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?

An output schema exists and the input schema is exhaustively documented, so the description need not explain returns or per-platform options. It covers the state-machine and re-queue behavior well, though it is silent on the concurrency/ifUnmodifiedSince editing discipline that a careful editor would want surfaced.

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

Parameters3/5

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

Schema description coverage is 100% and the description only restates the field list already documented in the schema (content, schedule, media, labels, status, platform settings). It adds the status-legality rule, but that is also spelled out in the status parameter description, so it does not meaningfully exceed the schema.

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

Purpose5/5

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

States a specific verb and resource ('Update an existing post') and enumerates the mutable fields, then explicitly routes immediate publishing to the sibling publish_post. An agent can distinguish this from create_post/publish_post/retry_post without opening any schema.

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

Usage Guidelines5/5

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

Gives explicit eligibility rules ('Only draft, scheduled, failed, or partial posts can be edited'), the state-machine consequence of editing each, and a named alternative with its triggering condition ('use publish_post to publish immediately'). It also states the user intent that selects this tool.

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