Edit a draft
update_content[writes flayr data · write scope] Edits a draft in place; only the fields you pass change. Any media field replaces the draft's media as a set (keeps the id, so queue items still point at it). Refused (409) for archived or already-published items, and a media swap is refused once a queue booked it. labels, opus, videoWatermarked, library and aiGenerated may be changed on published items too. aiGenerated is the post's AI label: false for real footage, null back to automatic. A video draft's custom thumbnail/cover: thumbnailStorageId (an image from upload_media) or thumbnailUrl, or thumbnailFrameOffsetMs for a frame of the video; thumbnailUrl: null clears it. It is sent to YouTube (long-form), Facebook, LinkedIn, Instagram Reels, TikTok and Pinterest at publish.
(Wraps PATCH /api/v2/content/{id}.)
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"id": "<id>"
},
"name": "update_content"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| opus | No | Link this row to an Opus Clip clip (owner only; allowed on published rows) so an Opus project import skips it instead of creating a duplicate. null unlinks. | |
| text | No | ||
| title | No | Shorthand for youtube.title (the video title). No < or >. | |
| images | No | Carousel image URLs. Cannot be combined with the other media fields. | |
| labels | No | Replaces the labels ([] or null clears). Allowed on published items too. Normalized "key:value" labels (keys and values are lower-cased, spaces become "-"). Linked keys: campaign:<media campaign id>, experiment:<experiment id> (+ variant:<name> or the experiment's compareKey), type:<post type> (short, long-form, carousel, image, text, reel, story, poem, timelapse…). Free keys work too: cut:opus, lane:tech, parent:pantheon-part-1, ab:<pair id> (an A/B pair). Labels are copied onto every post made from the draft, and compared in GET /api/v2/analytics/experiments. | |
| credits | No | Creator credits for work this post uses. Added to the published caption above the flayr footer, one line each: model → "Print your own: <url> (model by <author>)"; other kinds → "Credit: <title> by <author> <url>". Never added twice (a URL already in the caption is skipped); on X a shorter line (or no URL) is used, or the credits are left out, before the caption text is ever cut. YouTube: description only, never the title. | |
| library | No | The Library item's own title and description, searchable from the Library. null or "" clears one. Metadata: allowed on published items. Not the same as `title` (the YouTube video title). | |
| youtube | No | Merged into the stored YouTube options. YouTube upload options, applied to YouTube targets only. madeForKids is always sent to YouTube (default false). A missing title is derived from the first sentence of the caption, cut to 100 characters at a word boundary. SCHEDULED UPLOADS: the video is uploaded ahead of scheduledAt. "public" is uploaded as private and released by YouTube at the scheduled time; "unlisted" is watchable by anyone with the link from upload time; "private" stays private. | |
| imageUrl | No | http(s) image URL: the video's thumbnail, or on its own the post's single image. Not with imageStorageId. | |
| videoUrl | No | http(s) URL of the new video. Not with videoStorageId. | |
| platforms | No | ||
| aiGenerated | No | The post's "AI-generated" label toggle: false = real footage (no AI label), true = always label, null = automatic (on when flayr made the media). Metadata: allowed on published items. Removing the `source:ai-generated` label alone does not turn it off. | |
| platformText | No | Per-platform captions: platform id → the caption that platform gets instead of `text`, e.g. { "twitter": "short version" }. Each must fit its platform: X 280 (a link counts 23, an emoji 2), Bluesky 300, Threads 500, Instagram 2200, LinkedIn 3000. Platforms without one get `text` when it fits, else an automatic short version: the first line, the credits in short form, as many hashtags as fit and the short flayr link (hashtags go first, then the credit link becomes "Model by <author>"; words are never cut). PATCH merges: a null (or "") value clears that platform, platformText: null clears all. At publish every platform is validated on its own caption: one failing platform no longer fails the others — the post publishes to the rest and reports the failures in platformErrors. | |
| thumbnailUrl | No | Custom video thumbnail: an http(s) image URL. Not with thumbnailStorageId. null clears. | |
| imageStorageId | No | Uploaded image storageId: the video's thumbnail, or on its own the post's single image. Not with imageUrl. | |
| videoStorageId | No | storageId from uploading to POST /api/v2/media/upload-url's uploadUrl. Not with videoUrl. Another account's upload is refused (422). | |
| videoWatermarked | No | The item's own video already has the "Posted by flayr.social" watermark: publish it as-is. null clears. | |
| thumbnailStorageId | No | Custom video thumbnail: an image storageId from POST /api/v2/media/upload-url. Not with thumbnailUrl. null clears. | |
| thumbnailFrameOffsetMs | No | Use this frame of the video (ms from the start) as the cover. Instagram and TikTok get the offset; YouTube/Facebook/LinkedIn need an image, so pass the captured frame as thumbnailStorageId / thumbnailUrl too. |