TikTok
Video and photo posts, privacy levels, commercial disclosure, and the app audit that decides who can see them.
TikTok accepts video and photo posts. It rejects text-only posts, and it is stricter than the other platforms about who is allowed to publish publicly.
The audit problem
Read this before anything else. TikTok's Content Posting API has two tiers:
- Unaudited app — every post is forced to
SELF_ONLY. Visible to the creator, nobody else. The API accepts the post and returns success. - Audited app — posts can be public.
If your posts publish successfully and no one can see them, this is why, and no amount of debugging your integration will change it. Apply for audit in the TikTok Developer Portal.
A related failure is domain verification: TikTok fetches video from the URL you supply, and refuses URLs on unverified domains with url_ownership_unverified. URLs from /v1/media/upload are on a verified domain, so use them unless you have verified your own.
Video
await cutedyno.posts.create({
content: 'Three ways to use the new grinder.',
media: [{ type: 'video', url: videoUrl }],
accountIds: [tiktokAccountId],
platforms: {
tiktok: {
title: 'Three ways to use the new grinder',
privacy_level: 'PUBLIC_TO_EVERYONE',
disable_duet: true,
video_cover_timestamp_ms: 2000,
},
},
});Publishing is asynchronous on TikTok's side as well as ours: CuteDyno hands over the URL, TikTok downloads and processes the video, and we poll for up to ten minutes before giving up. A post can sit in processing for several minutes for a large video, which is normal.
content becomes the caption. platforms.tiktok.title is the video's title, which TikTok treats separately.
Photos
await cutedyno.posts.create({
content: 'Roastery, 6am.',
media: [
{ type: 'image', url: firstUrl },
{ type: 'image', url: secondUrl },
],
accountIds: [tiktokAccountId],
platforms: { tiktok: { title: 'Roastery, 6am' } },
});Photo titles are capped at 90 characters and trimmed for you, taking the first line or sentence of your caption when you do not supply a title. The caption goes through in full as the description.
Images must be JPEG or WebP. Anything else — PNG, GIF — is converted to JPEG before upload, so you do not have to think about it.
Duration
TikTok's maximum video length depends on the creator's account, not on your app. CuteDyno reads that limit per account and rejects a longer video before uploading, with the account's actual maximum in the message. There is no fixed number to code against.
Options
| Option | Effect |
|---|---|
title | Video title, or photo title. Distinct from the caption. |
privacy_level | PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY. Defaults to the widest the creator allows. |
disable_comment | Turn off comments. |
disable_duet | Turn off duets. |
disable_stitch | Turn off stitches. |
video_cover_timestamp_ms | Frame to use as the cover. Defaults to 1 second in. |
brand_content_toggle | Discloses a paid partnership. |
brand_organic_toggle | Discloses the creator promoting their own brand. |
is_aigc | Marks the video as AI-generated. |
auto_add_music | Let TikTok suggest music for photo posts. |
upload_as_draft | Send to the creator's TikTok drafts instead of publishing. |
privacy_level is validated against what the creator's account actually permits, so a private account cannot be made to post publicly by passing a wider value.
Commercial disclosure
If brand_content_toggle is set, TikTok requires the disclosure to be coherent: branded content cannot also be SELF_ONLY, and you must indicate whether the content promotes the creator, a third party, or both. Incoherent combinations are rejected before upload with a message naming the problem.
Drafts
upload_as_draft: true sends the video to the creator's TikTok inbox instead of publishing. They finish and post it from the app.
This is the honest option for an unaudited app: rather than publishing something only the creator can see, put it in their drafts where they expect to find it. TikTok allows five pending inbox drafts per 24 hours.
Failures worth handling
| Message | Meaning |
|---|---|
unaudited_client_can_only_post_to_private_accounts | Your app is not audited. See above. |
url_ownership_unverified | The media URL's domain is not verified with TikTok. |
spam_risk_too_many_pending_share | Too many pending posts. Slow down. |
| This TikTok account cannot post more right now | The creator hit TikTok's own rate limit. Retry later. |
| Video exceeds TikTok max duration | Shorter video needed; the message carries the account's limit. |
These arrive in results[].error for the TikTok account. Other accounts in the same post are unaffected.
Analytics
Per-video views, likes, comments, and shares, plus follower and video counts on the account. TikTok does not expose audience demographics to the API, so those are unavailable rather than empty.
Comments
Not supported. TikTok has no comment webhook or moderation API for this integration, so TikTok comments do not appear in GET /v1/comments.