Skip to main content
TikTok for DevelopersTikTok for Developers

Docs

Direct Post

Overview

To post a video to users' TikTok accounts, you must invoke the Content Posting API - Direct Post endpoint to perform the following actions:

  1. Query creator information to render the UI elements to be displayed on the Export page of your app. Learn more about the UX guidelines here.
  2. Initialize the post request.
  3. Export video to TikTok servers.

This guide contains comprehensive information about the API, including the endpoint, request schema, and response schema.

Query creator information

This API returns profile and permission information of the current user.

When rendering the Export to TikTok page, your app must invoke the API and use the latest creator information returned to display the account's available privacy level options and video interaction settings.

HTTP URL

/v2/post/publish/creator_info/query/

HTTP Method

POST

Scope

video.publish

Request

Note: Each user access_token is limited to 20 requests per minute.

Field Name

Description

Value

Required

Authorization

The token that bears the authorization of the TikTok user, which is obtained through /oauth/access_token/.

Bearer {$UserAccessToken}

true

Content-Type

The content format of the body of this HTTP request.

application/json; charset=UTF-8

true

Example

curl --location --request POST 'https://open.tiktokapis.com/v2/post/publish/creator_info/query/' \
--header 'Authorization: Bearer act.example12345Example12345Example' \
--header 'Content-Type: application/json; charset=UTF-8'

Response

Field Name

Nested Field

Type

Description

data

creator_avatar_url

string

The URL of the TikTok creator's avatar with a TTL of 2 hours.

creator_username

string

The unique ID of the TikTok creator.

creator_nickname

string

The nickname of TikTok creator.

privacy_level_options


list<string>


If the TikTok creator account is public, the available options are:

  • PUBLIC_TO_EVERYONE
  • MUTUAL_FOLLOW_FRIENDS
  • SELF_ONLY

If the TikTok creator account is private, the available options are:

  • FOLLOWER_OF_CREATOR
  • MUTUAL_FOLLOW_FRIENDS
  • SELF_ONLY

comment_disabled


boolean


Returns true if the creator sets comment interaction to "No one" in their privacy setting.

duet_disabled


boolean

Return true if the creator account is private or they set the Duet interaction to "No one" in their privacy setting.

stitch_disabled


boolean


Return true if the creator account is private or they set the Stitch interaction to "No one" in their privacy setting.

max_video_post_duration_sec

int32

The longest video duration in seconds that the TikTok creator can post. Different users have different maximum video-duration privileges. Developers should use this field to stop video posts that are too long.

error

code

string

You can decide whether the request is successful based on the error code. Any code other than ok indicates the request did not succeed. Learn more about error codes.

message

string

A human readable description of the error.

logid

string

A unique identifier for the execution of this request. Different users have different maximum video-duration privileges. Developers should use this field to stop video posts that are too long.

Note: Every field in the response.data (excluding max_video_post_duration_sec) must be displayed on your app's Export screen to the user. This will indicate the TikTok account to which the post will be published and provide creators with the available privacy settings they can choose from. Learn more about the UX guidelines here.

Example

200 OK

{
   "data":{
      "creator_avatar_url": "https://lf16-tt4d.tiktokcdn.com/obj/tiktok-open-platform/8d5740ac3844be417beeacd0df75aef1",
      "creator_username": "tiktok",
      "creator_nickname": "TikTok Official",
      "privacy_level_options": ["PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"] 
      "comment_disabled": false,
      "duet_disabled": false,
      "stitch_disabled": true,
      "max_video_post_duration_sec": 300
   },
    "error": {
         "code": "ok",
         "message": "",
         "log_id": "202210112248442CB9319E1FB30C1073F3"
     }
}

Error codes

HTTP Status

Error code

Description

200

ok

200

(intentional)


spam_risk_too_many_posts


The daily post cap from API is reached for the current user.

spam_risk_user_banned_from_posting

The user is banned from making new posts.


reached_active_user_cap

The daily quota for active publishing users from your client is reached.

unaudited_client_can_only_post_to_private_accounts

Unaudited clients can only post to a private account. The publish attempt will be blocked when calling publish/video/init/.

401

access_token_invalid

The access_token is invalid or has expired.

scope_not_authorized

The access_token does not bear user's grant on video.publish scope.

429

rate_limit_exceeded

Your request is blocked due to exceeding the API rate limit.

5xx

TikTok server or network error. Try again later.


Initialize the posting request

Once users have provided the necessary metadata for their posts and given explicit consent to send their video to TikTok, the next step is to initialize the posting request.

HTTP URL

/v2/post/publish/video/init/

HTTP Method

POST

Scope

video.publish

Request

Note: Each user access_token is limited to 6 requests per minute.

Header

Field Name

Description

Value

Required

Authorization

The token that bears the authorization of the TikTok user, which is obtained through /oauth/access_token/.

Bearer {$UserAccessToken}

true

Content-Type

The content format of the body of this HTTP request.

application/json; charset=UTF-8

true

Body

Field Name

Nested Field Name

Type

Description

Required

post_info

privacy_level


string

Enum of:

PUBLIC_TO_EVERYONE

MUTUAL_FOLLOW_FRIENDS

FOLLOWER_OF_CREATOR

SELF_ONLY


The provided value must match one of the privacy_level_options returned in the /creator_info/query/ API.

true


title


string

