Update post
update_postEdits caption, title, description, first comment, custom thumbnail (image URL or timeline frame), and platform-specific settings on any not-yet-published post — drafts, ready-to-publish, scheduled, and failed posts are all editable. Writes to the shared video_settings row so every unpublished post attached to the same upload sees the change. Use platform_caption / platform_first_comment for per-platform overrides on this post's platform. Refuses posts that are already queued for publish, currently processing, or already published. Captions over a platform's limit are rejected (a shared caption is checked against every unpublished post on the upload). Fixing the caption of a post that failed for an over-limit caption re-queues it automatically — the result's status shows where it went. Custom covers (custom_thumbnail_url / custom_thumbnail_upload_id) apply to video posts on YouTube, Instagram Reels, Facebook Reels and Pinterest; image posts don't take a cover.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | New title. Used by YouTube, Facebook, Pinterest, Tumblr (an optional heading above the post text) and Reddit (the post title, max 300 chars, only when platform_settings.title is empty); ignored by platforms without a title concept. This is the upload's shared title, so changing it also changes the YouTube, Facebook, Pinterest and Tumblr titles of the same upload. To set a Reddit-only title, use platform_settings.title on the Reddit post instead. | |
| caption | No | New shared caption. Applies to every platform that doesn't have a per-platform override. | |
| description | No | New long-form description. Used by YouTube, Facebook, Pinterest, Tumblr and Reddit. On Pinterest this is the pin description; on Tumblr it is the post text; on Reddit it is the post body. | |
| first_comment | No | Shared first comment. Auto-posted after the post by platforms that support it (YouTube, Instagram, Facebook, Threads, Bluesky, X, LinkedIn, Mastodon, and Discord: in Discord text channels it's a separate message right after the post, in forum channels the first reply in the post's thread). Empty string clears it. | |
| video_post_id | Yes | The video_posts.id whose text/settings you want to edit. | |
| idempotency_key | No | Optional client-generated key (e.g., a UUID) to make retries safe. Identical calls with the same key within 10 minutes return the original result instead of running the write twice. | |
| platform_caption | No | Per-platform caption override for this post's platform. Overrides `caption` on that one platform only; leave empty string to clear. Do NOT use for Pinterest or YouTube: those platforms use `title` and `description` instead of captions. On Tumblr it overrides the description as the post text. | |
| platform_settings | No | AI-generated label, by platform: TikTok isAigc, Instagram isAiGenerated, Facebook isAiGenerated (Reels, photos and carousels), YouTube containsSyntheticMedia; when the user wants content labelled as AI-generated, set it on each of these platforms the upload has a post on. Partial per-platform settings blob for this post's platform. Shallow-merged into video_settings.platform_settings[platform] — keys you pass overwrite, keys you omit are preserved. Keys are stored in camelCase; snake_case keys are converted automatically. Shape is platform-specific: TikTok has privacyLevel, disableComment, disableDuet, disableStitch, isAigc (boolean — labels the post as AI-generated content), commercialContentDisclosure (boolean — must be true for isYourBrand/isBrandedContent to take effect), isYourBrand, isBrandedContent, and autoAddMusic (photo/carousel only — TikTok auto-picks background music); YouTube has tags/categoryId/playlistIds/privacyStatus/madeForKids/containsSyntheticMedia (boolean — AI/altered-content disclosure); Instagram has collaborators/userTags/locationId/shareToFeed/shareToStory/storyOnly (Story only, no Reel or feed post; single videos up to 60 seconds, single images and carousels, which go to Stories as one frame per slide with video slides over 60 seconds left out)/trialReel (boolean; Reels only: posts a Trial Reel shown to non-followers first)/trialGraduationStrategy ("SS_PERFORMANCE" (default): Instagram shares it with followers automatically if it performs well; "MANUAL": the user shares it from the Instagram app; Instagram has no time-based option)/isPaidPartnership/brandPartners (string[], up to 2 brand usernames on a paid partnership; needs Facebook Login for Instagram; for a sponsored post also set TikTok commercialContentDisclosure + isBrandedContent and YouTube hasPaidProductPlacement)/productTags (array of {product_id, x?, y?} from the account's Instagram Shop, single images and Reels; beta, needs Facebook Login for Instagram)/poll ({ options: 2 to 4 strings of max 25 chars, extended: boolean, keeps it open past 3 days }; feed posts, carousels and Reels, the caption is the question; beta, needs Facebook Login for Instagram or the post fails)/commentPrompt (boolean; the caption becomes a prompt answered in the comments; not with poll; beta, needs Facebook Login for Instagram or the post fails)/storyCaption (boolean; shows the caption on the Story, first frame only on carousels; beta)/isAiGenerated (boolean — adds Instagram's "AI info" label)/altText (string, single image posts, alt text for screen readers, max 1000 chars)/altTexts (object, carousels: alt text per image keyed by the image's upload id); Facebook has shareToStory/storyOnly (single videos up to 60 seconds and single photos)/isAiGenerated (boolean; adds Facebook's "AI info" label to Reels, photos and carousels, not to Stories or text posts); LinkedIn has visibility ("PUBLIC" | "CONNECTIONS" | "LOGGED_IN"; Company Pages always post PUBLIC), plus on text posts only either poll ({ question: max 140 chars, options: 2 to 4 strings of max 30 chars, duration: "ONE_DAY" | "THREE_DAYS" | "SEVEN_DAYS" | "FOURTEEN_DAYS", default SEVEN_DAYS }; single choice, can't be edited once posted) or document ({ url: public https URL to a .pdf, .ppt, .pptx, .doc or .docx up to 100 MB and 300 pages, title: name shown on the document }), not both; set either to null to remove it; Mastodon has visibility ("public" | "unlisted" | "private"), language (BCP-47), textOnly, and on text posts only poll ({ options: 2 to 4 strings of max 50 chars, durationMinutes: 5 to 10080, default 1440, multiple: boolean });X (twitter) and Threads also take poll on text posts only (the caption is the question): X { options: 2 to 4 strings of max 25 chars, durationMinutes: 5 to 10080, default 1440 }, Threads { options: 2 to 4 strings of max 25 chars }, open 24 hours; Telegram and Discord take poll on text posts with its own question: Telegram { question: max 300 chars, options: 2 to 10 strings of max 100 chars, multiple: boolean }, sent alone when the caption equals the question, otherwise right after the caption, and open until closed in Telegram; Discord { question: max 300 chars, options: 2 to 10 strings of max 55 chars, durationMinutes: whole hours 60 to 46080, default 1440, multiple: boolean }; Telegram has textOnly; Discord has channelIds (array of channel ids from list_discord_channels; omit to post to every default channel), silent (boolean — no push/desktop notifications), mention ("none" | "here" | "everyone", default "none"), threadName (forum post title, max 100 chars — needed for forum channels, falls back to the caption's first line), username (overrides the webhook's display name, max 80 chars, must not contain "discord"), and textOnly (boolean, video uploads only — sends just the caption as a plain channel message); Discord has no custom thumbnail, and its first comment (max 2000 chars) is posted only in forum channels, as the first reply in the post's thread; Tumblr has blogName (short name of one of the connection's blogs; omit to post to the primary blog), tags (array of strings, no "#", no commas, max 30), title (optional heading above the post text, max 4096 chars; overrides the shared title), and textOnly (boolean, video uploads only — posts just the title and post text as a text post); Tumblr's post text is the description (up to 5,000 chars), falling back to the caption; Tumblr has no custom thumbnail and no first comment; Reddit has subreddit (required; bare name like "AskReddit", "r/AskReddit" also works, or "u_username" for the user's own profile; a bare name is always a subreddit, so "jane" posts to r/jane, never to u/jane), title (the Reddit post title, max 300 chars; the publisher reads platform_settings.title first and only falls back to the upload's shared title when it's empty, so set it here to give Reddit its own title without touching other platforms' titles), nsfw (boolean, default false), and flairId (id from the subreddit's flair list; some subreddits require a flair); Reddit's post body is the description; Reddit has no carousels, no custom thumbnail and no first comment; Pixelfed has visibility ("public" | "unlisted" | "private", default "public"), sensitive (boolean, default false — blurs the media behind a warning), and spoilerText (content-warning text, max 140 chars, only used when sensitive is true); Pixelfed has no custom thumbnail, and its first comment (max 500 chars) is posted as a reply under the post; Google Business Profile (google_business) has locationIds (array of location ids from the google_business connection's `locations` in list_platform_connections; omit to post to the default locations; the post fans out to each), ctaType (optional button: "BOOK" | "ORDER" | "SHOP" | "LEARN_MORE" | "SIGN_UP" | "CALL"; null clears it), ctaUrl (http(s) link, required with every ctaType except CALL, which dials the profile's phone number), and textOnly (boolean, video uploads only; posts just the caption, since Google Business Profile can't post video); Google Business Profile has a 1500-character caption, no custom thumbnail and no first comment; Snapchat has formats (array of "spotlight" and/or "story", at least one) and skipSaveToProfile (boolean, Spotlight-only — hides the video from the Public Profile grid but keeps it in the discovery feed). Hashtags aren't a separate field on Snapchat — write them inline in the caption (Spotlight caption cap 160 chars; Story doesn't use the caption at all). Pinterest has link (destination URL where users land after tapping the pin, must be a full URL like https://example.com), boardId (target board ID — required for publishing), boardName (display name, optional), and altText (screen-reader text, max 500 chars). Call get_post_details first to see the current values, and only touch keys you understand. | |
| follow_up_comments | No | Up to 4 more comments after the first comment (5 per post in total), posted on the same platforms as the first comment. Shared by every post of the upload; passing it replaces the current list, [] clears it. Not posted on X, which only gets the first comment. On Threads, Bluesky, Mastodon and Pixelfed each one replies to the previous comment, so they read as a thread. | |
| custom_thumbnail_url | No | Public https:// URL to a cover/thumbnail image (jpeg, png, webp, or gif, max 20 MB). ShortSync downloads the image, stores it in the workspace's bucket, and attaches it to the video_settings row so every unpublished post on this upload uses it at publish time. Used as the cover on YouTube, Instagram Reels, Facebook Reels and Pinterest; other platforms pick their own cover (TikTok uses a frame, set with thumbnail_timestamp_ms). Pass an empty string to remove the current custom thumbnail. Same SSRF guards as create_video_upload_from_url apply: https only, public IPs, Content-Length required. Mutually exclusive with thumbnail_timestamp_ms. | |
| first_comment_enabled | No | Set false to skip the first comment on this post's platform entirely (neither the per-platform nor the shared first comment is posted). Set true to turn it back on. Same toggle as the dashboard's per-platform first-comment switch. | |
| platform_first_comment | No | Per-platform first comment override for this post's platform. Empty string clears the override and falls back to the shared first_comment. | |
| thumbnail_timestamp_ms | No | Extract a frame from the upload's own video at this timestamp (milliseconds from the start) and store it as the video's 'Thumbnail from Timeline' (video_settings.generated_thumbnail_url), matching what the dashboard scrubber writes. Video-only: refuses text posts, image uploads, and carousel parents. Must be within the video's duration. Publish-time behavior: this DOES NOT overwrite a custom_thumbnail_url the user already set. Platforms that read `custom_thumbnail_url || generated_thumbnail_url` (YouTube, Facebook Reels, Pinterest, and others) will use this timeline frame only when no custom cover is present. Platforms that read custom only (Instagram in particular) will NOT use this frame as a cover — pass custom_thumbnail_url or custom_thumbnail_upload_id for those. If the user wants the timeline frame to override an existing custom cover, first clear the custom with `custom_thumbnail_url: ""`, then set the timestamp. Mutually exclusive with custom_thumbnail_url and custom_thumbnail_upload_id. | |
| custom_thumbnail_upload_id | No | Alternative to custom_thumbnail_url: reference an existing image upload (a video_uploads row whose content_type is 'image') and use it as the cover for this post. Use this when the user already uploaded the cover image via create_video_upload_from_url or create_video_upload and wants to attach it to a video's post rather than re-hosting it publicly. The image must be in the same workspace as this post. Mutually exclusive with custom_thumbnail_url and thumbnail_timestamp_ms. | |
| first_comment_delay_minutes | No | Minutes after the post goes live to post the first comment. 0 = right away (default). Up to 10080 (7 days). Shared by every post of the upload. |