Skip to content

TikTok API

Postproxy publishes single videos and photo posts (up to 35 images) to a connected TikTok account.

Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.

Every post targets one or more profiles. A profile is one connected account — for TikTok, a TikTok account. Reference one in a request by its id (the prof_abc123 in the examples below) or by the platform name "tiktok", which selects the group’s TikTok profile (a group holds at most one profile per platform). List what’s connected with GET /api/profiles.

Profiles live in profile groups — containers that organize the accounts for one brand, client, or project. List groups with GET /api/profile_groups, and connect a new TikTok profile with the Initialize Connection endpoint.

Example: get profiles and profile groups

List the profiles you can post to — GET /api/profiles:

Terminal window
curl -X GET "https://api.postproxy.dev/api/profiles" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "prof_abc123",
"name": "@mycompany",
"platform": "tiktok",
"status": "active",
"profile_group_id": "grp_xyz789",
"expires_at": null,
"post_count": 47,
"avatar_url": "https://cdn.postproxy.dev/uploads/avatar_prof_abc123.jpg"
}
]
}

List your profile groups — GET /api/profile_groups:

Terminal window
curl -X GET "https://api.postproxy.dev/api/profile_groups" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{ "id": "grp_xyz789", "name": "Main Brand", "profiles_count": 5 },
{ "id": "grp_def456", "name": "Client Project", "profiles_count": 3 }
]
}

TikTok connections — from the app, onboarding, an “Ask colleague” link, or POST /api/profile_groups/:id/initialize_connection — run through TikTok’s Business API. The profile is still platform: "tiktok", so nothing changes in how you address it in a request.

Profiles connected on or after 2026-09-30 get two things earlier TikTok connections can’t have:

  • Comments — list, reply, delete, hide/unhide, like/unlike, and pin/unpin through the Comments API.
  • Reach and watch time — reach on post stats, watch-time metrics in raw_stats, and daily profile_views.
  • Custom video covers — cover_url / cover_file on video posts. thumb_offset works on every profile.

Profiles connected before that date keep working exactly as they are, Reconnect included, but they don’t get comments or reach. To move one over, disconnect it and connect TikTok again — it comes back as a new profile, so re-point anything scheduled against the old one.

Accounts that bring their own TikTok app (Integrations → TikTok) keep connecting through that app.

One publishing difference on Business API profiles: TikTok publishes videos publicly, so privacy_status applies to photo posts only.

Platform IDtiktok
Formatsvideo (default), image
Character limit2,200
MediaRequired
CommentsList, reply, delete, hide/unhide, like/unlike, pin/unpin — profiles connected on or after 2026-09-30, see Connecting TikTok
Direct messagesNo
Post chainsNo
FormatDescription
videoSingle video (default)
imagePhoto post, up to 35 images
ParameterTypeRequiredDescription
formatstringNo"video" (default)
upload_as_draftbooleanNoUpload to the creator’s TikTok inbox instead of publishing. Defaults to false. See Draft uploads
privacy_statusstringNoSee privacy values; defaults to PUBLIC_TO_EVERYONE
made_with_aibooleanNoMark content as AI-generated. Defaults to false
disable_commentbooleanNoDisable comments on the post. Defaults to true — pass false to allow comments
disable_duetbooleanNoDisable Duets. Defaults to true — pass false to allow Duets
disable_stitchbooleanNoDisable Stitches. Defaults to true — pass false to allow Stitches
brand_content_togglebooleanNoPaid partnership promoting a third-party business. Defaults to false
brand_organic_togglebooleanNoPaid partnership promoting your own brand. Defaults to false
cover_url / cover_filestring / fileNoCustom cover image for the video. JPG, PNG, or WebP, 360×360 to 1080×1920 px, up to 20 MB. Pass cover_url (URL) in JSON or cover_file (file) in multipart. Rejected with a 422 on profiles connected before 2026-09-30 — see Connecting TikTok
thumb_offsetstringNoFrame of the video to use as the cover, in milliseconds. Ignored if cover_url is set. Works on every TikTok profile
MediaMax sizeFormatsCountDuration
Video4 GBmp4, mov, av, webm13 s – 10 min
  • A video is required. Minimum dimensions: 720×1280 px.
Terminal window
# Video post
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Quick tip: Building APIs just got easier! 🚀" },
"profiles": ["prof_abc123"],
"media": ["https://example.com/video.mp4"],
"platforms": {
"tiktok": {
"privacy_status": "PUBLIC_TO_EVERYONE",
"disable_comment": false,
"made_with_ai": false
}
}
}'
ParameterTypeRequiredDescription
formatstringYes"image"
upload_as_draftbooleanNoUpload to the creator’s TikTok inbox instead of publishing. Defaults to false. See Draft uploads
privacy_statusstringNoSee privacy values; defaults to PUBLIC_TO_EVERYONE
photo_cover_indexintegerNoIndex (0-based) of the cover photo. Defaults to 0 (first photo)
auto_add_musicbooleanNoAdd music automatically. Defaults to false
disable_commentbooleanNoDisable comments on the post. Defaults to true — pass false to allow comments
brand_content_togglebooleanNoPaid partnership promoting a third-party business. Defaults to false
brand_organic_togglebooleanNoPaid partnership promoting your own brand. Defaults to false
MediaMax sizeFormatsCountDuration
Image20 MBjpg, gif35—
Terminal window
# Photo post
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Swipe through our 2026 lookbook 📸" },
"profiles": ["prof_abc123"],
"media": [
"https://example.com/photo1.jpg",
"https://example.com/photo2.jpg"
],
"platforms": {
"tiktok": {
"format": "image",
"privacy_status": "PUBLIC_TO_EVERYONE",
"photo_cover_index": 0,
"auto_add_music": true
}
}
}'

