TikTok
Mutation
Use the scheduleTikTokPost mutation to schedule video content to TikTok:
mutation ScheduleTikTokPost($input: ScheduleTikTokPostInput!) {
scheduleTikTokPost(input: $input) {
success
errors {
field
message
}
post {
id
socialAccount {
id
username
}
publishingStatus
caption
description
privacyLevel
allowUsersToComment
allowUsersToDuet
allowUsersToStitch
isBrandContent
isPaidPartnership
isAiGeneratedContent
gallery {
id
galleryMediaSet {
id
media {
url
mimeType
}
}
}
submissions {
id
postAt
publishingMethod
}
}
}
}
Input Parameters
ScheduleTikTokPostInput
SPECIFIC_TIME, QUEUE_NEXT (default: SPECIFIC_TIME).
Only accepted when scheduling a new post. See Scheduling at the Next Open Slot.id, name, or url. See Attaching Media.
Only supported when scheduling new posts, not when updating existing ones.PUBLIC_TO_EVERYONE, FOLLOWER_OF_CREATOR, MUTUAL_FOLLOW_FRIENDS, SELF_ONLYREADY_TO_PUBLISH, DRAFT (default: READY_TO_PUBLISH)TikTokPostSubmissionInputType
Each submission defines a specific posting schedule:
schedulingMode: QUEUE_NEXT on the post when scheduling a new one, or the post is a draft.
See Drafts without a date.AUTOMATIC, MANUAL (default: AUTOMATIC)Examples
Simple TikTok Video
Schedule a basic TikTok video with a video from URL.
{
"input": {
"username": "myhandle",
"caption": "Check out this amazing dance! 💃 #dance #viral #fyp",
"media": [{ "url": "https://example.com/dance-video.mp4" }],
"privacyLevel": "PUBLIC_TO_EVERYONE",
"allowUsersToComment": true,
"allowUsersToDuet": true,
"allowUsersToStitch": false,
"isBrandContent": false,
"isPaidPartnership": false,
"submissions": [
{
"postAt": "2025-12-01T18:00:00Z"
}
]
}
}
Scheduling at the Next Open Slot
Instead of picking a time yourself, pass schedulingMode: QUEUE_NEXT and leave postAt out. Postpone puts the video in the next open slot on the account's Account Schedule, skipping any slot that already has a post on it.
{
"input": {
"username": "myhandle",
"schedulingMode": "QUEUE_NEXT",
"caption": "This one goes out at my next open slot. #fyp",
"media": [{ "url": "https://example.com/dance-video.mp4" }],
"privacyLevel": "PUBLIC_TO_EVERYONE",
"submissions": [{}]
}
}
Leave postAt off the submissions — the resolved slot becomes the date for all of them.
The account needs a schedule set up for this to work, postAt and QUEUE_NEXT can't be combined, and updateScheduledTikTokPost rejects schedulingMode. See Scheduling at the Next Open Slot for the full rules.
TikTok Video with Content Library Media
Schedule a video using media from your Content Library. Reference the file by its id, which every upload mutation returns.
{
"input": {
"username": "myhandle",
"caption": "Tutorial time! Save this for later 📚 #tutorial #howto #learn",
"description": "Step-by-step guide to mastering this technique",
"media": [{ "id": "1043" }],
"privacyLevel": "PUBLIC_TO_EVERYONE",
"allowUsersToComment": true,
"allowUsersToDuet": false,
"allowUsersToStitch": true,
"autoAddMusic": true,
"isBrandContent": false,
"isPaidPartnership": false,
"submissions": [
{
"postAt": "2025-12-01T16:30:00Z"
}
]
}
}
You can also reference the file by name. Names are matched case-insensitively and the first match wins, so prefer id when several files share a name.
{
"media": [{ "name": "tutorial-video.mp4" }]
}
Branded Content Video
Schedule a TikTok video with brand content disclosures.
{
"input": {
"username": "myhandle",
"caption": "Loving this new product! #sponsored #brandpartner #ad",
"media": [{ "url": "https://example.com/brand-video.mp4" }],
"privacyLevel": "PUBLIC_TO_EVERYONE",
"allowUsersToComment": true,
"allowUsersToDuet": true,
"allowUsersToStitch": true,
"isBrandContent": true,
"isPaidPartnership": true,
"isAiGeneratedContent": false,
"submissions": [
{
"postAt": "2025-12-01T20:00:00Z"
}
]
}
}
AI-Generated Content Video
Schedule a video created with AI tools.
{
"input": {
"username": "myhandle",
"caption": "AI-generated content experiment! What do you think? 🤖 #ai #tech #future",
"media": [{ "url": "https://example.com/ai-video.mp4" }],
"privacyLevel": "PUBLIC_TO_EVERYONE",
"allowUsersToComment": true,
"allowUsersToDuet": false,
"allowUsersToStitch": false,
"isBrandContent": false,
"isPaidPartnership": false,
"isAiGeneratedContent": true,
"submissions": [
{
"postAt": "2025-12-01T14:00:00Z"
}
]
}
}
Response Types
Success Response
{
"data": {
"scheduleTikTokPost": {
"success": true,
"errors": [],
"post": {
"id": "123",
"socialAccount": {
"id": "456",
"username": "myhandle"
},
"publishingStatus": "READY_TO_PUBLISH",
"caption": "Check out this amazing dance! 💃 #dance #viral #fyp",
"description": null,
"privacyLevel": "PUBLIC_TO_EVERYONE",
"allowUsersToComment": true,
"allowUsersToDuet": true,
"allowUsersToStitch": false,
"isBrandContent": false,
"isPaidPartnership": false,
"isAiGeneratedContent": false,
"gallery": {
"id": "789",
"media": [
{
"id": "101",
"url": "https://cdn.example.com/dance-video.mp4",
"type": "video"
}
]
},
"submissions": [
{
"id": "112",
"postAt": "2025-12-01T18:00:00Z",
"publishingMethod": "AUTOMATIC"
}
]
}
}
}
}
Error Response
{
"data": {
"scheduleTikTokPost": {
"success": false,
"errors": [
{
"field": "media",
"message": "TikTok videos must be between 3 seconds and 10 minutes long."
}
],
"post": null
}
}
}
Updating a Post
To update an existing scheduled post, use the same input type with the corresponding update mutation and include the post id:
mutation UpdateScheduledTikTokPost($input: ScheduleTikTokPostInput!) {
updateScheduledTikTokPost(input: $input) {
success
errors {
field
message
}
post {
id
}
}
}
Pass the id of the post you want to update in the input, along with the fields you want to change:
{
"input": {
"id": "12345",
"username": "myhandle",
"caption": "Updated caption!",
"submissions": [{"postAt": "2025-12-01T15:30:00Z"}]
}
}
id field to specify which post to update. Only scheduled posts that have not been published yet can be updated.postAt is required on an update, so every update states the date the post goes out on — pass the date it already has to leave it where it is. A draft staying a draft is exempt, and a draft you're promoting to READY_TO_PUBLISH needs a date of your choosing; see Drafts without a date.
schedulingMode is not accepted on an update at all; see Scheduling at the Next Open Slot.
Validation Rules
- Video Duration: Minimum 3 seconds, maximum 10 minutes
- File Size: Maximum 287.6MB per video
- Video Format: Supports MP4, MOV, MPEG, AVI, WMV, 3GPP, WEBM
- Aspect Ratios: Vertical (9:16) recommended, also supports 1:1 and 16:9
- Resolution: Minimum 540x960, maximum 1080x1920 for vertical videos
- Frame Rate: Minimum 23fps, maximum 60fps
- Audio: Required for video content
- Caption Length: No strict limit, but shorter captions perform better
- Hashtags: Use 3-5 relevant hashtags for better discoverability
- Brand Content: Must be properly disclosed if sponsored
- AI Content: Must be labeled if AI-generated
- Scheduling: Posts must be scheduled for future dates only
- Account Limits: Respects your plan's monthly post limits
Common Errors
The specified username is not connected to your Postpone account. Connect the account in your settings first.
Your video duration is outside TikTok's accepted range. Trim your video to be between 3 seconds and 10 minutes.
You must include a video file. Use media to attach a video to your post.
Your video format is not supported. Use MP4, MOV, MPEG, AVI, WMV, 3GPP, or WEBM format.
Your video file is too large. TikTok supports videos up to 287.6MB in size.
Your video aspect ratio is not optimal. Use vertical (9:16), square (1:1), or horizontal (16:9) formats.
The postAt timestamp must be in the future. Check your timezone settings.
A new post has to say when it goes out: pass a postAt, or schedulingMode: QUEUE_NEXT. Drafts are exempt: leave postAt off one and it is parked on a placeholder date about 30 days out.
schedulingMode isn't accepted on an update, so a postAt is the only way to say when the post goes out. You'll also see it when promoting a parked draft to publishingStatus: READY_TO_PUBLISH without giving it a date.
schedulingMode: QUEUE_NEXT needs an Account Schedule on the account you're posting to. Set one up, or pass an explicit postAt.
schedulingMode is only accepted when scheduling a new post. To move a post that is already scheduled, pass a postAt to updateScheduledTikTokPost.
When isBrandContent is true, ensure your content follows TikTok's branded content guidelines.
You've reached your plan's TikTok post limit for the scheduled month. Upgrade your plan or schedule for a different month.