TikTok max_video_post_duration_sec: trim before Direct Post
TikTok's creator_info endpoint returns max_video_post_duration_sec, a per-creator limit. Read it first, then cut the clip to fit with Sume video trim.

The maximum video length for a TikTok API post varies by creator. The Query Creator Info page says max_video_post_duration_sec is the longest video duration in seconds that the creator can post, that different users have different maximum video-duration privileges, and that developers should use the field to stop video posts that are too long (read 2026-10-02). Its example response shows 300.
So read the number per creator, then cut with Sume's video trim so the clip is never longer than it.
Where does the field come from?
POST https://open.tiktokapis.com/v2/post/publish/creator_info/query/ with a user access token, scope video.publish. The page says each access token is limited to 20 requests per minute, and that your export screen must call the endpoint and use the latest values.
| Field | Meaning |
|---|---|
| max_video_post_duration_sec | Longest video the creator can post, in seconds |
| privacy_level_options | Privacy choices open to this account |
| comment_disabled | True if comments are set to No one |
| duet_disabled / stitch_disabled | True if private or set to No one |
How do I cut a clip to the creator's limit?
Video trim takes start and exactly one of end or duration. An end beyond the source clamps and returns the warning trim_clamped_to_source, so start: 0, end: cap is safe for a clip shorter than the cap. The default precision is exact, a frame-accurate re-encode. Trim output is at most 900 seconds, so a creator whose limit is longer needs a second look at the source.
Trim is async by default; poll GET /v1/jobs/:id/status, then fetch GET /v1/jobs/:id/result for the new MP4.
import os, requests
tt = requests.post("https://open.tiktokapis.com/v2/post/publish/creator_info/query/",
headers={"Authorization": f"Bearer {os.environ['TIKTOK_ACCESS_TOKEN']}",
"Content-Type": "application/json; charset=UTF-8"}, timeout=30)
tt.raise_for_status()
cap = tt.json()["data"]["max_video_post_duration_sec"]
r = requests.post("https://api.sume.com/v1/video-trim", timeout=60,
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
"Idempotency-Key": f"tiktok-cap-{cap}-001"},
json={"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"start": 0, "end": cap})
r.raise_for_status()
print("cap", cap, "trim job", r.json()["data"]["request_id"])Does trimming set the AI label?
No. The Direct Post page separately carries is_aigc for AI-generated video; trimming does not set it. Trim costs $0.02 per job per its docs; confirm the current rate in GET /v1/catalog.
What should I do?
Call creator_info per account at publish time, not once at setup, since privileges can differ by user. Cache it for the batch, stay under 20 calls a minute per token, trim to the cap, and only then start the upload.
Sources
Related posts
More in Integrations
- TikTok privacy_level_options: public vs private account values
TikTok creator_info returns different privacy_level_options for public and private accounts, and Direct Post privacy_level must match one. Values for each.
- TikTok publish webhooks vs Sume run webhooks: wire both safely
TikTok sends webhooks for failed, complete, inbox, public and removed posts. Sume signs its own run webhook separately. Keep two receivers and verify Sume's.
- Val Town free 1-minute timeout: a Sume webhook receiver val
Val Town's free plan stops a val at 1 minute and runs crons every 15 minutes at best. Submit Sume jobs async, then take the result by webhook or a slow cron.
- Vercel Workflow createWebhook is token-only: verify Sume first
createWebhook trusts only the URL token. For a Sume callback, verify the sume-v1 signature in your own route, then resume a hook with resumeHook.
Written by Sume