With upload_as_draft: true the media is sent to the creator’s TikTok inbox instead of being published. The creator opens the notification in the TikTok app and finishes the post there — which is the only way to add a trending sound from TikTok’s music library, since the API can’t set one. Works for both video and photo posts.

  • Video drafts ignore every other TikTok parameter, including the post body. TikTok’s upload endpoint accepts the video file and nothing else; caption, privacy, Duet/Stitch and content disclosure are all chosen by the creator in the app.
  • Photo drafts keep every parameter except privacy_status, which the creator picks when publishing.
  • The platform entry reaches status: "published" once TikTok confirms the media landed in the inbox — read that as delivered to the creator, not live on TikTok.
  • permalink stays null and no insights are collected: neither exists until the creator publishes the post themselves.
Terminal window
# Video sent to the creator's drafts
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "" },
"profiles": ["prof_abc123"],
"media": ["https://example.com/video.mp4"],
"platforms": {
"tiktok": {
"upload_as_draft": true
}
}
}'
ValueVisibility
PUBLIC_TO_EVERYONEEveryone
MUTUAL_FOLLOW_FRIENDSMutual followers
FOLLOWER_OF_CREATORFollowers only
SELF_ONLYPrivate (only you)

privacy_status is optional — omit it and the post defaults to PUBLIC_TO_EVERYONE. That default is only accepted for production-audited TikTok apps; unaudited or sandbox apps must send a non-public value (such as SELF_ONLY), or TikTok rejects the post.

On profiles connected on or after 2026-09-30, TikTok publishes videos publicly and privacy_status applies to photo posts only — see Connecting TikTok.

The full Comments API works on TikTok videos and photo posts — for profiles connected on or after 2026-09-30 (see Connecting TikTok). Earlier connections return 405.

ActionEndpoint
List comments and repliesGET /api/posts/:post_id/comments
Comment or replyPOST /api/posts/:post_id/comments
DeleteDELETE /api/posts/:post_id/comments/:id
Hide / unhidePOST .../hide / /unhide
Like / unlikePOST .../like / /unlike
Pin / unpinPOST .../pin / /unpin
Terminal window
# Reply to a comment on a TikTok video
curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Thanks for watching!", "parent_id": "7412345678901234567" }'
  • Pinning: TikTok keeps one pinned comment per video, so pinning a second comment moves the pin. Pin state is returned as platform_data.pinned.
  • Editing a comment isn’t possible — TikTok has no comment-edit API.
  • New comments and replies arrive in real time and fire comment.created; a comment deleted on TikTok drops out of the API.
  • Comment actions are asynchronous, as on every other network — the response is { "accepted": true }.

Not supported.

Postproxy records periodic stat snapshots you can pull as a timeseries; field names pass through from TikTok unchanged.

Account-level metrics, refreshed roughly every 23 hours via the Profile stats endpoint (GET /api/profiles/:id/stats).

Fields: follower_count, following_count, likes_count, video_count

Terminal window
# Fetch the profile stats timeseries
curl "https://api.postproxy.dev/api/profiles/prof_abc123/stats" \
-H "Authorization: Bearer YOUR_API_KEY"

Per-post engagement, captured after publish via the Post stats endpoint (GET /api/posts/stats). Requires the post to have a public ID.

Fields: impressions, likes, comments, shares, plus reach — the number of unique accounts that saw the video — on profiles connected on or after 2026-09-30.

On those profiles raw_stats also carries video_duration, average_time_watched, total_time_watched, and full_video_watched_rate, and GET /api/profiles/:id/daily_stats reports daily profile_views under platform_stats.

Terminal window
# Fetch post stats
curl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123&profiles=tiktok" \
-H "Authorization: Bearer YOUR_API_KEY"

Subscribe with the Webhooks API:

Terminal window
curl -X POST "https://api.postproxy.dev/api/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/postproxy",
"events": ["platform_post.published", "platform_post.failed", "platform_post.insights"]
}'

Events relevant to TikTok:

EventWhen
post.processedA post is ready to publish
platform_post.publishedA post was published to the platform
platform_post.failedA post failed to publish (retries exhausted)
platform_post.failed_waiting_for_retryA publish attempt failed; will retry
platform_post.insightsNew analytics snapshot
comment.createdA new comment or reply arrived on a TikTok post
profile.connected / .disconnectedConnection state changed
profile.statsNew profile stats snapshot
media.failedA media attachment failed to process

TikTok’s API doesn’t expose these features, so they aren’t available through Postproxy:

  • Edit a post after it’s published
  • Publish text-only posts — media is always required
  • Edit a comment after posting it
  • Send or read direct messages
  • Go Live
  • Create Duets or Stitches
  • Apply effects or filters
  • Pull from TikTok’s sound/music library (except auto_add_music on photo carousels, or by sending the post to drafts for the creator to finish in the app)
  • Create playlists
  • Read For You Page analytics
  • privacy_status is optional and defaults to PUBLIC_TO_EVERYONE — see Privacy status for the audited-app caveat.
  • Videos must be at least 720×1280 px.
  • Comments, reach, and watch-time metrics need a profile connected on or after 2026-09-30 — see Connecting TikTok.
  • upload_as_draft: true delivers to the creator’s TikTok inbox rather than publishing — see Draft uploads.
  • When a post is a paid partnership, set brand_content_toggle (third-party) or brand_organic_toggle (own brand) as required by TikTok.