TikTok upload API Schedule videos and photo posts

Upload and schedule TikTok videos and photo carousels from your code or AI agent, with the privacy level and the comment, duet and stitch settings TikTok asks for on every post.

Base URL https://api.so-me.studio/v1 · Auth X-API-Key · socialMedia: TIKTOK

What you can publish to TikTok

Send one of these values as postType. Every post needs text, and photos or videos are attached by fileId from your media library.

VIDEO

One video.

IMAGE

One photo, published as a TikTok photo post.

MULTIPLE_IMAGES

A swipeable photo carousel.

Schedule a TikTok post

Upload the media, then create the post. Leave out scheduledAt to publish right away.

  1. Read the creator settings

    TikTok decides which privacy levels each creator may use. Read them first, then let the user pick one.

    Read the creator settings
    curl https://api.so-me.studio/v1/accounts/<account-uuid>/tiktok/creator-info \
      -H "X-API-Key: $SOME_API_KEY"
    
    # → { "privacyLevelOptions": ["PUBLIC_TO_EVERYONE", "SELF_ONLY", …],
    #     "commentDisabled": false, "duetDisabled": false, … }
  2. Reserve an upload URL

    POST /v1/media/presign-upload adds the file to your media library and returns a fileId and a presigned uploadUrl.

    Reserve an upload URL
    curl -X POST https://api.so-me.studio/v1/media/presign-upload \
      -H "X-API-Key: $SOME_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"files":[{"filename":"editing-tips.mp4","mimetype":"video/mp4","size":31457280}]}'
    
    # → [{ "fileId": "…", "uploadUrl": "https://…", "fileSrc": "…", "s3Key": "…" }]
  3. Upload the file

    PUT the bytes to uploadUrl with exactly the Content-Type you declared. The URL is valid for one hour.

    Upload the file
    curl -X PUT "$UPLOAD_URL" \
      -H "Content-Type: video/mp4" \
      --upload-file ./editing-tips.mp4
  4. Create the post

    POST /v1/posts with the fileId. The response is the post with status SCHEDULED, and it publishes at scheduledAt through a queue that retries on failure.

    Create the post
    curl -X POST https://api.so-me.studio/v1/posts \
      -H "X-API-Key: $SOME_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "socialMedia": "TIKTOK",
        "postType": "VIDEO",
        "text": "3 editing tricks in 30 seconds #editingtips",
        "fileIds": ["<fileId>"],
        "scheduledAt": "2026-11-05T18:00:00Z",
        "tiktok": {
          "privacyLevel": "PUBLIC_TO_EVERYONE",
          "allowComments": true,
          "allowDuet": false,
          "allowStitch": true
        }
      }'

accountId is optional when the workspace has one TikTok account. Otherwise pass an id from GET /v1/accounts.

Files attached with fileIds are checked against the TikTok limits below before anything is queued. A file that breaks a rule returns 400 with a report per file.

TikTok options

The fields that change how a post is published on TikTok.

FieldWhat it does
tiktok.privacyLevelRequired. PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY, limited to the levels the creator info lists. A post without it returns 400 TIKTOK_PRIVACY_LEVEL_REQUIRED.
tiktok.allowCommentsWhether viewers can comment, true by default. Turned off, with a warning, when the creator has disabled comments.
tiktok.allowDuet · tiktok.allowStitchWhether viewers can duet or stitch the video, true by default. Video only.
tiktok.brandContentToggle · tiktok.brandOrganicToggleDisclosure flags: brandContentToggle marks a paid partnership, brandOrganicToggle marks promotion of your own business. Both are false by default.
GET /v1/accounts/:id/tiktok/creator-infoReturns the allowed privacy levels, the comment, duet and stitch settings of the creator and the longest video they may post. Cached for ten minutes.

TikTok media limits

Social media studio checks each file against these limits before it publishes. They are our configured limits, not a promise from TikTok: GET /v1/media/rules returns the live table, and POST /v1/media/validate checks a file without posting it.

Post type VIDEO

