TikTok API Documentation

Post videos and photo carousels to TikTok via our API.

All API requests require authentication using your API Key:

// Add this header to all API requests
X-API-Key: sk_your_api_key_here

Get Your API Key

  1. Login to your dashboard
  2. Click the profile icon in the header
  3. Generate or view your API key
  4. Copy and use in your requests

Security: Never share your API key or commit it to public repositories. Regenerate if compromised.

Post to TikTok in seconds:

// POST Video
fetch('https://api-tiktok.wahdx.co/api/content/post', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sk_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    accountId: 'YOUR_ACCOUNT_ID',
    content: 'Check out this video! #viral #fyp',
    mediaItems: [
      { url: 'https://your-domain.com/video.mp4' }
    ],
    tiktokSettings: {
      privacy_level: 'PUBLIC_TO_EVERYONE',
      allow_comment: true,
      allow_duet: true,
      allow_stitch: true,
      video_cover_timestamp_ms: 1000
    }
  })
})
POST/api/content/postCreate post
GET/api/content/status/:accountId/:publishIdCheck status
GET/api/content/creator-info/:accountIdGet permissions
GET/api/content/accountsList linked accounts

TikTok supports two content types:

Video

Single video post (3s - 10min)

Photo Carousel

2-35 photos in slideshow

Important: You cannot mix photos and videos in the same post.

Recommended Video Specs

SpecificationRequirement
FormatMP4, MOV, WebM
CodecH.264 (recommended)
Aspect Ratio9:16 (vertical)
Resolution1080x1920 (Full HD)
Duration3 seconds - 10 minutes
File SizeUp to 500MB
Frame Rate24-60 FPS

Video Cover (Thumbnail)

Customize which frame appears as the thumbnail:

{
  "tiktokSettings": {
    "video_cover_timestamp_ms": 3000
  }
}
  • • Value in milliseconds
  • • Default: 0 (start)
  • • Must be within video duration
Content TypeTitle FieldDescription Field
Video2,200 characters (Caption)-
Photo Carousel90 characters4,000 characters

Tip: Use the photoTitle field for the main headline and content field for the longer description when posting photo carousels.

Let TikTok automatically add recommended music to photo carousels:

{
  "tiktokSettings": {
    "auto_add_music": true // Default: true for photos
  }
}

Note: This feature is only available for photo carousels.

Disclose AI-generated content to comply with TikTok policies:

{
  "tiktokSettings": {
    "video_made_with_ai": true
  }
}

When to use: Set to true if your content was created or significantly modified using AI tools.

Send content to Creator's TikTok Inbox as a draft instead of publishing immediately. Works for both video and photo posts.

Usage

Add draft: true to your tiktokSettings:

// Video Draft
{
  "accountId": "YOUR_ACCOUNT_ID",
  "content": "My video caption",
  "mediaItems": [
    { "url": "https://your-domain.com/video.mp4" }
  ],
  "tiktokSettings": {
    "draft": true
  }
}

// Photo Draft
{
  "accountId": "YOUR_ACCOUNT_ID",
  "content": "Photo description",
  "mediaItems": [
    { "url": "https://your-domain.com/photo1.jpg" },
    { "url": "https://your-domain.com/photo2.jpg" }
  ],
  "tiktokSettings": {
    "media_type": "photo",
    "draft": true,
    "privacy_level": "PUBLIC_TO_EVERYONE"
  }
}

How It Works

TypeBehaviorSettings
Video DraftSent to TikTok inboxTitle, privacy, etc. configured in TikTok app
Photo DraftSent to TikTok inboxAll settings sent via API

Video Draft Note: When sending a video to inbox, only the video file is uploaded. Title, privacy level, and other settings must be configured directly in the TikTok app before publishing.

Use case: Ideal for workflows requiring manual review before publishing, or for unaudited apps that cannot use Direct Post.

PUBLIC_TO_EVERYONE

Visible to everyone

MUTUAL_FOLLOW_FRIENDS

Visible to mutual followers

FOLLOWER_OF_CREATOR

Visible to followers only

SELF_ONLY

Private (only you)

These fields are required for all posts:

privacy_level- Functionality visibility
allow_comment- Enable/disable comments
allow_duet- Enable/disable duets (video only)
allow_stitch- Enable/disable stitch (video only)

Invalid privacy_level

The privacy level must maintain or restrict the user's account settings. Check creator-info endpoint for allowed values.

Cannot mix media types

A post must be either single video OR photo carousel. Mixing is not supported.

Video rejected

  • • Check duration (3s - 10min)
  • • Verify format (MP4 recommended)
  • • Ensure file size < 500MB

Title Truncated

Photo carousel titles are limited to 90 characters. Descriptions can be up to 4,000 characters.

⚡ Maximum Subscription Only

