Automate TikTok video posting using the Content Posting API's Direct Post flow: query creator settings with POST /v2/post/publish/creator_info/query/, initialize the upload with POST /v2/post/publish/video/init/, upload video chunks via PUT to the provided upload URL, then poll status with POST /v2/post/publish/status/fetch/. Access tokens expire every 24 hours. Without TikTok audit approval (2-6 weeks), all posts go to SELF_ONLY (private). Daily cap is ~15 posts per creator account.
API Quick Reference
OAuth 2.0
6 req/min (publish); 30 req/min (status); ~15 posts/day per account
JSON
REST only
Understanding the TikTok Content Posting API
TikTok's Content Posting API (Direct Post) is the most restrictive publishing API of any major social platform. Before you can post videos publicly, your app must pass TikTok's Content Posting Audit — a 2-6 week review process. Without it, every post defaults to SELF_ONLY (private) regardless of the privacy_level parameter you set. TikTok explicitly rejects apps described as 'personal account management utilities' — your use case must serve a broad audience.
The upload flow has four steps: (1) call creator_info/query to get allowed settings for the specific creator, (2) initialize the post with video/init/ to receive an upload URL, (3) upload the video in chunks using PUT requests with Content-Range headers, (4) poll status/fetch/ until the post is PUBLISHED. Video upload uses a dedicated upload domain: open-upload.tiktokapis.com. The access token expires every 24 hours — a token refresh job is not optional.
Mandatory UX requirements from TikTok's audit: your app must display the creator's nickname from creator_info, show a Commercial Content checkbox (for Brand Partnerships and Your Brand), and let users consent to music usage. Apps that skip these UI elements fail the audit. Official documentation: https://developers.tiktok.com/doc/content-posting-api-get-started
https://open.tiktokapis.comSetting Up TikTok Content Posting API Authentication
TikTok OAuth2 v2 uses short-lived access tokens (24h) with a long-lived refresh token (365 days). The video.publish scope enables Direct Post. Unlike most APIs, TikTok requires a mandatory token refresh loop — there is no way to get longer-lived tokens. Missing a refresh means your automation breaks silently.
- 1Create a developer account at developers.tiktok.com with a business email
- 2Create a new app and add the 'Video: Direct Post' capability to request video.publish scope
- 3Submit your app for the Content Posting Audit (required for public posts) — this takes 2-6 weeks
- 4Note your client_key and client_secret from the app dashboard
- 5Implement OAuth authorization: https://www.tiktok.com/v2/auth/authorize/?client_key={key}&scope=video.publish&response_type=code&redirect_uri={uri}&state={random}
- 6Exchange the code for tokens at POST https://open.tiktokapis.com/v2/oauth/token/ with grant_type=authorization_code
- 7Store both access_token (24h) and refresh_token (365 days) securely
- 8Set up a cron job to call POST /v2/oauth/token/ with grant_type=refresh_token every 18-20 hours
1import requests2import os34CLIENT_KEY = os.environ['TIKTOK_CLIENT_KEY']5CLIENT_SECRET = os.environ['TIKTOK_CLIENT_SECRET']67def refresh_token(refresh_token_value):8 """MANDATORY: call every 18-20 hours. 24h expiry is strict."""9 resp = requests.post(10 'https://open.tiktokapis.com/v2/oauth/token/',11 data={12 'client_key': CLIENT_KEY,13 'client_secret': CLIENT_SECRET,14 'grant_type': 'refresh_token',15 'refresh_token': refresh_token_value,16 },17 headers={'Content-Type': 'application/x-www-form-urlencoded'}18 )19 resp.raise_for_status()20 data = resp.json()21 print(f'Token refreshed. Expires in: {data["expires_in"]}s')22 return data['access_token'], data.get('refresh_token', refresh_token_value)2324def tiktok_api(method, url, access_token, **kwargs):25 headers = kwargs.pop('headers', {})26 headers.update({27 'Authorization': f'Bearer {access_token}',28 'Content-Type': 'application/json; charset=UTF-8',29 })30 resp = getattr(requests, method)(url, headers=headers, **kwargs)31 resp.raise_for_status()32 data = resp.json()33 if data.get('error', {}).get('code', 'ok') != 'ok':34 raise ValueError(f'TikTok error: {data["error"]}')35 return dataSecurity notes
- •Access token expires in 24 hours — automate refresh or your automation breaks every day
- •Store client_key, client_secret, access_token, and refresh_token in environment variables or a secrets manager
- •Never embed API credentials in video files, watermarks, or content visible to users
- •TikTok monitors for IP/geolocation mismatches — use consistent server infrastructure for API calls
- •Never put watermarks, external links, or competitor branding on API-uploaded videos — violates TikTok Terms of Service
- •Log all post publications with publish_id and video_id for audit trail and debugging
Key endpoints
/v2/post/publish/creator_info/query/REQUIRED before every post. Returns the creator's allowed settings: privacy levels, max video duration, whether comments/duets/stitches can be disabled. Your app must display the creator's nickname from this response. This is a hard audit requirement.
Request
1{}Response
1{"data": {"creator_username": "creator123", "creator_nickname": "Creator Display Name", "creator_avatar_url": "https://...", "privacy_level_options": ["PUBLIC_TO_EVERYONE", "FOLLOWER_OF_CREATOR", "SELF_ONLY"], "comment_disabled": false, "duet_disabled": false, "stitch_disabled": false, "max_video_post_duration_sec": 180}, "error": {"code": "ok"}}/v2/post/publish/video/init/Initializes a Direct Post by providing post metadata and video file info. Returns an upload_url for chunked video upload. The publish_id tracks the post through the upload and publish pipeline.
| Parameter | Type | Required | Description |
|---|---|---|---|
post_info.title | string | required | Video caption. Max 2,200 characters. Can include hashtags and @mentions. |
post_info.privacy_level | string | required | Must be one of the values from creator_info/query. Without audit approval, posts go SELF_ONLY regardless. |
source_info.video_size | number | required | Total video file size in bytes. Must be exact. |
source_info.chunk_size | number | required | Size of each upload chunk in bytes. Recommended: 10MB (10485760). Last chunk can be smaller. |
source_info.total_chunk_count | number | required | Total number of chunks. Must equal ceil(video_size / chunk_size). |
Request
1{"post_info": {"title": "Video caption #fyp", "privacy_level": "PUBLIC_TO_EVERYONE", "disable_duet": false, "disable_comment": false, "disable_stitch": false, "video_cover_timestamp_ms": 1000}, "source_info": {"source": "FILE_UPLOAD", "video_size": 52428800, "chunk_size": 10485760, "total_chunk_count": 5}}Response
1{"data": {"publish_id": "v_pub_url~v2.123456789", "upload_url": "https://open-upload.tiktokapis.com/upload/?upload_id=abc&upload_token=xyz"}, "error": {"code": "ok"}}https://open-upload.tiktokapis.com/upload/ (from upload_url)Uploads video chunks to the TikTok upload server. Each chunk requires Content-Range header specifying the byte range. Upload chunks sequentially.
| Parameter | Type | Required | Description |
|---|---|---|---|
Content-Range | string | required | Byte range of this chunk. Format: 'bytes {start}-{end}/{total}'. E.g., 'bytes 0-10485759/52428800' for the first 10MB chunk. |
Content-Type | string | required | Must be 'video/mp4' (or video/quicktime for MOV files). |
Request
1Binary video data (chunk bytes)Response
1{"backend_trace": "abc123"}/v2/post/publish/status/fetch/Polls the publish status for a video upload. Status progresses: PROCESSING_UPLOAD → PROCESSING_DOWNLOAD → PUBLISH_COMPLETE (or FAILED). Check this after upload completes to confirm the post went live.
| Parameter | Type | Required | Description |
|---|---|---|---|
publish_id | string | required | The publish_id returned from /video/init/. |
Request
1{"publish_id": "v_pub_url~v2.123456789"}Response
1{"data": {"status": "PUBLISH_COMPLETE", "privacy_level": "PUBLIC_TO_EVERYONE", "share_url": "https://www.tiktok.com/@creator/video/12345", "video_id": "7123456789012345678"}, "error": {"code": "ok"}}Step-by-step automation
Query Creator Info and Prepare Post Metadata
Why: Creator info is required by TikTok's audit — skipping it will cause your audit application to be rejected, and you need the privacy_level_options to set valid privacy.
Call POST /v2/post/publish/creator_info/query/ before every post. Use the response to validate your target privacy_level is available for this creator, and store the creator_nickname to display in your UI (required for audit). Also check max_video_post_duration_sec to validate your video length.
1curl -X POST https://open.tiktokapis.com/v2/post/publish/creator_info/query/ \2 -H "Authorization: Bearer ${ACCESS_TOKEN}" \3 -H "Content-Type: application/json; charset=UTF-8" \4 -d '{}'Pro tip: TikTok's audit specifically checks that your app displays the creator_nickname in the posting UI. Build your front-end to show 'Posting as: {creator_nickname}' before the user confirms publishing.
Expected result: Creator info object including creator_nickname (display in your UI), privacy_level_options (valid values for post_info.privacy_level), and max_video_post_duration_sec.
Initialize the Video Post and Get Upload URL
Why: The video/init/ call creates the post record and returns a time-limited upload URL — you must start uploading immediately after receiving it.
Send POST /v2/post/publish/video/init/ with post metadata and video file details. You need the exact video file size in bytes and must calculate total_chunk_count correctly. The response contains a publish_id (track this throughout the flow) and an upload_url with embedded auth credentials that expire.
1curl -X POST https://open.tiktokapis.com/v2/post/publish/video/init/ \2 -H "Authorization: Bearer ${ACCESS_TOKEN}" \3 -H "Content-Type: application/json; charset=UTF-8" \4 -d '{5 "post_info": {6 "title": "My video #fyp #trending",7 "privacy_level": "PUBLIC_TO_EVERYONE",8 "disable_duet": false,9 "disable_comment": false,10 "disable_stitch": false11 },12 "source_info": {13 "source": "FILE_UPLOAD",14 "video_size": 52428800,15 "chunk_size": 10485760,16 "total_chunk_count": 517 }18 }'Pro tip: Use 10MB chunk size for reliable uploads. Smaller chunks mean more HTTP requests; larger chunks risk timeout on slow connections. TikTok recommends 5-64MB chunks.
Expected result: publish_id for status tracking, upload_url for chunked upload, and video_size for calculating byte ranges.
Upload Video in Chunks
Why: TikTok uses chunked upload to handle large video files — you cannot POST the full video in one request.
Split the video file into chunks and PUT each one to the upload_url with appropriate Content-Range headers. The Content-Range format is 'bytes {start}-{end}/{total}'. Upload chunks sequentially — TikTok does not support parallel chunk uploads. Include retry logic for individual chunks.
1# Upload the first 10MB chunk (bytes 0-10485759 of a 52428800-byte file)2curl -X PUT "${UPLOAD_URL}" \3 -H "Content-Range: bytes 0-10485759/52428800" \4 -H "Content-Type: video/mp4" \5 --data-binary @/path/to/chunk_0.binPro tip: TikTok's upload URL contains embedded credentials with a time limit — start uploading immediately after calling video/init/. If upload takes too long, the URL may expire and you'll need to re-initialize.
Expected result: All chunks uploaded successfully. TikTok begins processing the video for publishing.
Poll Publish Status Until Complete
Why: Video processing takes time and may fail at multiple stages — polling confirms the video actually went live and gives you the video_id for tracking.
After upload completes, poll POST /v2/post/publish/status/fetch/ with the publish_id every 10-30 seconds. Status progresses: PROCESSING_UPLOAD → PROCESSING_DOWNLOAD → PUBLISH_COMPLETE (or FAILED). Store the video_id from the PUBLISH_COMPLETE response.
1curl -X POST https://open.tiktokapis.com/v2/post/publish/status/fetch/ \2 -H "Authorization: Bearer ${ACCESS_TOKEN}" \3 -H "Content-Type: application/json; charset=UTF-8" \4 -d '{"publish_id": "${PUBLISH_ID}"}'Pro tip: Always check the privacy_level in the PUBLISH_COMPLETE response — it confirms whether your audit approval is active. A post appearing as SELF_ONLY despite setting PUBLIC_TO_EVERYONE means your audit is still pending.
Expected result: Status PUBLISH_COMPLETE with video_id and share_url. If privacy_level is SELF_ONLY, the app needs audit approval.
Complete working code
Complete TikTok video posting pipeline: refreshes the token, queries creator info, initializes the post, uploads video in chunks, polls publish status, and logs the result. Handles the full flow from video file on disk to published TikTok post.
1#!/usr/bin/env python32"""TikTok Direct Post Video Publisher."""3import os4import math5import time6import logging7import requests89logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')10log = logging.getLogger(__name__)1112CLIENT_KEY = os.environ['TIKTOK_CLIENT_KEY']13CLIENT_SECRET = os.environ['TIKTOK_CLIENT_SECRET']14REFRESH_TOKEN = os.environ['TIKTOK_REFRESH_TOKEN']15CHUNK_SIZE = 10 * 1024 * 1024 # 10MB1617def get_fresh_token():18 resp = requests.post('https://open.tiktokapis.com/v2/oauth/token/',19 data={'client_key': CLIENT_KEY, 'client_secret': CLIENT_SECRET,20 'grant_type': 'refresh_token', 'refresh_token': REFRESH_TOKEN},21 headers={'Content-Type': 'application/x-www-form-urlencoded'})22 resp.raise_for_status()23 return resp.json()['access_token']2425def tt(method, url, token, **kwargs):26 headers = kwargs.pop('headers', {})27 headers.update({'Authorization': f'Bearer {token}', 'Content-Type': 'application/json; charset=UTF-8'})28 resp = getattr(requests, method)(url, headers=headers, **kwargs)29 resp.raise_for_status()30 data = resp.json()31 if data.get('error', {}).get('code', 'ok') != 'ok':32 raise ValueError(f'TikTok API error: {data["error"]}')33 return data['data']3435def query_creator(token):36 return tt('post', 'https://open.tiktokapis.com/v2/post/publish/creator_info/query/', token, json={})3738def init_post(token, video_path, title, privacy_level):39 video_size = os.path.getsize(video_path)40 return tt('post', 'https://open.tiktokapis.com/v2/post/publish/video/init/', token, json={41 'post_info': {'title': title, 'privacy_level': privacy_level, 'disable_duet': False, 'disable_comment': False, 'disable_stitch': False},42 'source_info': {'source': 'FILE_UPLOAD', 'video_size': video_size, 'chunk_size': CHUNK_SIZE, 'total_chunk_count': math.ceil(video_size / CHUNK_SIZE)}43 }), video_size4445def upload_chunks(upload_url, video_path, video_size):46 n = math.ceil(video_size / CHUNK_SIZE)47 with open(video_path, 'rb') as f:48 for i in range(n):49 start = i * CHUNK_SIZE50 end = min(start + CHUNK_SIZE - 1, video_size - 1)51 f.seek(start)52 data = f.read(end - start + 1)53 resp = requests.put(upload_url, data=data,54 headers={'Content-Range': f'bytes {start}-{end}/{video_size}', 'Content-Type': 'video/mp4'}, timeout=120)55 resp.raise_for_status()56 log.info(f'Chunk {i+1}/{n} uploaded')5758def poll_status(publish_id, token, timeout=600):59 deadline = time.time() + timeout60 delay = 1061 while time.time() < deadline:62 data = tt('post', 'https://open.tiktokapis.com/v2/post/publish/status/fetch/', token, json={'publish_id': publish_id})63 status = data.get('status')64 log.info(f'Status: {status}')65 if status == 'PUBLISH_COMPLETE':66 if data.get('privacy_level') == 'SELF_ONLY':67 log.warning('Post is PRIVATE — audit approval needed for public posts')68 return data69 if status == 'FAILED':70 raise ValueError(f'Publish failed: {data}')71 delay = min(delay * 1.5, 60)72 time.sleep(delay)73 raise TimeoutError('Polling timeout')7475def publish_video(video_path, title, privacy_level='PUBLIC_TO_EVERYONE'):76 log.info('Refreshing token...')77 token = get_fresh_token()78 log.info('Querying creator info...')79 creator = query_creator(token)80 log.info(f'Creator: {creator["creator_nickname"]}')81 if privacy_level not in creator.get('privacy_level_options', []):82 log.warning(f'{privacy_level} not available; using SELF_ONLY')83 privacy_level = 'SELF_ONLY'84 log.info('Initializing post...')85 (post_data, video_size) = init_post(token, video_path, title, privacy_level)86 publish_id = post_data['publish_id']87 upload_url = post_data['upload_url']88 log.info(f'Uploading video ({video_size/1024/1024:.1f}MB)...')89 upload_chunks(upload_url, video_path, video_size)90 log.info('Polling publish status...')91 result = poll_status(publish_id, token)92 log.info(f'Done! Video ID: {result.get("video_id")}')93 return result9495if __name__ == '__main__':96 result = publish_video('/path/to/video.mp4', 'My TikTok video #fyp')97 print(f'Published: {result}')Error handling
{"error": {"code": "access_token_invalid", "message": "Access token is invalid or expired"}}The 24-hour access token has expired. This is the most common error in TikTok automation.
Call POST /v2/oauth/token/ with grant_type=refresh_token immediately before every API operation. Build token refresh into the start of every automation run.
Refresh token, then retry the original request.
{"error": {"code": "unaudited_client_only_self_visibility"}}Your TikTok app has not passed the Content Posting API audit. All posts are forced to SELF_ONLY (private).
Apply for the Content Posting Audit at developers.tiktok.com. Takes 2-6 weeks. Your app must demonstrate broad audience utility — TikTok rejects 'personal account utilities'. While waiting, test with SELF_ONLY posts.
Cannot bypass — audit approval required.
{"error": {"code": "video_duration_exceeds_max"}}The video is longer than the creator's maximum allowed duration from creator_info/query.
Always call creator_info/query first and validate duration against max_video_post_duration_sec. Trim video with ffmpeg: `ffmpeg -i input.mp4 -t {max_duration} output.mp4`.
Trim video and retry.
{"error": {"code": "unsupported_format", "message": "Video format not supported"}}Video is not in a supported format. TikTok requires MP4, MOV, WEBM, or AVI. Recommended: MP4 with H.264 codec and AAC audio.
Re-encode: `ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4`. Check codec with ffprobe.
Re-encode and retry.
{"error": {"code": "rate_limit_exceeded"}}Exceeded 6 requests per minute on publish endpoints.
Add 10-second minimum delays between publish API calls. Monitor X-RateLimit-Remaining header.
Wait 60 seconds, then retry with exponential backoff.
Rate Limits for TikTok Content Posting API
| Scope | Limit | Window |
|---|---|---|
| Per user access_token (publish endpoints: init, creator_info) | 6 requests | per minute |
| Per user access_token (status fetch) | 30 requests | per minute |
| Daily posting cap | ~15 posts per creator account | per 24 hours (shared across all API clients) |
1import time2import requests34def tiktok_post_with_retry(url, token, body, max_retries=3):5 for attempt in range(max_retries):6 resp = requests.post(url,7 headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json; charset=UTF-8'},8 json=body, timeout=30)9 remaining = int(resp.headers.get('X-RateLimit-Remaining', '3'))10 if resp.status_code == 429:11 reset = int(resp.headers.get('X-RateLimit-Reset', '60'))12 print(f'Rate limited. Waiting {reset + 5}s')13 time.sleep(reset + 5)14 continue15 resp.raise_for_status()16 return resp.json()17 raise Exception('Max retries exceeded')- Always refresh the access token before starting a post flow — the 24-hour expiry is non-negotiable
- Add 10-second minimums between publish endpoint calls to stay well within 6 req/min
- Monitor the daily posting cap (~15 posts/account) in your own database — TikTok returns an error when exceeded
- Upload chunks as quickly as the upload URL allows — it has an expiry and slow networks can cause failures
- Use 10MB chunk size for the optimal balance of reliability and upload speed on typical server connections
Security checklist
- Store client_key, client_secret, access_token, and refresh_token in environment variables or a secrets manager
- Never embed credentials in video files or visible UI elements
- Implement automated token refresh every 18-20 hours with failure alerts
- Log all publish operations with publish_id, video_id, and timestamp for audit purposes
- Use consistent server IP addresses for API calls — TikTok monitors for IP/geolocation anomalies
- Never include competitor watermarks, third-party logos, or external links in API-uploaded videos
- Validate video content for Terms of Service compliance before uploading to avoid account bans
Automation use cases
Content Calendar Publisher
advancedQueue videos with metadata in a database, fire a cron job at scheduled times to check for due posts, and execute the full upload-and-publish flow automatically.
Cross-Platform Video Syndicator
advancedAfter publishing to Instagram or YouTube, automatically repost the same video to TikTok using the Content Posting API with adapted captions.
Batch Product Video Publisher
advancedFor e-commerce brands, automatically publish product demo videos to TikTok when new products launch in Shopify, using auto-generated captions.
No-code alternatives
Don't want to write code? These platforms can automate the same workflows visually.
Zapier
Free tier; Starter from $19.99/monthZapier has limited TikTok integration and cannot post videos through the Content Posting API flow — it's mainly for lead generation forms.
- + No code
- + Easy setup for other platforms
- - No video upload support via TikTok API
- - Same audit requirements
- - Very limited TikTok module
Make (formerly Integromat)
Free tier (1,000 ops/month); Core from $9/monthMake has some TikTok support but the chunked video upload flow requires direct API access that no-code tools cannot easily abstract.
- + Visual workflow builder
- + More affordable than Zapier
- - Chunked upload not supported natively
- - Same audit requirements apply
- - Complex setup
n8n
Free (self-hosted); Cloud from $20/monthn8n can implement the full TikTok posting pipeline via HTTP request nodes, including chunked uploads, making it the most capable no-code alternative.
- + Free self-hosted
- + Full HTTP API support including chunked upload
- + Complete flow control
- - Requires server setup
- - More complex than Zapier
- - Same audit requirements
Best practices
- Always call creator_info/query before every post and display creator_nickname in your UI — this is a hard TikTok audit requirement
- Apply for the Content Posting Audit early in development (it takes 2-6 weeks) — test with SELF_ONLY during the wait
- Always refresh the access token at the start of every posting flow — the 24-hour expiry is strict
- Use exactly 10MB chunk size for reliable uploads — smaller increases HTTP overhead, larger risks timeouts
- Start uploading immediately after receiving the upload_url from video/init/ — the URL has a time limit
- Track the daily posting cap (~15/account) in your own database and build queue management to distribute posts across days
- Store publish_id and the resulting video_id for every post — this is your audit trail and debugging data
Ask AI to help
Copy one of these prompts to get a personalized, working implementation.
I'm building a TikTok video poster using the Content Posting API v2. The flow is: POST /v2/post/publish/creator_info/query/ → POST /v2/post/publish/video/init/ → PUT chunked upload to upload_url → POST /v2/post/publish/status/fetch/. My access tokens expire every 24 hours. Help me: 1) implement a robust token refresh system using the refresh_token that runs automatically every 18 hours, 2) build the chunked upload with proper Content-Range headers and retry logic for failed chunks, 3) handle the case where the poll returns SELF_ONLY privacy (app not yet audited) and alert the operator.
Build a React video scheduling dashboard for TikTok. It needs: a queue of scheduled TikTok posts with video thumbnail preview, caption, scheduled time, and status (queued, uploading, published, failed); a post creation form with video file upload, caption editor with hashtag suggestions, privacy level selector (showing options from creator_info), and datetime picker; an 'Audit Status' banner that prominently shows whether the app has TikTok audit approval with instructions if not; and a token health indicator showing when the access token was last refreshed. Use Supabase for storage and Edge Functions for the TikTok API calls.
Frequently asked questions
Why are my TikTok posts private (SELF_ONLY) even when I set PUBLIC_TO_EVERYONE?
Your app has not passed TikTok's Content Posting Audit. Without audit approval, all posts are forced to SELF_ONLY mode regardless of the privacy_level parameter you set. The audit takes 2-6 weeks and requires demonstrating that your app serves a broad audience. Apply at developers.tiktok.com under Content Posting API. During development, test with SELF_ONLY intentionally to validate your flow works before the audit completes.
What happens when my TikTok access token expires?
You'll get error code 'access_token_invalid' (HTTP 401) on all API calls. TikTok access tokens expire every 24 hours without exception. You must call POST /v2/oauth/token/ with grant_type=refresh_token and your 365-day refresh_token to get a new access_token. Set up an automated cron job that runs every 18-20 hours to refresh before expiry. Alert if the refresh fails — a failed refresh means your next post attempt will also fail.
How does TikTok's chunked video upload work?
After calling /video/init/, you receive an upload_url. Split your video into chunks (10MB recommended) and PUT each one with a Content-Range header in the format 'bytes {start}-{end}/{total}'. For example, for a 30MB video: first chunk is 'bytes 0-10485759/31457280', second is 'bytes 10485760-20971519/31457280', third is 'bytes 20971520-31457279/31457280'. Upload chunks sequentially — TikTok does not support parallel chunk uploads. Start uploading immediately after receiving the upload_url as it has a time limit.
What is the daily posting limit for TikTok's API?
TikTok's official documentation states: 'The upper limit may vary among creators (typically around 15 posts per day per creator account) and is shared across all API Clients using Direct Post.' This is not a hard published number — it depends on the creator account's settings agreed upon during your audit application. The limit is shared across all apps using the Direct Post API for that creator, not per-app.
What video formats does the TikTok API accept?
Supported formats: MP4, MOV, WEBM, AVI. Recommended: MP4 with H.264 video codec and AAC audio codec, 9:16 aspect ratio, 1080x1920px, 23-60 FPS. File size up to 1GB via API. Minimum duration: 3 seconds. Maximum duration: varies per creator (from creator_info/query). Re-encode with ffmpeg if needed: `ffmpeg -i input.mp4 -c:v libx264 -c:a aac -vf scale=1080:1920 output.mp4`.
Can RapidDev help navigate the TikTok audit process?
Yes — RapidDev has experience with the TikTok Content Posting Audit process and building compliant applications. We help structure your app's use case to pass the audit, build the required UX elements (creator nickname display, commercial content checkbox), and implement the full posting pipeline. Book a free consultation at rapidevelopers.com.
What are the mandatory UX requirements for TikTok's audit?
TikTok's audit requires: (1) display the creator's nickname from creator_info/query in your posting UI, (2) include a Commercial Content checkbox with two options — 'Your Brand' and 'Branded Content (Paid Partnership)' — for posts containing branded content, and (3) let users consent to music usage for their post. Skipping these UI elements is grounds for audit rejection. The audit reviewer will test your app's actual interface.
Need this automated?
Our team has built 600+ apps with API automations. We can build this for you.
Book a free consultation