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" }.
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. 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."
      +}
  2. 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"
      +  }
      +]
  3. 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"
      +}
  4. First observed

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already convey the mutation (readOnlyHint=false) and destructive/destructiveHint=true nature. The description adds valuable behavioral nuance beyond that: failed posts reset to draft, partial posts stay partial, scheduling a partial post re-queues only failed channels, and status transitions between draft and scheduled. It does not contradict any annotation and explains outcomes that annotations don't cover. A 4 is appropriate because it supplements rather than replaces the annotations.

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?

The description is a single, well-organized paragraph that front-loads the purpose and key rules. It is longer than many descriptions but justified by the tool's complexity, and every sentence carries useful information (editable statuses, status transitions, and sibling routing). It makes efficient use of ~4 sentences and avoids fluff, earning a 4 rather than a 3.

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 tool with 13 parameters and deeply nested platform-specific options, the description provides a solid overview: it names the editable fields, the status constraints, and the alternative publish path. It does not enumerate each platform's details, but the schema covers those thoroughly. Given the output schema exists and annotations cover safety, the description is sufficiently complete for an agent to decide when to invoke it and what it will do. It could mention the ifUnmodifiedSince precondition or approval parameters, but these are already described in the schema, so the description's brevity is acceptable.

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%, so the baseline is 3. The description adds a high-level mapping to 'content, schedule, media, labels, status, and platform-specific settings' but does not go into the meaning of individual parameters beyond that – that detail is already in the schema. It does clarify the behavior of the status parameter (only draft/scheduled allowed, and the effects on failed/partial posts), which is a modest extra. Overall, it meets the baseline without adding much beyond what the schema already states.

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?

The description opens with 'Update an existing post' – a specific verb and resource – and lists the exact fields it can change (content, schedule, media, labels, status, platform-specific settings). It also implicitly distinguishes itself from publish_post by noting 'use publish_post to publish immediately.' This clearly sets it apart from siblings like delete_post or compose_post.

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?

The description gives explicit when-to-use guidance ('Use this when the user wants to edit an existing post') and concrete exclusions: only draft, scheduled, failed, or partial posts can be edited. It also names the alternative (publish_post) for immediate publishing and explains status-transition rules. This is strong routing guidance.

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