Platforms

TikTok

Connect a TikTok account, publish videos and photo posts with privacy and disclosure settings, and read post metrics and account stats.

Publish videos and photo posts, and read post metrics and account stats.

Quick Reference

PropertyValue
Account typesTikTok accounts
Connection methodOAuth
Post typesvideo, image, multi_image
Max media per post35
Text limit2,200 characters, title 90 (photo posts), description 4,000 (photo posts)
ThreadsNo
QuotesNo
Remote deleteNo
CommentsNo
LikesNo
RepostsNo
BookmarksNo
Direct messagesNo
Post analytics
Account analyticsStats

A post needs uploaded media, a privacyLevel and each interaction choice.

TikTok takes only files uploaded with Create Media. Any other media URL fails with INVALID_MEDIA, so upload the file first.

Connect

Connect in Dashboard → Connections, or with a connect session.

Permissions

ScopeUsed for
user.info.basicUser id, name and avatar
user.info.profileUsername, for post links
user.info.statsAccount stats
video.listAnalytics, video list and sync
video.publishPublishing

A missing scope returns PERMISSION_DENIED or ANALYTICS_PERMISSION. Reconnect the account and approve every permission.

Staying Connected

Access renews itself, so canAutoRenew is true. It ends if the creator removes the app in TikTok, or the account is deleted or banned. The account then turns revoked and account.revoked fires with authorization_removed. Requests for it return TOKEN_INVALID.

Reconnect with the same TikTok account. The id stays the same.

Publish

import { Configuration, PostsApi } from "@onepostly/sdk";

const postsApi = new PostsApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await postsApi.createPost({
  createPostBody: {
    "text": "Behind the scenes of launch day #startup",
    "mediaKind": "video",
    "media": [
      {
        "id": "med_7f3a9c2e1b4d4e8f9a6b5c4d3e2f1a0b"
      }
    ],
    "accounts": [
      {
        "accountId": "acc_YOUR_TIKTOK_ACCOUNT_ID",
        "tiktok": {
          "privacyLevel": "public_to_everyone",
          "allowComment": true,
          "allowDuet": true,
          "allowStitch": true
        }
      }
    ]
  },
});
console.log(response);
{
  "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
  "data": [
    {
      "id": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
      "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
      "accountId": "acc_YOUR_TIKTOK_ACCOUNT_ID",
      "platform": "tiktok",
      "source": "onepostly",
      "status": "publishing",
      "text": "Behind the scenes of launch day #startup",
      "mediaKind": "video",
      "media": [
        {
          "url": "https://cdn.onepostly.com/media/5b0e7c1a-2f4d-4c8e-9a3b-6d1f0e2c4a7b/7f3a9c2e-1b4d-4e8f-9a6b-5c4d3e2f1a0b.mp4"
        }
      ],
      "thread": [],
      "scheduledFor": null,
      "timezone": null,
      "options": {
        "tiktok": {
          "privacyLevel": "public_to_everyone",
          "allowComment": true,
          "allowDuet": true,
          "allowStitch": true
        }
      },
      "platformPostId": null,
      "url": null,
      "error": null,
      "publishedAt": null,
      "metrics": null,
      "createdAt": "2027-03-15T09:00:00.000Z",
      "updatedAt": "2027-03-15T09:00:00.000Z"
    }
  ]
}

The post stays publishing while TikTok processes it.

Post Types

mediaKindPublishesMedia
videoVideo post1 video
imagePhoto post1 photo
multi_imagePhoto carousel2 to 35 photos

A post has one video or photos, never both. text and stories return 400.

Text and Captions

PostCaptionTitle
Videotext, up to 2,200None
Phototiktok.description, up to 4,000, else textFirst 90 of text

The title is cut at 90, so long text is not refused.

Photo Posts

photoCoverIndex picks the cover photo, counting from 0. autoAddMusic adds TikTok's suggested music to the post.

import { Configuration, PostsApi } from "@onepostly/sdk";

