API reference
Per-network options
Per-network options are the fields a target's options object carries for one network only — a YouTube title and privacy, a TikTok privacy level, an Instagram placement, a Pinterest board, a Mastodon content warning — on top of the content and files the post shares across every network. Every field for every network is listed here; what a network does not take is reported in the dry run rather than dropped silently. How a target is named and scheduled is on posts.
Per-network options
Everything below goes in a target's options. The ids a few of them need come from lookups on the account, all readable with posts:read: GET /v1/oauth/accounts/{id}/boards (Pinterest), /youtube/playlists, /tiktok/creator (the privacy levels this creator may use) and /mentions?q= (Bluesky and Mastodon handles).
YouTube
title (up to 100; the caption's first line otherwise), description (replaces the caption), privacy (public, unlisted, private; public by default), tags (a list; 500 characters across all of them, counting commas and quotes — tags past that are left off), categoryId (YouTube's own id; 22, People & Blogs, by default and for an unknown one), madeForKids, containsSyntheticMedia (realistic altered or AI-made content), short (adds #Shorts; YouTube decides from the file whether it is a Short), defaultLanguage and defaultAudioLanguage (BCP-47), notifySubscribers: false, thumbnailMediaId (an uploaded JPEG or PNG up to 2 MB, on a verified channel), playlistId, captions and firstComment (posted as the channel once the video is public; if refused, the video stands and the target carries a warning).
{ "platform": "youtube",
"options": {
"title": "Weekly Mix #14", "privacy": "public",
"tags": ["house", "dj set"], "categoryId": "10", "madeForKids": false,
"thumbnailMediaId": "4a71…", "playlistId": "PLx0sYbCqOb8…",
"scheduleOnYouTube": true, "firstComment": "Tracklist in the description.",
"captions": [ { "language": "cs", "name": "", "content": "1\n00:00:01,000 --> 00:00:04,000\nAhoj…" } ]
} }With scheduleOnYouTube on a public video scheduled more than 20 minutes ahead, the upload starts up to three hours before scheduledAt, private, and YouTube itself makes it public on the minute. Rescheduling or editing the caption afterwards is passed on to YouTube; the file cannot be swapped, and deleting the post deletes the waiting video. captions is a list of tracks with a language, an optional name and the file's text as content — SRT, WebVTT or SBV, up to 400 KB and five tracks. Anything YouTube would not do — a thumbnail on an unverified channel, a playlist that is gone, a track it refuses — does not fail the post and is reported in the target's warning.
TikTok
privacy (PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY; SELF_ONLY by default, and a level the creator may not use falls back to it), disableComment, disableDuet and disableStitch (video), yourBrand and brandedContent (branded content cannot be private), aiGenerated, coverTimestampMs (a video's cover frame), asDraft (to the creator's TikTok inbox to finish in the app).
Pictures instead of a video make a photo post of up to 35, with photoCoverIndex for the cover. TikTok takes pictures only as JPEG or WebP up to 1080p, so each is converted and fitted on the way. Set autoAddMusic and TikTok adds a track of its own choosing — the post then shows that track rather than an original sound.
{ "platform": "tiktok",
"options": { "privacy": "PUBLIC_TO_EVERYONE", "autoAddMusic": true, "photoCoverIndex": 0 } }Instagram and Facebook
placement: feed (default) or story — a story needs a file and carries no caption. firstComment is posted under the post once it is up; if refused, the post stands and the target carries a warning. The same option works on YouTube and LinkedIn. Instagram also takes collaborators (usernames), and on a single video trialReel (MANUAL or SS_PERFORMANCE, shown only to non-followers first; collaborators are dropped on a trial), shareToFeed: false to keep it off the grid and thumbnailMediaId for the cover. On Facebook, asReel posts a single video of 3 to 90 seconds as a reel. Instagram takes JPEG pictures only, up to 8 MB; any other picture is converted to a JPEG when it is published, so PNG, WebP or HEIC can be sent as they are.
{ "platform": "instagram",
"options": { "trialReel": "SS_PERFORMANCE", "shareToFeed": false,
"thumbnailMediaId": "4a71…", "firstComment": "Tracklist in bio." } }boardId is required, and a pin needs a picture; video is not taken. title (up to 100) defaults to the first line; the description is the rest, up to 500. The pin links to the post's linkUrl.
Threads, Mastodon, Telegram and Discord
Threads: topicTag (up to 50), replyControl (everyone, followers_only, accounts_you_follow, mentioned_only, parent_post_author_only) and poll, 2 to 4 answers of up to 25 characters on a post without files. Mastodon: visibility (public, unlisted, private, direct), spoilerText for a content warning (it counts towards the limit), sensitive and language (two or three letters, such as cs); the thread's replies share the audience and warning. Telegram: silent, pin (the bot needs the right to pin), protectContent, spoiler and noLinkPreview; 1,024 characters with a file, 4,096 without. Discord: username (up to 80, without "discord" or "clyde"), avatarUrl (https), threadName (up to 100) for a forum channel and silent.
[
{ "platform": "mastodon", "options": { "visibility": "unlisted", "spoilerText": "Spoilers", "language": "cs" } },
{ "platform": "telegram", "options": { "silent": true, "pin": true } },
{ "platform": "discord", "options": { "username": "Weekly Mix", "threadName": "Mix #14" } }
]X, LinkedIn, Bluesky and Tumblr
X posts text only, with thread for a thread. LinkedIn posts to a personal profile: up to 20 pictures or one video (up to 30 minutes and 500 MB), or linkUrl as an article card when there is no file; it takes firstComment and alt text. Bluesky links URLs, mentions and hashtags from the text itself and takes thread. Tumblr posts to the main blog: up to 30 pictures or one video (up to 10 minutes and 500 MB); tags is a comma-separated list, and without it hashtags on the caption's last line become the tags. All of them take caption.
Questions: info@preflight.social. The same API as a schema: openapi.json (OpenAPI 3.1).
Write it once. Let the rules be our problem.
Preflight checks every post against each network's rules before it leaves, then publishes it to twelve networks. Free plan, no card.