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:
- 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.
- Initialize the post request.
- 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.
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 |
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:
If the TikTok creator account is private, the available options are:
| |
comment_disabled | boolean | Returns | |
duet_disabled | boolean | Return | |
stitch_disabled | boolean | Return | |
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 |
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 | |
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 | |
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:
The provided value must match one of the | 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 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 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 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 | ||
brand_organic_toggle | bool | Set to | ||
source_info | source | string | Choose from:
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 | |
video_size | int64 | The size of the to-be-uploaded video file in bytes. | true for | |
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 | |
error | code | string | You can decide whether the request is successful based on the error code. Any code other than |
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 | |
url_ownership_unverified | To use | |
privacy_level_option_mismatch |
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 | |
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 |
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:
| 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'