# TikTok (/docs/platforms/tiktok)




What you can post [#what-you-can-post]

| Type           | Supported | Max media | Notes                                                 |
| -------------- | --------- | --------- | ----------------------------------------------------- |
| Video          | ✅         | 1         | MP4, WebM, MOV. Max 4 GB, duration varies per account |
| Photo carousel | ✅         | 35        | WebP, JPEG. Max 20 MB per image                       |

<Callout title="Limitations" type="warn">
  * **Media is required.** TikTok does not support text-only posts.
  * **You cannot mix images and video in the same post.** A post is either a single video or up to 35 photos.
  * **Video duration varies per account.** Query the creator info endpoint before posting to get the current limit.
  * **Daily API posting limit.** TikTok enforces a daily post cap for posts created via third-party APIs, separate from the native app limit. This is per-account. When you hit it, the post will fail with `spam_risk_too_many_posts`.
</Callout>

Quick start [#quick-start]

Post a video [#post-a-video]

A single video post that appears on the creator's TikTok profile. Supports MP4, WebM, and MOV up to 4 GB. Duration limit depends on the account (3, 5, or 10 minutes).

<div className="fd-steps">
  <div className="fd-step">
    Query creator info [#1-query-creator-info]

    TikTok requires that the `privacyLevel` you set matches one of the options available for the target account. Call this endpoint to get the current settings.

    ```bash
    GET /api/v1/accounts/{accountId}/tiktok-creator-info
    ```

    The response depends on the account type:

    **Public account:**

    ```json
    {
      "privacyLevelOptions": ["PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"],
      "commentDisabled": false,
      "duetDisabled": false,
      "stitchDisabled": false,
      "maxVideoPostDurationSec": 600
    }
    ```

    **Private account:**

    ```json
    {
      "privacyLevelOptions": ["FOLLOWER_OF_CREATOR", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"],
      "commentDisabled": false,
      "duetDisabled": true,
      "stitchDisabled": true,
      "maxVideoPostDurationSec": 180
    }
    ```

    If `duetDisabled` or `stitchDisabled` is `true`, TikTok will ignore the corresponding `disableDuet`/`disableStitch` settings.
  </div>

  <div className="fd-step">
    Get your media ready [#2-get-your-media-ready]

    <Tabs items="['Upload new media', 'Use existing media']">
      <Tab value="Upload new media">
        ```bash
        curl -X POST https://publishq.com/api/v1/media \
          -H "Authorization: Bearer pq_live_..." \
          -F "file=@video.mp4"
        ```
      </Tab>

      <Tab value="Use existing media">
        ```bash
        curl https://publishq.com/api/v1/media \
          -H "Authorization: Bearer pq_live_..."
        ```

        Pick the `id` of the video you want to use from the response.
      </Tab>
    </Tabs>
  </div>

  <div className="fd-step">
    Create the post [#3-create-the-post]

    The caption goes in `content` (max 2200 characters). Hashtags (`#`) and mentions (`@`) in the caption are automatically parsed by TikTok.

    ```json
    {
      "content": "New tutorial dropping 🎬 #coding #fyp",
      "mediaIds": ["video-media-id"],
      "thumbnailTimestamp": 3500,
      "accounts": [
        {
          "accountId": "tiktok-account-id",
          "platformSpecificSettings": {
            "privacyLevel": "PUBLIC_TO_EVERYONE",
            "disableComment": false,
            "disableDuet": false,
            "disableStitch": false,
            "brandContentToggle": false,
            "brandOrganicToggle": false
          }
        }
      ],
      "publishNow": true
    }
    ```
  </div>
</div>

Post a photo carousel [#post-a-photo-carousel]

A swipeable photo post with 1–35 images. WebP and JPEG only, max 20 MB per image.

<div className="fd-steps">
  <div className="fd-step">
    Query creator info [#1-query-creator-info-1]

    Same as above — call the creator info endpoint to get the available privacy options.

    ```bash
    GET /api/v1/accounts/{accountId}/tiktok-creator-info
    ```
  </div>

  <div className="fd-step">
    Get your media ready [#2-get-your-media-ready-1]

    <Tabs items="['Upload new media', 'Use existing media']">
      <Tab value="Upload new media">
        ```bash
        curl -X POST https://publishq.com/api/v1/media \
          -H "Authorization: Bearer pq_live_..." \
          -F "file=@photo1.jpg"
        ```

        Repeat for each image. Collect the `id` from each response.
      </Tab>

      <Tab value="Use existing media">
        ```bash
        curl https://publishq.com/api/v1/media \
          -H "Authorization: Bearer pq_live_..."
        ```

        Pick the `id`s of the images you want to use from the response.
      </Tab>
    </Tabs>
  </div>

  <div className="fd-step">
    Create the post [#3-create-the-post-1]

    Attach 1–35 images. TikTok displays them as a swipeable carousel. The `content` field maps to the photo title (max 90 characters). Use `description` in `platformSpecificSettings` for longer text (max 4000 characters).

    ```json
    {
      "content": "Travel dump 🌍",
      "mediaIds": ["img-1", "img-2", "img-3", "img-4", "img-5"],
      "accounts": [
        {
          "accountId": "tiktok-account-id",
          "platformSpecificSettings": {
            "privacyLevel": "PUBLIC_TO_EVERYONE",
            "disableComment": false,
            "disableDuet": false,
            "disableStitch": false,
            "brandContentToggle": false,
            "brandOrganicToggle": false,
            "autoAddMusic": true,
            "photoCoverIndex": 2,
            "description": "Best spots from our trip through Southeast Asia 🇹🇭🇻🇳🇰🇭 #travel #photomode #backpacking"
          }
        }
      ],
      "publishNow": true
    }
    ```

    <Callout title="Photo carousel title limit" type="info">
      TikTok photo posts have a **90-character title limit** (the `content` field), while video posts allow up to 2200 characters. If you're posting to TikTok alongside platforms with longer limits, use `postOverrides` to provide a shorter title just for TikTok.

      ```json
      {
        "content": "Full description of our latest product launch with all the details...",
        "mediaIds": ["img-1", "img-2", "img-3"],
        "accounts": [
          { "accountId": "instagram-account-id" },
          {
            "accountId": "tiktok-account-id",
            "postOverrides": {
              "content": "New product just dropped 🔥"
            },
            "platformSpecificSettings": {
              "privacyLevel": "PUBLIC_TO_EVERYONE",
              "disableComment": false,
              "disableDuet": false,
              "disableStitch": false,
              "brandContentToggle": false,
              "brandOrganicToggle": false,
              "description": "Full description with all the #details and @mentions here"
            }
          }
        ],
        "publishNow": true
      }
      ```
    </Callout>
  </div>
</div>

Media specs [#media-specs]

Video [#video]

| Spec              | Value                                    |
| ----------------- | ---------------------------------------- |
| Max file size     | **4 GB**                                 |
| Min duration      | **3 seconds**                            |
| Max duration      | Varies per account (3, 5, or 10 minutes) |
| Supported formats | MP4 (recommended), WebM, MOV             |
| Supported codecs  | H.264 (recommended), H.265, VP8, VP9     |
| Framerate         | 23–60 FPS                                |
| Resolution        | Min 360px, max 4096px (both dimensions)  |

Images [#images]

| Spec                | Value               |
| ------------------- | ------------------- |
| Max file size       | **20 MB** per image |
| Max images per post | **35**              |
| Supported formats   | WebP, JPEG          |
| Max resolution      | 1080p               |

Platform-specific settings [#platform-specific-settings]

{/* Fields auto-generated from TikTokPlatformSpecificSettingsSchema */}

<PlatformSettingsTable platform="TIKTOK" />

<small>
  Full schema: 

  [TikTokPlatformSpecificSettings](/docs-scalar#model/TikTokPlatformSpecificSettings)
</small>

Not yet supported [#not-yet-supported]

* Video captions/subtitles (TikTok supports up to 20 VTT files via the API)
