Postpone Logo
Platforms

TikTok

Schedule video content to TikTok

Mutation

Use the scheduleTikTokPost mutation to schedule video content to TikTok:

Mutation
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

username
String! required
The username of the connected TikTok account to post from
schedulingMode
SchedulingModeType
How the post date is decided. Options: SPECIFIC_TIME, QUEUE_NEXT (default: SPECIFIC_TIME). Only accepted when scheduling a new post. See Scheduling at the Next Open Slot.
caption
String
The caption text for the video (optional)
description
String
The description text for the video (optional)
media
[SimpleMediaInput]
Media files to attach to the post: a single video, or several images for a photo carousel. Each item references a file by id, name, or url. See Attaching Media. Only supported when scheduling new posts, not when updating existing ones.
privacyLevel
TikTokPrivacyLevel! required
Privacy setting for the video. Options: PUBLIC_TO_EVERYONE, FOLLOWER_OF_CREATOR, MUTUAL_FOLLOW_FRIENDS, SELF_ONLY
allowUsersToComment
Boolean! required
Whether users can comment on the video
allowUsersToDuet
Boolean! required
Whether users can create duets with the video
allowUsersToStitch
Boolean! required
Whether users can stitch with the video
autoAddMusic
Boolean
Whether to automatically add music to the video (default: false)
isBrandContent
Boolean! required
Whether this is branded content that needs disclosure
isPaidPartnership
Boolean! required
Whether this is a paid partnership that needs disclosure
isAiGeneratedContent
Boolean
Whether the content is AI-generated (default: false)
submissions
[TikTokPostSubmissionInputType!]! required
Array of submissions defining when to post (minimum 1 submission)
publishingStatus
PublishingStatusType
Publishing status. Options: READY_TO_PUBLISH, DRAFT (default: READY_TO_PUBLISH)
postTags
[ID!]
Array of post tag IDs to organize your content. See Post Tags.
id
ID
ID of existing post when updating (only for updates)

TikTokPostSubmissionInputType

Each submission defines a specific posting schedule:

postAt
DateTime
When to publish the video (must be in the future). Required unless you pass schedulingMode: QUEUE_NEXT on the post when scheduling a new one, or the post is a draft. See Drafts without a date.
publishingMethod
PublishingMethodType
How to publish the content. Options: AUTOMATIC, MANUAL (default: AUTOMATIC)
id
ID
ID of existing submission when updating (only for updates)

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
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"}]
  }
}
The update mutation uses the same input type as the create mutation. Include the 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

The API enforces TikTok's content policies and technical limitations:
  • 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