Formats
MP4, MOV, WebM
Max file size
350 MB
Files per post
1
Max duration
10 min
Dimensions
360–4096 px
Video codecs
H.264, H.265, VP8, VP9
Frame rate
≤ 60 fps

Post type IMAGE

Formats
JPEG, PNG, WebP
Max file size
20 MB
Files per post
1
Dimensions
≥ 360 px

Post type MULTIPLE_IMAGES

Formats
JPEG, PNG, WebP
Max file size
20 MB each
Files per post
2–20 per request
Dimensions
≥ 360 px

Know when it is live

Publishing is asynchronous. Subscribe to post.published and post.failed, or poll GET /v1/posts/:id until postStatus is POSTED or FAILED.

Subscribe once
curl -X POST https://api.so-me.studio/v1/webhooks/subscriptions \
  -H "X-API-Key: $SOME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/social",
    "categories": ["post"],
    "events": ["post.published", "post.failed"]
  }'

# The response includes the secret that signs every delivery.
What each delivery looks like
POST /hooks/social
X-Webhook-Event: post.published
X-Webhook-Signature: <hex HMAC-SHA256 of the raw body>

{
  "event": "post.published",
  "category": "post",
  "timestamp": "2026-11-03T15:00:07.412Z",
  "data": { "postId": "…", "platform": "TIKTOK" }
}

Every delivery is signed with HMAC-SHA256 in X-Webhook-Signature. post.failed fires after the last retry; fix the cause and call POST /v1/posts/:id/retry. A first comment reports on its own with post.first_comment_posted or post.first_comment_failed.

Building an AI agent?

The same API key drives an MCP server with 200+ tools and a CLI, so an agent can post to TikTok without hand-written HTTP calls.

MCP server

Add the server to Claude, Cursor or any MCP client with your API key. OAuth works too. For TikTok, the agent calls these tools with the same fields as the REST request:

  • get_tiktok_creator_info
  • presign_media_upload
  • create_post
mcp.json
{
  "mcpServers": {
    "so-me-studio": {
      "url": "https://api.so-me.studio/mcp",
      "headers": { "X-API-Key": "sk_live_…" }
    }
  }
}

CLI

Install it with npm i -g @social-media-scheduler/cli. It uploads local files for you and prints JSON, so a script or a CI job can schedule a TikTok post in one command.

so-me
so-me posts:create --platform TIKTOK --post-type VIDEO \
  -m ./editing-tips.mp4 \
  -c "3 editing tricks in 30 seconds #editingtips" \
  -s 2026-11-05T18:00:00Z \
  --tiktok-privacy PUBLIC_TO_EVERYONE --no-tiktok-allow-duet

API, CLI and MCP access is included on every paid plan: Lite, Creator, Standard, Advanced and Lifetime. See plans and limits

Keep reading

Other platform guides

The TikTok Content Posting API refuses a post without one, and only the levels allowed for that creator are valid. Read them from the creator-info route, let the user choose, and send tiktok.privacyLevel.

Yes. Send postType MULTIPLE_IMAGES with two or more photos, or IMAGE for a single one. Photos larger than 1080p are resized and saved as JPEG at publish time, so large originals are fine.

After TikTok has processed the post and made it public. TikTok publishes asynchronously, so the post first carries the TikTok publish id and the final link is filled in afterwards.

No. You connect the TikTok account once in the Social media studio dashboard through the TikTok sign-in. Its tokens are stored encrypted and refreshed on our side, and your code only sends your Social media studio API key in the X-API-Key header.

No. It returns as soon as the post is queued. Publishing runs in a worker that retries on failure, so listen for post.published and post.failed, or poll GET /v1/posts/:id.

The REST API, the CLI and the MCP server are included on every paid plan: Lite, Creator, Standard, Advanced and Lifetime. Lite, Creator, Standard and Advanced start with a 7-day trial (card required), and Lifetime is a one-time payment.

Schedule once.
Post everywhere.

Stop juggling tabs, draft, customize, and publish to 20 platforms from a single calendar.

TikTok Upload API: Schedule Videos & Photo Posts