const postsApi = new PostsApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await postsApi.createPost({
  createPostBody: {
    "text": "Weekend on the coast",
    "mediaKind": "multi_image",
    "media": [
      {
        "id": "med_7f3a9c2e1b4d4e8f9a6b5c4d3e2f1a03"
      },
      {
        "id": "med_7f3a9c2e1b4d4e8f9a6b5c4d3e2f1a04"
      },
      {
        "id": "med_7f3a9c2e1b4d4e8f9a6b5c4d3e2f1a05"
      }
    ],
    "accounts": [
      {
        "accountId": "acc_YOUR_TIKTOK_ACCOUNT_ID",
        "tiktok": {
          "description": "Two days, three beaches, one very windy picnic. #travel #roadtrip",
          "privacyLevel": "public_to_everyone",
          "allowComment": false,
          "photoCoverIndex": 1,
          "autoAddMusic": true
        }
      }
    ]
  },
});
console.log(response);
{
  "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
  "data": [
    {
      "id": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
      "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
      "accountId": "acc_YOUR_TIKTOK_ACCOUNT_ID",
      "platform": "tiktok",
      "source": "onepostly",
      "status": "publishing",
      "text": "Weekend on the coast",
      "mediaKind": "multi_image",
      "media": [
        {
          "url": "https://cdn.onepostly.com/media/5b0e7c1a-2f4d-4c8e-9a3b-6d1f0e2c4a7b/7f3a9c2e-1b4d-4e8f-9a6b-5c4d3e2f1a03.jpg"
        },
        {
          "url": "https://cdn.onepostly.com/media/5b0e7c1a-2f4d-4c8e-9a3b-6d1f0e2c4a7b/7f3a9c2e-1b4d-4e8f-9a6b-5c4d3e2f1a04.jpg"
        },
        {
          "url": "https://cdn.onepostly.com/media/5b0e7c1a-2f4d-4c8e-9a3b-6d1f0e2c4a7b/7f3a9c2e-1b4d-4e8f-9a6b-5c4d3e2f1a05.jpg"
        }
      ],
      "thread": [],
      "scheduledFor": null,
      "timezone": null,
      "options": {
        "tiktok": {
          "description": "Two days, three beaches, one very windy picnic. #travel #roadtrip",
          "privacyLevel": "public_to_everyone",
          "allowComment": false,
          "photoCoverIndex": 1,
          "autoAddMusic": true
        }
      },
      "platformPostId": null,
      "url": null,
      "error": null,
      "publishedAt": null,
      "metrics": null,
      "createdAt": "2027-03-15T09:00:00.000Z",
      "updatedAt": "2027-03-15T09:00:00.000Z"
    }
  ]
}

Privacy Levels

Every TikTok account needs tiktok.privacyLevel.

ValueWho can see it
public_to_everyoneEveryone
mutual_follow_friendsFollowers the creator follows back
follower_of_creatorFollowers
self_onlyOnly the creator

The creator's settings decide which values work. Others return 400 INVALID_PRIVACY_LEVEL. The level is checked again at publish, so a privacy change in TikTok can fail a scheduled post that passed on create.

Only public_to_everyone posts get a post id, a link and metrics.

Creator Info

TikTok asks you to read and show the creator's settings before each post.

import { Configuration, AccountsApi } from "@onepostly/sdk";

const accountsApi = new AccountsApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await accountsApi.getCreatorInfo({
  id: "acc_YOUR_TIKTOK_ACCOUNT_ID",
});
console.log(response);
{
  "accountId": "acc_YOUR_TIKTOK_ACCOUNT_ID",
  "username": "yourbrand",
  "nickname": "Your Brand",
  "avatarUrl": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/7310942817465028614~c5_168x168.jpeg",
  "privacyLevelOptions": [
    "public_to_everyone",
    "mutual_follow_friends",
    "follower_of_creator",
    "self_only"
  ],
  "commentDisabled": false,
  "duetDisabled": false,
  "stitchDisabled": false,
  "maxVideoPostDurationSec": 600,
  "fetchedAt": "2027-03-15T08:59:30.000Z"
}
FieldMeaning
privacyLevelOptionsAllowed privacyLevel values
commentDisabledComments are off in TikTok
duetDisabledDuets are off, such as on a private account
stitchDisabledStitches are off, such as on a private account
maxVideoPostDurationSecThe longest video allowed, or null

These settings are read live. Creating or editing a post reads them too, and the request fails if they cannot be loaded.

Interactions

TikTok wants the creator to pick every interaction, so each post sets them.

OptionApplies toRequired
tiktok.allowCommentVideos and photosYes
tiktok.allowDuetVideos onlyOn videos
tiktok.allowStitchVideos onlyOn videos
  • A missing one returns 400 VALIDATION_ERROR. On photos, duet or stitch returns 400.
  • true for an interaction the creator turned off returns 400 INTERACTION_DISABLED.
  • If the creator turns one off after scheduling, the post publishes with it off.

