Skip to main content
TikTok for Developers

Docs

New: Content Posting API now supports posting photos!

Direct Post

Overview

To directly 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.
    1. Learn more about the UX guidelines here.
    2. Learn more about the creator_info/query API here.
  2. Initialize the post request.
  3. Export the video to TikTok servers.

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

Note: All content posted by unaudited clients will be restricted to private viewing mode. Once you have successfully tested your integration, to lift the restriction on content visibility, your API client must undergo an audit to verify compliance with our Terms of Service.

Initialize the posting request

Once you have requested creator info, and 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.

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 2200 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.


The 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.


The 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.


The TikTok server disables comments for users who set the Comments 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 the video is a paid partnership to promote a third-party business.

brand_organic_toggle

bool

Set to true if this video is promoting the creator's own 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 the 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 the 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/.

url_ownership_unverified


To use PULL_FROM_URL as the video transfer method, the 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/upload/?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'