This feature is exclusively available for users with Maximum subscription plan. Other plans will receive a 403 error.

Connect TikTok accounts via QR code scan — no browser redirect needed.
The user scans the QR code with their TikTok app and confirms the authorization. This method is ideal if you want to integrate our platform into your own custom application, allowing your users to link their TikTok accounts seamlessly from within your app.

1️⃣

Request QR

POST /qr-login/request

2️⃣

Display QR

Show base64 image to user

3️⃣

Poll Status

POST /qr-login/check every 10s

4️⃣

Account Linked

Status: confirmed

1. Request QR Code

POST /api/content/qr-login/request

Request Body (optional)

{
  "unique_id": "my_session_12345"  // Optional, min 8 chars. Auto-generated if not provided.
}

Example Request

// Step 1: Request QR Code
fetch('https://api-tiktok.wahdx.co/api/content/qr-login/request', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sk_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    unique_id: 'my_session_12345' // Optional, min 8 chars
  })
})

Success Response (200)

{
  "success": true,
  "data": {
    "qrCodeImage": "data:image/png;base64,iVBORw0KGgo...",
    "token": "VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D",
    "unique_id": "my_session_12345",
    "expiresIn": 300
  }
}

Subscription Error (403)

{
  "error": "QR Code login is only available for Maximum subscription",
  "subscription": "free"
}

2. Check QR Status

POST /api/content/qr-login/check

Request Body

{
  "token": "VJ5JCKGJGRSWNMFWHQH4W5NKY943Q97D"  // Required: token from Step 1
}

Example Request

// Step 2: Poll QR Status (every 3 seconds)
fetch('https://api-tiktok.wahdx.co/api/content/qr-login/check', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sk_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    token: 'TOKEN_FROM_STEP_1'
  })
})

Response by Status

new — QR code not yet scanned

{ "success": true, "data": { "status": "new", "unique_id": "my_session_12345" } }

scanned — User has scanned, awaiting confirmation

{ "success": true, "data": { "status": "scanned", "unique_id": "my_session_12345" } }

confirmed — Account successfully linked

{
  "success": true,
  "data": {
    "status": "confirmed",
    "unique_id": "my_session_12345",
    "account": {
      "accountId": "8abd72f0-4ede-441c-9c17-XXXXXXXXX",
      "display_name": "Creator Name",
      "username": "creator_username"
    }
  }
}

expired — QR code has expired, request a new one

{ "success": true, "data": { "status": "expired", "unique_id": "my_session_12345" } }

utilised — Auth code has already been used

{ "success": true, "data": { "status": "utilised", "unique_id": "...", "message": "QR code has already been used." } }

3. Check List Account

GET /api/content/accounts

Response List Account

{
  "success": true,
  "subscription": "maximum",
  "data": [
    {
      "accountId": "aada5586-xxxx-xxxx-xxxx-XXXXXXXXXXX",
      "display_name": "Account 1",
      "username": "account_1",
      "avatar_url": "https://p16-sign-va.tiktokcdn.com/tos-...",
      "bio_description": "My awesome bio",
      "followers": 1500,
      "following": 300,
      "likes": 12500,
      "videos": 42,
      "is_verified": false
    },
    {
      "accountId": "8abd72f0-xxxx-xxxx-xxxx-XXXXXXXXXXX",
      "display_name": "Account 2",
      "username": "account_2"
    },
    {
      "accountId": "23369e89-xxxx-xxxx-xxxx-XXXXXXXXXXX",
      "display_name": "Account 3",
      "username": "account_3"
    }
  ]
}

Complete Example

// Complete QR Login Flow
async function loginWithQR(apiKey) {
  // Step 1: Request QR Code
  const qr = await fetch('https://api-tiktok.wahdx.co/api/content/qr-login/request', {
    method: 'POST',
    headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
    body: JSON.stringify({ unique_id: 'session_' + Date.now() })
  }).then(r => r.json());

  // Display QR: <img src={qr.data.qrCodeImage} />
  console.log('Scan this QR code with TikTok app');

  // Step 2: Poll status every 10 seconds
  const poll = setInterval(async () => {
    const check = await fetch('https://api-tiktok.wahdx.co/api/content/qr-login/check', {
      method: 'POST',
      headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
      body: JSON.stringify({ token: qr.data.token })
    }).then(r => r.json());

    if (check.data.status === 'confirmed') {
      clearInterval(poll);
      console.log('Account linked!', check.data.account);
    } else if (['expired', 'utilised'].includes(check.data.status)) {
      clearInterval(poll);
      console.log('QR expired, request a new one');
    }
  }, 10000);
}
{
  "success": true,
  "data": {
    "publish_id": "v_pub_url~v2.123456789",
    "public_post_url": "https://www.tiktok.com/@user/video/1234567890" // Only available after processing
  },
  "mediaType": "video"
}