Post ID and Link

FieldOnce publicBefore that, or not public
platformPostIdThe TikTok post idA publish id, v_pub_… or p_pub_…
urlThe post linkThe profile for videos, null for photos

A public post can be published before TikTok's review ends. Once public, both fields update and post.updated fires, so store the new values.

Options

Options go under tiktok. Another platform's options there return 400.

Prop

Type

Disclosure Labels

You can set both brand labels. A paid partnership cannot be self_only. That combination passes on create but fails at publish.

Media Requirements

These are TikTok's limits, on top of the Media URL Requirements.

MediaFormatsMax size
ImagesJPEG and WebP20 MB
VideosMP4, MOV and WebM1 GB

A file outside these formats and sizes is refused. See Platform Limits.

Images

PropertyRequirement
Max resolution1080p

Videos

PropertyRequirement
DurationUp to maxVideoPostDurationSec
Frame rate23 to 60 fps
Dimensions360 to 4096 each side

Scheduling, Editing and Deleting

Scheduling and editing work as usual. Both check the creator's settings. A post that is publishing or published returns NOT_EDITABLE.

You can cancel a post before publish. During processing, a delete returns POST_PUBLISHING. Published posts can only be deleted in the TikTok app.

Engagement

TikTok has no comments, likes, reposts or bookmarks here. Those calls return UNSUPPORTED_PLATFORM. Counts are in analytics.

Inbox

TikTok has no inbox through Onepostly.

Analytics

Metrics

FieldTikTok metric
impressionsview_count
reachAlways null
viewsview_count
likeslike_count
commentscomment_count
sharesshare_count
savesAlways null
engagementlikes + comments + shares

Only public_to_everyone posts have metrics. Freshness is the standard.

StatusCodeMeaning
pendingVIDEO_ID_PENDINGNot public yet, read again later
pendingVIDEO_NOT_FOUNDPublic, but no metrics yet
unavailablePRIVACY_RESTRICTEDNot public, for good

On YouTube, VIDEO_NOT_FOUND means gone for good. Read it with status.

A post that stops being public keeps its last metrics. They update again once it is public again.

Account Stats

Get Account Stats reads followers, following, likes and videos live. likesCount counts likes across all of the creator's videos.

Recent Posts

List Account Media lists public videos with metrics, 20 per page. The first page adds your non-public posts, with a publish id and null metrics.

Limitations

Not available for TikTok through Onepostly.

  • Text posts and stories
  • Mixing photos and a video
  • Editing or deleting published posts
  • Comments, likes, reposts and bookmarks
  • Quotes and reply chains
  • Direct messages
  • Sending to drafts
  • Metrics for non-public posts

Errors

Breaking a rule on this page returns 400 VALIDATION_ERROR and creates nothing. TikTok can also refuse a setting at publish and fail the post.

Every code is in Errors.

Publish Errors

CodeCauseFix
INVALID_PRIVACY_LEVELNot in privacyLevelOptionsUse an allowed value
INTERACTION_DISABLEDtrue for an interaction the creator turned offSend false
INVALID_MEDIAA file not uploaded with Create MediaUpload it first
INVALID_MEDIATikTok refused the format, length, frame rate or photo sizeMeet the Media Requirements
MEDIA_UNFETCHABLETikTok could not download the fileUpload it again
URL_OWNERSHIP_UNVERIFIEDTikTok refused the fileUpload it again
TOKEN_INVALIDThe creator removed access while the post was processingReconnect the account
CREATOR_INFO_FAILED502. Creator info did not loadTry again, then reconnect
MEDIA_UPLOAD_FAILEDTikTok refused to start the postRead error.message
MEDIA_PROCESSING_TIMEOUTProcessing took too longCheck the profile first
SPAM_RISKTikTok flagged the postChange the caption and media
POSTING_LIMIT_REACHEDToo many recent postsWait before posting
ACCOUNT_RESTRICTEDTikTok restricted postingFix it in the app
CAPACITY_LIMITEDTikTok is not taking direct postsTry again in a few hours
UNSUPPORTED_PLATFORMA delete of a published postDelete it in the app

Analytics Errors

CodeCauseFix
VIDEO_ID_PENDINGNot public yetRead again later
VIDEO_NOT_FOUNDNo metrics yetRead again later
PRIVACY_RESTRICTEDNot publicPublish to everyone
ANALYTICS_PERMISSIONNo video.listReconnect with every permission
STATS_FAILEDStats did not loadTry again later