Skip to main content

1. Overview

TikTok publishing uses the TikTok Content Posting API v2 (PULL_FROM_URL flow). SocialAPI queries creator info to validate settings, submits a publish job, then polls the status endpoint until the post reaches PUBLISH_COMPLETE or FAILED. Both video and photo carousel formats are supported.

2. Supported media

Single images are not supported. Mixed media (video plus images) is not supported. The media_ids field takes IDs of media you upload first via the media upload flow. SocialAPI resolves each ID to a presigned HTTPS URL that TikTok pulls directly, so the underlying files must remain accessible while the post is being published. Accepted formats. TikTok is strict about formats, and a mismatch is rejected up front rather than failing silently mid-publish:
  • Video posts accept MP4, MOV, or WebM.
  • Photo posts accept JPEG and WebP only. PNG, AVIF, GIF, and other image formats are rejected by TikTok; convert them to JPEG or WebP before uploading.
Media type is resolved for you when omitted. If you do not set media_type, SocialAPI infers it: 2 or more images with no video is treated as a photo carousel, and anything else is treated as a video. Attaching an image to a video post (for example, a single image with no media_type) is rejected with a clear 400 error, not accepted and then silently dropped. See Media type must match the file. Video duration: The maximum video duration is per-creator and returned by the TikTok creator info endpoint. SocialAPI validates duration during POST /v1/posts/validate when the media item includes a duration_seconds field. Photo carousel count: Exactly 2 to 35 images. Fewer than 2 or more than 35 will produce a validation error.

3. Create post

Use POST /v1/posts with targets targeting a TikTok account. The text field becomes the post title or description. privacy_level in platform_data.tiktok is required: TikTok’s Direct Post guidelines prohibit a client-applied default, so SocialAPI enforces an explicit selection. Before publishing, SocialAPI calls the TikTok creator info endpoint to validate the privacy level, check posting availability, and apply creator-level disable flags for comment, duet, and stitch settings.

Video post

Photo carousel post

platform_data.tiktok fields

Creator info and valid privacy levels

Privacy level options differ per creator. Always call POST /v1/posts/validate before publishing to confirm the target privacy level is allowed for the specific account. SocialAPI fetches creator info from TikTok and caches it for 10 minutes.

Publish flow

  1. SocialAPI calls POST /v2/post/publish/creator_info/query/ to get creator settings and allowed privacy levels.
  2. SocialAPI validates the draft (privacy level required, duet/stitch for video, brand content rules).
  3. For video: SocialAPI calls POST /v2/post/publish/video/init/ (PULL_FROM_URL, single media URL).
  4. For photo: SocialAPI calls POST /v2/post/publish/content/init/ (PULL_FROM_URL, array of image URLs).
  5. SocialAPI polls POST /v2/post/publish/status/fetch/ every 3 seconds until PUBLISH_COMPLETE or FAILED, or until a 60-second timeout.
  6. On success, the published item ID is stored and returned.

4. Update post

TikTok does not support editing posts after publication. PATCH /v1/posts/:pid returns 501 Not Supported for TikTok post platforms.

5. Delete post

TikTok does not expose a post deletion endpoint in its Content Posting API. DELETE /v1/posts/:pid returns 501 Not Supported for TikTok post platforms.

6. Retrieve posts

GET /v1/posts returns TikTok posts stored in the SocialAPI database. SocialAPI fetches videos from TikTok via POST /v2/video/list/ (up to 20 per page, paginated by cursor) during background sync. This sync requires the video.list scope, which is subject to TikTok app review and may not be active for all connected accounts. What this means in practice:
  • Posts created through SocialAPI are stored immediately after a successful publish and are returned by GET /v1/posts.
  • Background sync pulls TikTok-native posts (created outside SocialAPI) once the video.list scope is approved for the app.
  • Engagement metrics (likes, comments, shares, views) are populated from the video list response during sync.
Analytics exports (POST /v1/accounts/:id/export) do retrieve full TikTok video data including like_count, comment_count, share_count, view_count, duration, width, and height.

7. Quirks, errors, and recovery

privacy_level is required

privacy_level is required. Omitting it produces an error issue (field privacy_level) from POST /v1/posts/validate and blocks publishing. TikTok’s Direct Post guidelines prohibit any client-applied default, so SocialAPI enforces an explicit selection. The allowed values are not static: they are returned by the TikTok creator info endpoint and vary per account. Validate before publishing to confirm the chosen value is allowed for the target account.

Photo carousels require 2 to 35 images

Sending fewer than 2 or more than 35 media_ids when media_type is "photo" returns a 400 validation error immediately. Single-image photo posts are not supported by TikTok.

Media type must match the file

TikTok publishes videos and photos through different endpoints, and it will not build a video out of an image. If an image reaches the video path (for example, a single image with no media_type, which resolves to a video), TikTok accepts the job but never downloads the file, so it stalls until the 60-second timeout. SocialAPI now blocks this before publishing: both POST /v1/posts/validate and POST /v1/posts return a 400 error on the media field (code validation.media_type_mismatch) telling you to publish the images as a photo post instead. To post images, set media_type to "photo" and attach 2 or more JPEG or WebP images.

Photo posts accept only JPEG and WebP

A photo carousel that includes a PNG, AVIF, GIF, or any non-JPEG/WebP image is rejected with a 400 error on the media field (code validation.unsupported_photo_format) that names the offending format. A video included in a photo post is rejected the same way. Convert images to JPEG or WebP before uploading.

disable_duet and disable_stitch are silently ignored for photo posts

Setting disable_duet: true or disable_stitch: true on a photo carousel post has no effect. TikTok does not expose these controls for photo posts. POST /v1/posts/validate will return a warning (not an error) if these fields are set on a photo post.

brand_content_toggle is incompatible with SELF_ONLY privacy

Setting brand_content_toggle: true alongside privacy_level: "SELF_ONLY" is rejected by TikTok. SocialAPI validates this combination before submitting and returns a 400 error.

video_cover_timestamp_ms applies only to videos

This field is sent only when media_type is "video". It is not included in photo carousel requests.

Creator daily posting limit

When a creator has reached their daily TikTok posting limit, the creator info endpoint returns an empty privacy_level_options list. SocialAPI detects this and returns a 400 validation error with field posting_limit.

Token auto-refresh

TikTok access tokens expire. SocialAPI automatically refreshes them using the stored refresh token before each request. If the refresh token has also expired, the connector returns 401 invalid_token and the account must be reconnected.

Publish timeout

SocialAPI polls the publish status for up to 60 seconds. If TikTok has not completed processing within that window, the post status is set to failed with error code publish_timeout. Retry via POST /v1/posts/:pid/retry.

Error categories


8. Full worked example

This example publishes a video, validates the request first, then creates the post.

Step 1: validate

Expected response (no issues):

Step 2: create post

Expected response:

Handling a failed publish

If TikTok rejects the video during processing, the platform status is failed with an error detail. Inspect the error and retry:

9. Required OAuth scopes

These scopes are requested automatically during the OAuth connect flow (POST /v1/accounts/connect). No additional configuration is required.