The video caption. Hashtags (#) and mentions (@) will be matched, or deliminated by spaces or new lines.


The maximum length is 150 in UTF-16 runes.

If not specified, the ticket post will not have any captions.













false


disable_duet

bool

If set to true, other TikTok users will not be allowed to make Duets using this post.


TikTok server disables Duets for private accounts and those who set the Duet permission to "No one" in their privacy setting.

disable_stitch


bool

If set to true, other TikTok users will not be allowed to make Stitches using this post.


TikTok server disables Stitches for private accounts and those who set the Stitch permission to "No one" in their privacy setting.

disable_comment


bool


If set to true, other TikTok users will not be allowed to make comments on this post.


TikTok server disables comments for users who set the Stitch permission to "No one" in their privacy setting.

video_cover_timestamp_ms

int32

Specifies which frame (measured in milli-seconds) will be used as the video cover.


If not set, or the specified value is invalid, the cover is set to the first frame of the uploaded video.

brand_content_toggle

bool

Set to true if this video is promoting the creator's own business

brand_organic_toggle

bool

Set to true if the video is in paid partnership for promoting third-party business


source_info

source


string

Choose from:

PULL_FROM_URL

FILE_UPLOAD

Learn about the limitations for these file transmission methods.

true


video_url

string

A public-accessible URL from which the TikTok server will pull to retrieve the video resource.

true for PULL_FROM_URL

video_size

int64

The size of the to-be-uploaded video file in bytes.


true forFILE_UPLOAD


chunk_size

int64

The size of the chunk in bytes.

total_chunk_count

int64

The total number of chunks.

Example

curl --location 'https://open.tiktokapis.com/v2/post/publish/video/init/' \
--header 'Authorization: Bearer act.example12345Example12345Example' \
--header 'Content-Type: application/json; charset=UTF-8' \
--data-raw '{
  "post_info": {
    "title": "this will be a funny #cat video on your @tiktok #fyp",
    "privacy_level": "MUTUAL_FOLLOW_FRIENDS",
    "disable_duet": false,
    "disable_comment": true,
    "disable_stitch": false,
    "video_cover_timestamp_ms": 1000
  },
  "source_info": {
      "source": "FILE_UPLOAD",
      "video_size": 50000123,
      "chunk_size":  10000000,
      "total_chunk_count": 5
  }
}'

Response

Field Name

Nested Field

Type

Description

data


publish_id


string


An identifier to track the posting action, which you can use to check status.

The maximum length of this field is 64.

upload_url


string


The URL provided by TikTok where the video file can be uploaded. The maximum length of this field is 256.

This field is only for source=FILE_UPLOAD.

error

code

string

You can decide whether the request is successful based on the error code. Any code other than ok indicates the request did not succeed. Learn more about error codes.

message

string

A human readable description of the error.

logid

string

A unique identifier for the execution of this request.

Note: The upload_url is valid for one hour after issuance. The upload must be completed in this time range.

Example

200 OK
{
    "data": {
        "publish_id": "v_pub_file~v2-1.123456789",
        "upload_url": "https://open-upload.tiktokapis.com/video/?upload_id=67890&upload_token=Xza123"    
    },
    "error": {
         "code": "ok",
         "message": "",
         "log_id": "202210112248442CB9319E1FB30C1073F3"
     }
}

Error codes

HTTP Status

error.code

Description

400

invalid_param

Check error message for details.

403


spam_risk_too_many_posts

The daily post cap from API is reached for the current user.

spam_risk_user_banned_from_posting

The user is banned from making new posts.


reached_active_user_cap

The daily quota for active publishing users from your client is reached.

unaudited_client_can_only_post_to_private_accounts

Unaudited clients can only post to private account. The publish attempt will be blocked when calling /publish/video/init/.

url_ownership_unverified


To use PULL_FROM_URL as the video transfer method, developer must verify the ownership of the URL prefix or domain. Refer to this doc for more details.

privacy_level_option_mismatch

privacy_level is not specified or not among the options from the privacy_level_options returned in /publish/creator_info/query/ API.


All clients are required to correctly display the creator account's privacy level options and honor the users' choice. Occurances of this error for product-use applications suggest violations to TikTok's product-use guidance.

401

access_token_invalid

The access_token is invalid or has expired.

scope_not_authorized

The access_token does not bear user's grant on video.publish scope

429

rate_limit_exceeded

Your request is blocked due to exceeding the API rate limit.

5xx

TikTok server or network error. Try again later.


Send video to TikTok servers

Note: If you used the source=PULL_FROM_URL to initialize the video export, you can skip this part. The TikTok server will handle the video uploading process for you.

Once you have initialized the video export and received an upload_url, you must send the video file to TikTok for processing. We support many video formats and provide chunking for larger files. Learn more about media transmission.

HTTP URL

Returned in upload_url

HTTP Method

PUT

Note: Use the entire URL returned as the upload_url including the returned query parameters.

Request

Note: This document provides schemas for the API request and response. Learn more about media upload formats and advanced capabilities.

Header

Field Name

Description

Value

Required

Content-Type

The content format of the body of this HTTP request.

Select from:

  • video/mp4
  • video/quicktime
  • video/webm

true


Content-Length

Byte size of this chunk.

{BYTE_SIZE_OF_THIS_CHUNK}

true


Content-Range

The metadata describing the portion of the overall file contained in this chunk.

bytes {FIRST_BYTE}-{LAST_BYTE}/{TOTAL_BYTE_LENGTH}

true

Body

The binary file data.

Example

curl --location --request PUT 'https://open-upload.tiktokapis.com/video/?upload_id=67890&upload_token=Xza123' \
--header 'Content-Range: bytes 0-30567099/30567100' \
--header 'Content-Length: 30567100'\
--header 'Content-Type: video/mp4' \
--data '@/path/to/file/example.mp4'