Post a video or photo post to TikTok
post_to_tiktokPublish a finished video or TikTok photo post (1-35 images) to a connected account: make it live with the user's chosen privacy, or save it as a draft to finish in the app.
Instructions
Publish to the user’s connected TikTok account — a finished VIDEO, or a PHOTO POST (TikTok’s photo/slideshow format). A photo post carries 1 to 35 images and ONE image is simply a one-slide photo post, so there is nothing special to do for a single picture: pass imageUrls, in the order the slides should appear, and optionally coverIndex. Pass videoUrl for a video. Never pass both — TikTok has no mixed post. TWO destinations. destination:"post" (THE DEFAULT) publishes it LIVE on their profile: TikTok requires the user to CHOOSE the privacy themselves (no default is allowed), so call tiktok_creator_info, show them their real privacy options, and get their choice and an explicit yes before calling. destination:"draft" is ONLY for when the user asks for a draft, or wants to add a TikTok sound or trending audio (TikTok’s API takes no sound for a VIDEO): BEFORE sending, tell them plainly it lands in their TikTok inbox as a DRAFT, that they add the sound in TikTok’s editor, and that THEY must publish it from the TikTok app — nothing goes live until they do. Never pick draft on your own. A photo post published with destination:"post" gets a TikTok-recommended track automatically (autoAddMusic, default on) that they can change in the app. Pass Hermoso render URLs (or upload_file urls for local/external files). Needs TikTok connected (Settings > Connectors > TikTok).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| hook | No | WHAT ANGLE this post is built on, recorded only at publish time. post_performance ranks hooks on it (a winner needs 5 posts sharing ONE hook), so pass a list_hooks id (e.g. "direct_callout", "before_after") or reuse your own wording EXACTLY across a campaign. Omit it and this post never votes on which hook works. | |
| brand | No | WHICH PROFILE this post belongs to — id or exact name from list_brands (a shared workspace: its profile id). Beats the connection's pin for THIS CALL ONLY; a name that matches no profile, or two, is REFUSED and nothing is posted. | |
| title | No | the caption — hashtags go here (video ≤2200 chars, photo post ≤4000) | |
| ideaId | No | short id of the content-plan idea this post came from | |
| recipe | No | the post's FORMAT id, e.g. "slideshow" or "imessage_chat" — post_performance groups by it, so reuse one id per format | |
| account | No | WHICH connected account of this channel to post as — its @handle or id from list_connector_accounts. Needed only when the profile has more than one tiktok account connected (several and none named is refused by name, never guessed); omit when there is one. | |
| privacy | No | REQUIRED for destination:"post", for photos and video alike. Must be one the creator actually allows — read them from tiktok_creator_info, never guess. | |
| subject | No | WHAT THIS POST IS ABOUT — product, feature, offer or theme (e.g. "winter coat", "free trial"). post_performance's second grouping axis: reuse the exact wording, as with hook. | |
| videoUrl | No | the video to post — a Hermoso render URL or an upload_file url. Omit for a photo post. | |
| imageUrls | No | a PHOTO POST: 1–35 image URLs in slide order. One url = a single-image photo post. Do not combine with videoUrl. | |
| yourBrand | No | discloses that this promotes the creator’s own brand | |
| coverIndex | No | photo posts: which slide is the cover, 0-based. Default 0 (the first slide). | |
| photoTitle | No | photo posts only: a short title above the caption (≤90 chars). Defaults to the caption’s first line. | |
| aiGenerated | No | TikTok’s is_aigc AI-generated-content label (video posts). OMIT IT and Hermoso decides from provenance: a Hermoso render is declared, a video that came through upload_file or an external URL (the user’s own footage) is NOT. true/false overrides. | |
| destination | No | "post" (default) = live on the profile now (needs the privacy the user chose + their explicit yes); "draft" = to their TikTok inbox for them to finish and publish in the app — only when they ask for a draft or want to add a TikTok sound, and only after telling them so. | |
| disableDuet | No | video only — TikTok has no duet on a photo post | |
| autoAddMusic | No | photo posts only: let TikTok add a recommended track (default true — a silent slideshow reads as broken) | |
| disableStitch | No | video only — TikTok has no stitch on a photo post | |
| platformCover | No | VIDEO COVER. Omit it (the default) and Hermoso sets the video’s best frame — the same frame as its Library thumbnail — as the cover (TikTok video_cover_timestamp_ms, on a direct post — a draft takes no cover, you pick it in the TikTok app). true = send no cover and let the platform pick (usually the first frame). A cover you pass yourself always wins. | |
| brandedContent | No | discloses a paid partnership — cannot be combined with SELF_ONLY privacy | |
| disableComment | No | ||
| coverTimestampMs | No | video only: which frame to use as the cover, in ms |