Build with Social Publish.
Publish a caption, with media or as text alone, to one or more connected social channels.
Best for
Publish a caption, with media or as text alone, to one or more connected social channels. Use the playground to set up a single step, then open a workflow when you want to connect more tools.
Inputs explained
- Media (required)
- Set the media used by this model. Type: unknown.
- Caption (required)
- Set the caption used by this model. Type: text.
- Accounts (optional)
- Set the accounts used by this model. Type: array.
- Publish at (optional)
- Set the publish at used by this model. Type: text.
- Per-platform overrides (optional)
- Set the per-platform overrides used by this model. Type: json.
- Jitter (minutes) (optional)
- Set the jitter (minutes) used by this model. Type: number.
- Min interval (hours) (optional)
- Set the min interval (hours) used by this model. Type: number.
- Max per day (optional)
- Set the max per day used by this model. Type: number.
- Require caption variation (optional)
- Set the require caption variation used by this model. Type: boolean.
- Source key (optional)
- Set the source key used by this model. Type: text.
Tips before you run
Start with the default settings and change one input at a time. Keep the result you like on your board so the next step can use it.
If you add a reference file, use a link the workflow can read. Check the inputs and credit estimate on the board before starting a run.
Working with this model
Platform options
Pick accounts in the config panel, then set options per platform. Each platform only shows the options it actually supports.
| Platform | Options |
|---|---|
| First comment, alt text for images | |
| YouTube | Title, visibility, go-public time, tags, thumbnail |
| Threads, Bluesky, Mastodon | Alt text for images |
| X (staff preview) | Alt text for an image |
| TikTok | Who can watch, interactions, AI label, cover frame, commercial content, inbox mode |
YouTube visibility: a new node starts at Private, so nobody sees the upload until you pick Unlisted or Public. A node saved before this setting existed keeps posting Public until you change it. Setting a go-public time keeps the video private and lets YouTube publish it at that time; if that time has already passed when the video uploads, it goes public straight away. YouTube may keep uploads from Wireflow private until Google finishes reviewing Wireflow's use of its API; when it does, the result says so. The title falls back to the first line of the caption. Custom thumbnails need a verified YouTube channel.
YouTube tags: type them as a comma separated list, like ai, video, shorts.
Saved config and the API also take a list of strings, like ["ai", "video"].
Anything else, such as a number or an object, is refused before anything is
posted. YouTube keeps 500 characters of tags in total (commas count, and a tag
with a space counts two more), so Wireflow keeps the first tags that fit and
drops the rest.
The first comment and the thumbnail are added after the post is live. If either fails, the post still counts as published, is not re-posted, and the result shows a warning saying what did not happen.
Account ids and per-platform keys
An agent or script sets these in the node's config.
config.accounts is a list of account ids such as native:cm1abc23. List them with GET /api/v1/social/accounts using an API key that has social:read (the MCP list_social_accounts tool returns the same list, but needs the opt-in social:publish permission). An account a person has just connected shows up there on the next call. Details: Social Accounts.
config.perPlatformOverrides is keyed by platform, then by option, for example { "youtube": { "title": "How it was made", "privacy": "unlisted" } }. These are the keys each platform reads:
| Platform | Keys |
|---|---|
linkedin | caption, firstComment, altText |
instagram | caption, firstComment, aiLabel, coverUrl, thumbOffsetMs |
youtube | caption, title, privacy, scheduledPublishAt, tags, thumbnailUrl |
threads | caption, altText |
bluesky | caption, altText |
mastodon | caption, altText |
x | caption, altText |
tiktok | caption, privacyLevel, isAigc, coverTimestampMs, disableComment, disableDuet, disableStitch, brandOrganic, brandContent, uploadToInbox |
What each one takes:
caption: the post text for that platform, used instead of the node's caption. A Threads post's text is its caption. There is no separatetextkey.title(YouTube): up to 100 characters. Without it the title is the first line of the caption.privacy(YouTube):private,unlistedorpublic. Leave it out of a hand-written config and the video posts public. The node panel and the agent door fill inprivatefor you; nothing does that for config you write yourself, so set it.scheduledPublishAt(YouTube): an ISO 8601 time. The video stays private until then. A time that has already passed means public now.tags(YouTube): comma separated, such as"ai, video", or a list of strings, such as["ai", "video"]. Anything else is refused. YouTube keeps 500 characters of tags in total; the first tags that fit are kept.thumbnailUrl(YouTube): a public https URL. Needs a verified channel.firstComment(LinkedIn, Instagram): text posted as a comment right after the post goes live. Instagram caps it at 2,200 characters, 5 @mentions and 1 link.altText(LinkedIn, Threads, Bluesky, Mastodon, X): one image description, used for every image. X takes it on an image, never a video, and charges for it (see X below).aiLabel(Instagram):trueorfalse. On unless you sendfalse.coverUrl(Instagram Reels): a public https URL of the cover image. Wireflow downloads it and converts it to JPEG, so a private or internal address is refused. Ignored on an image or carousel post.thumbOffsetMs(Instagram Reels): the cover frame, in whole milliseconds into the video, 0 to 900000. WhencoverUrlis also set, the frame wins and the agent door's reply carries a warning saying so.privacyLevel(TikTok):PUBLIC_TO_EVERYONE,MUTUAL_FOLLOW_FRIENDS,FOLLOWER_OF_CREATORorSELF_ONLY. Until TikTok audits Wireflow's app onlySELF_ONLYis accepted (it is the default) and anything else is refused. After the audit there is no default, so set it.isAigc(TikTok):trueorfalse. On unless you sendfalse.coverTimestampMs(TikTok): the cover frame, in whole milliseconds into the video, 0 to 600000. Unset lets TikTok pick the first frame.disableComment,disableDuet,disableStitch(TikTok):trueorfalse. All three aretrue(off) unless you sendfalse, as TikTok requires.brandOrganic,brandContent(TikTok):trueorfalse, defaultfalse.brandOrganiclabels the video "Promotional content".brandContentlabels it "Paid partnership" and it cannot be private.uploadToInbox(TikTok):truesends the video to the creator's TikTok inbox to finish in the app, and the result reads "Sent to TikTok inbox", never "Published". Defaultfalse.
Two more groups of keys are read from config but are not accepted by the agent door: Instagram's shareToFeed, collaborators, trialReel and trialGraduation (the Instagram options described further down), and Mastodon's privacy, which takes public, unlisted or private and means unlisted when unset. The node panel has no field for Mastodon's.
X (staff preview)
Posting to X is open to Wireflow staff while it is in preview. An X post takes
text (up to 280 characters, every link counting 23 and an emoji 2), with one
image or one video, or the caption alone. altText describes the image.
A post to X costs credits:
| Post | Credits |
|---|---|
| Text, image or video | 2 |
| Text with a link (an http(s) or www. link, or a bare domain like wireflow.ai) | 23 |
| Alt text on an image | +1 |
The node panel shows the price for the caption before you post, and the run estimate includes it. The credits are taken just before the post is sent; a short balance is refused before anything reaches X. A post that provably did not go out is refunded, so a post that only goes out on a retry is still charged once. If X does not answer the post request, the credits stay charged, because X may have created the post.
Text-only posts
With NOTHING wired to Media, the caption posts on its own to Threads, Bluesky and Mastodon. Instagram, YouTube and LinkedIn need an image or a video, and TikTok a video, so a text-only post that includes one of them is refused before anything is posted, and the error names the account.
A wired Media port is different. If the node feeding it fails, Social Publish is skipped, exactly as before. If it finishes but hands over nothing that can be posted, the post is refused. Either way the caption never goes out alone.
Captions are checked before anything is posted, never truncated:
- Threads: at most 500 characters, and Meta counts each emoji as its UTF-8 bytes (2 to 4), so emoji use up the limit faster. At most 5 links.
- Bluesky: at most 300 characters.
- Mastodon: the limit is set per server and is checked when the post goes out.
Shorten the caption, or set a shorter one for that platform under per-platform variations.
Source key
Set Source key to the id of the post this one copies, such as an X post or
draft id. Each account gets at most one post per key: running the node again
with the same key returns the post already there, marked duplicate,
instead of posting it twice. A cancelled post does not count, and neither does
one that provably never went out (it could not be queued, or every attempt
failed before posting). A post that failed in a way that may have published it
anyway (a timeout while posting) still counts: on Threads, Wireflow checks the
account's recent posts and posts again only when the earlier one is provably
not there; otherwise the node says so and posts nothing. Connected accounts
only.
Each entry in posts carries the platform's post id (postId) and
liveUrl; a Threads post also carries its own permalink.
When is a post "published"
- LinkedIn video: only after LinkedIn finishes processing the video. If it cannot, nothing is posted and the node reports why.
- YouTube: after the upload, the node waits up to two minutes for YouTube to finish processing. If YouTube rejects the video, the node fails. If it is simply slow, the post is reported published, because the video exists.
- TikTok: when TikTok reports it complete. A private post (every post until TikTok audits Wireflow's app) reads "Posted privately, flip to public in TikTok", never plain Published; inbox mode reads "Sent to TikTok inbox". See TikTok below.
Scheduled posts
A scheduled post that hits a temporary error (a platform outage, a rate limit) is retried with a growing wait, up to five attempts. A post more than 24 hours past its time is not sent at all. The scheduler never sends one post twice: if a run is interrupted mid-publish, the post is marked failed with a note to check the account before posting again.
Posting from an agent
The Wireflow MCP server can post without a node: list_social_accounts,
publish_post, get_post_status, cancel_post and update_post. They need the social:publish
permission, which is off by default and only the account owner can tick on the
authorization screen. publish_post takes an idempotencyKey: an agent
that retries with the same key gets the original post back instead of a second
one. It queues the post and returns right away; get_post_status reports
when it is live, and cancel_post stops a post that is still scheduled.
update_post swaps the thumbnail on a YouTube video that is already live
(thumbnailUrl, a JPG or PNG of at most 2 MB); titles are not editable. The
same ban-safety limits apply as in the node. Omit mediaUrls for a text-only
post (same platforms as the node), and pass sourceKey so one source post
reaches each account once.
For Instagram, publish_post takes firstComment, aiLabel (true or false)
and the Reel cover: coverUrl (a public https image URL) or thumbOffsetMs
(a frame, in whole milliseconds). Set both and the frame wins; the reply says
so in the post's warnings. Collaborators, Trial Reel and share-to-feed are
node-UI only for now; passing them to publish_post is refused.
Connecting an account
Open the node and use the Connect buttons under Accounts. Each one opens the platform's consent screen in a new tab; approve it, come back, and press Refresh. Tokens are stored encrypted and refreshed for you.
Bluesky connects with an app password instead: the button opens a small form
in the node. An agent can start any connection with the MCP
connect_social_account tool, which returns a link for the account owner (or
connects Bluesky with an app password they give it).
Instagram is in preview: until Meta approves the app, the Connect Instagram button is shown only to Wireflow staff and to accounts approved for preview access. A team admin role alone does not show it.
Instagram needs a Business or Creator account. Personal accounts cannot publish through the API.
What gets posted depends on what you wire into Media:
| Media | Posts as |
|---|---|
| One video | A Reel |
| One image | A feed post |
| 2 to 10 files | A carousel (images, videos, or both) |
Images are made to fit Instagram's rules before upload: JPEG, at most 8MB, 320 to 1440 wide, and between 4:5 and 1.91:1. An image outside that range gets white bars rather than a crop, so a 9:16 still posts as 4:5 with bars left and right. Reels must be MP4 or MOV. More than 10 files is refused rather than trimmed.
Selecting an Instagram account shows these options:
- Label as AI-generated. On by default, so every Instagram post goes out
with the "AI info" label (Instagram limits reach for AI-person profiles that
skip it). Turn it off only for real footage. Once a post is sent, the result
shows
aiLabelastrue,false,disabled(the operator kill switch withheld it), orfallback(Instagram refused the label for that media type, so the post went out without it and the result carries a warning: add the label in the app). - Also show Reel in the main feed. On by default. Off keeps the Reel in the Reels tab only.
- Trial Reel. Shows the Reel to non-followers first. Choose whether it is shared with followers when you decide in the app, or automatically if it performs well. Only works on a single video, and cannot have collaborators.
- Cover. A cover image URL, or a frame of the video in milliseconds. The frame wins when both are set.
- Collaborators. Up to 3 usernames. They accept the invite in the app.
Instagram allows 100 API posts per account in any 24 hours, shared with every other tool connected to that account. When it is used up the node fails with a message saying so and posts nothing.
The node waits for Instagram to finish processing each video before publishing
(up to 4 minutes for the whole post) and returns the post's permalink in posts.
Full setup, including the Meta app settings: Publishing to Instagram.
TikTok
TikTok is in preview: the Connect TikTok button is shown only to Wireflow staff while TikTok reviews Wireflow's TikTok app.
Wireflow posts through TikTok's own Content Posting API. Press Connect TikTok, approve on TikTok's consent screen, and come back. Wireflow asks for three permissions: your basic profile, posting videos, and uploading videos to your TikTok inbox. Tokens are stored encrypted and refreshed for you.
Until TikTok audits Wireflow's app, every TikTok post is private. TikTok only accepts "Only me" posts from an app it has not audited yet, and may require the TikTok account itself to be set to private while testing. The post goes out private and the result says so; open it in the TikTok app and change Who can watch to make it public.
Selecting a TikTok account shows the account you are posting to (TikTok's nickname for it) and these options:
- Who can watch. Only me until the audit. After it, you must pick one of the options TikTok offers for your account; there is no default.
- Allow comments, duets, stitches. Off until you turn them on, as TikTok requires. An interaction you turned off for the whole account in TikTok is greyed out.
- Label as AI-generated. On by default, so TikTok shows its "Creator labeled as AI-generated" tag.
- Cover frame. Milliseconds into the video. Unset uses the first frame.
- Disclose commercial content. Off by default. "Your brand" labels the video "Promotional content"; "Branded content" labels it "Paid partnership" and cannot be private.
- Send to my TikTok inbox instead of posting. The video lands in your TikTok inbox and you finish it in the app, for example to add a trending sound. The caption and settings do not travel with it, and the result reads "Sent to TikTok inbox", never "Published".
Each post is one video (MP4, MOV or WebM, up to 10 minutes). The caption is the TikTok caption, up to 2,200 characters.
A TikTok post counts as published when TikTok reports it complete. A public post links the video by TikTok's post id; if TikTok has not released the id within the 8 minute wait (it can lag behind moderation), the post still counts as published, links your profile and says so. TikTok gives no id for a private post, so a private post reads "Posted privately, flip to public in TikTok", links your profile, and never counts as a public post. These are failures, never "published": TikTok failing the video (too long, wrong format), TikTok dropping a direct post into your inbox, and no answer within 8 minutes (the post may still appear, so check the account before posting again).
A TikTok private post or inbox upload counts as posted for a sourceKey: flip the post public in TikTok rather than posting it again. If you deleted the post or discarded the draft, post again with a new sourceKey.
Comments, duets and stitches start off on every TikTok post, as TikTok requires. Tick Allow comments (and duets, stitches) in the node, or pass "disableComment": false from an agent, to turn them on for that post.
Scheduled TikTok posts go out at their exact time, like every other platform. TikTok allows about 15 posts a day per account across all apps.
Approve every post. TikTok's rules say the creator must see each post (the video, the caption and its settings) and agree to it before it goes out. In Wireflow that approval is the node: you see the video and caption you wired in, pick the options, and run or schedule it yourself. Do not build flows that post videos to TikTok that nobody has looked at. By posting, you agree to TikTok's Music Usage Confirmation (and its Branded Content Policy for branded content).
An agent can start the connection with the MCP connect_social_account tool,
or GET /api/social/connect/tiktok with a Wireflow API key that holds
social:publish: both return a link the account owner opens while signed in
to Wireflow. GET /api/social/tiktok/creator-info?accountId=... returns the
same account options the node shows.
Common questions
How do I use Social Publish on Wireflow?
Set the inputs above and choose Open in a workflow. Sign in to save your board, then check its credit estimate before you run.
Can I use Social Publish through an API?
Yes. Save a workflow with this model, then call the Wireflow run API with its workflow ID. The API tab has examples you can copy.
What changes the credit price?
The price shown uses the model defaults. Your inputs and model settings can change the total. The workflow shows an estimate before you run.
Can I connect this to another model?
Yes. Open it in a workflow and connect its output to another node with a matching input type.