Quick Start

Connect to any TikTok LIVE stream and receive real-time events in under 5 lines of code.

Quick Start - Node.js
Node.js
Python
cURL
Java
Go
C#
import WebSocket from 'ws';

const ws = new WebSocket('wss://api.tik.tools?uniqueId=streamer_name&apiKey=YOUR_KEY');

ws.on('message', (data) => {
  const event = JSON.parse(data);
  if (event.event === 'chat') {
    console.log(`${event.data.user.uniqueId}: ${event.data.comment}`);
  }
});
💡
Get your API key

Sign up at tik.tools/pricing to get a free API key. No credit card required.

🚀 Try It Now - 5-Minute Live Demo

Copy-paste this script, run it, and see real-time TikTok LIVE events in your terminal. Works on the free Sandbox tier - no credit card needed.

Zero setup required

Replace YOUR_API_KEY with your free key from tik.tools and LIVE_USERNAME with any currently live TikTok user. Runs for 5 minutes within sandbox limits.

Try It Now - Node.js
Node.js
Python
cURL
Java
Go
C#
// demo.mjs - TikTok LIVE in 5 minutes
// npm install ws
import WebSocket from 'ws';

const API_KEY       = 'YOUR_API_KEY';        // Get free key → https://tik.tools
const LIVE_USERNAME = 'tv_asahi_news';       // Any live TikTok username

const ws = new WebSocket(wss://api.tik.tools?uniqueId=${LIVE_USERNAME}&apiKey=${API_KEY}`);
let events = 0;

ws.on('open', () => console.log(`\n✅ Connected to @${LIVE_USERNAME} - listening for 5 min...\n`));
ws.on('message', (raw) => {
  const msg = JSON.parse(raw);
  events++;
  const d = msg.data || {};
  const user = d.user?.uniqueId || '';
  switch (msg.event) {
    case 'chat':        console.log(`💬 ${user}: ${d.comment}`); break;
    case 'gift':        console.log(`🎁 ${user} sent ${d.giftName} (${d.diamondCount}💎)`); break;
    case 'like':        console.log(`❤️  ${user} liked × ${d.likeCount}`); break;
    case 'member':      console.log(`👋 ${user} joined`); break;
    case 'roomUserSeq': console.log(`👀 Viewers: ${d.viewerCount}`); break;
    case 'roomInfo':    console.log(`📡 Room: ${msg.roomId}`); break;
    default:            console.log(`📦 ${msg.event}`); break;
  }
});
ws.on('close', () => console.log(`\n📊 Done! Received ${events} events.\n`));

setTimeout(() => ws.close(), );

Node.js SDK

The @tiktool/live npm package provides a high-level client and utility functions for working with TikTok LIVE data.

Install
npm install @tiktool/live

Python SDK

The tiktok-live-api PyPI package provides a high-level Python client for TikTok LIVE streams - sync and async support, decorator-based event handling, and built-in live captions.

Install
pip install tiktok-live-api
PyPI ↗Python 3.8+Async SupportLive Captions

Basic Example

basic.py - Python
from tiktok_live_api import TikTokLive

client = TikTokLive("streamer_username")

@client.on("connected")
def on_connected(event):
    print(f"Connected to @{event['uniqueId']}")

@client.on("chat")
def on_chat(event):
    print(f"[chat] {event['user']['uniqueId']}: {event['comment']}")

@client.on("gift")
def on_gift(event):
    diamonds = event.get("diamondCount", 0)
    print(f"[gift] {event['user']['uniqueId']} sent {event['giftName']} ({diamonds} diamonds)")

@client.on("like")
def on_like(event):
    print(f"[like] {event['user']['uniqueId']} liked (total: {event['totalLikes']})")

@client.on("follow")
def on_follow(event):
    print(f"[follow] {event['user']['uniqueId']} followed")

@client.on("roomUserSeq")
def on_viewers(event):
    print(f"[viewers] {event['viewerCount']} watching")

client.run()

Live Captions Example

captions.py - Python
from tiktok_live_api import TikTokCaptions

captions = TikTokCaptions(
    "streamer_username",
    translate="en",
    diarization=True,
)

@captions.on("connected")
def on_connected(event):
    print(f"Listening to @{event['uniqueId']}")

@captions.on("caption")
def on_caption(event):
    speaker = event.get("speaker", "")
    text = event["text"]
    is_final = event.get("isFinal", False)
    status = "FINAL" if is_final else "partial"
    print(f"[{status}] [{speaker}] {text}")

@captions.on("translation")
def on_translation(event):
    print(f"  -> {event['text']}")

captions.run()
TikTokLive

The main SDK class for connecting to TikTok LIVE streams via WebSocket. Handles authentication, reconnection, and event parsing automatically.

new TikTokLive({ uniqueId, apiKey, ... })

Parameters

NameTypeDescription
uniqueIdstringTikTok username (without @)
apiKeystringYour TikTool API key
sessionIdstring?Optional TikTok session ID for authenticated features

Returns

TikTokLive instance

Example

TikTokLive - Node.js
import { TikTokLive } from '@tiktool/live';

const client = new TikTokLive({
  uniqueId: 'streamer_name',
  apiKey: process.env.TIKTOOL_API_KEY
});

client.on('chat', (event) => {
  console.log(`${event.nickname}: ${event.comment}`);
});

client.on('gift', (event) => {
  console.log(`${event.nickname} sent ${event.giftName} x${event.repeatCount}`);
});

await client.connect();
// client.disconnect() to close
callApi

High-level utility that handles the full sign-and-return API flow automatically: resolves room ID → calls API → fetches signed URL → returns parsed TikTok data. Ideal for server-side integrations.

callApi(options: CallApiOptions): Promise<any>

Parameters

NameTypeDescription
apiKeystringYour TikTool API key
endpointstringAPI endpoint path (e.g. '/webcast/room_info')
uniqueIdstringTikTok username to query
method'GET'|'POST'HTTP method (default: POST)
serverUrlstring?API server URL (default: https://api.tik.tools)
extraBodyRecord?Additional body fields for POST requests

Returns

Parsed TikTok data object or null if user is not live

Example

callApi - Node.js
import { callApi } from '@tiktool/live';

// Get room info
const roomInfo = await callApi({
  apiKey: 'YOUR_KEY',
  endpoint: '/webcast/room_info',
  uniqueId: 'streamer_name'
});
console.log(roomInfo?.data?.title);

// Get stream video URLs
const video = await callApi({
  apiKey: 'YOUR_KEY',
  endpoint: '/webcast/room_video',
  uniqueId: 'streamer_name'
});
console.log(video?.data?.stream_urls?.origin?.hls);
resolveLivePage

Retrieves metadata from a TikTok live page including the room ID, session cookie (ttwid), and cluster region. Results are cached for 5 minutes. Used internally by TikTokLive.connect().

resolveLivePage(uniqueId: string): Promise<LivePageInfo | null>

Parameters

NameTypeDescription
uniqueIdstringTikTok username (with or without @)

Returns

LivePageInfo { roomId, ttwid, clusterRegion } or null

Example

resolveLivePage - Node.js
import { resolveLivePage } from '@tiktool/live';

const info = await resolveLivePage('streamer_name');
if (info) {
  console.log('Room ID:', info.roomId);
  console.log('Region:', info.clusterRegion);
  console.log('Cookie:', info.ttwid);
} else {
  console.log('User is not live');
}
resolveRoomId

Resolves a TikTok username to a numeric room ID. Thin wrapper around resolveLivePage() - returns just the room ID string. Results are cached for 5 minutes.

resolveRoomId(uniqueId: string): Promise<string | null>

Parameters

NameTypeDescription
uniqueIdstringTikTok username (with or without @)

Returns

Room ID string or null if not live

Example

resolveRoomId - Node.js
import { resolveRoomId } from '@tiktool/live';

const roomId = await resolveRoomId('streamer_name');
if (roomId) {
  console.log('Room ID:', roomId);
  // Use with REST API endpoints that require room_id
}
fetchSignedUrl

Executes a signed-URL response from the API server. When the API returns action: "fetch_signed_url", pass the response to this function to fetch the actual TikTok data. Used internally by callApi().

fetchSignedUrl(response: SignedUrlResponse): Promise<any>

Parameters

NameTypeDescription
responseSignedUrlResponseThe API response containing signed_url, headers, and cookies

Returns

Parsed JSON data from TikTok

Example

fetchSignedUrl - Node.js
import { fetchSignedUrl } from '@tiktool/live';

// Low-level usage (callApi handles this automatically)
const apiResponse = await fetch(
  'https://api.tik.tools/webcast/room_info?apiKey=KEY',
  { method: 'POST', body: JSON.stringify({ room_id: '123' }) }
).then(r => r.json());

if (apiResponse.action === 'fetch_signed_url') {
  const tiktokData = await fetchSignedUrl(apiResponse);
  console.log(tiktokData);
}

Authentication

All API requests require authentication via an API key or JWT token.

API Key

Pass your API key as a query parameter or header:

Authentication
# Query parameter
GET /webcast/check_alive?apiKey=YOUR_KEY&unique_id=username

# Header
GET /webcast/check_alive?unique_id=username
x-api-key: YOUR_KEY

JWT Token

For frontend WebSocket connections, generate a JWT token server-side and pass it as jwtKey:

WebSocket JWT
wss://api.tik.tools?uniqueId=username&jwtKey=YOUR_JWT

JWTs can be scoped to specific creators and have configurable expiry. See /authentication/jwt.

WebSocket Connection

Connect via WebSocket to receive real-time events from any TikTok LIVE stream.

Connection URL

Connection
wss://api.tik.tools?uniqueId=USERNAME&apiKey=YOUR_KEY

Message Format

Events are sent as JSON with the following structure:

JSON
{ "event": "chat", "data": { "type": "chat", "user": { ... }, "comment": "Hello!" } }

First Message

Upon connection, the server sends a roomInfo event:

roomInfo
{ "event": "roomInfo", "roomId": "7123456789", "uniqueId": "streamer", "connectedAt": "..." }
WebSocket Example - Node.js
Node.js
Python
cURL
Java
Go
C#
import WebSocket from 'ws';

const ws = new WebSocket('wss://api.tik.tools?uniqueId=streamer&apiKey=YOUR_KEY');

ws.on('open', () => console.log('Connected!'));

ws.on('message', (raw) => {
  const { event, data } = JSON.parse(raw);
  switch (event) {
    case 'roomInfo': console.log('Room:', data.roomId); break;
    case 'chat':     console.log(data.user.uniqueId + ':', data.comment); break;
    case 'gift':     console.log(data.user.uniqueId, 'sent', data.giftName); break;
    case 'like':     console.log(data.user.uniqueId, 'liked ×' + data.likeCount); break;
    case 'member':   console.log(data.user.uniqueId, 'joined'); break;
  }
});

ws.on('close', (code, reason) => console.log('Closed:', code, reason.toString()));

REST API Reference

HTTP endpoints for signing, fetching room data, and managing authentication.

POST/webcast/sign_url

Sign any TikTok webcast URL with the required X-Bogus and X-Gnarly anti-bot parameters. This is the foundation of the API - TikTok rejects unsigned requests, so this endpoint adds the cryptographic signatures needed for valid requests.

How it works: Send any raw TikTok webcast URL in the request body. The API returns the signed URL with all required parameters appended, plus the User-Agent and cookies you must use when fetching.

Use cases: Building custom TikTok integrations, signing WebSocket URLs for direct connections, or signing any TikTok API endpoint that requires X-Bogus validation.

Response data: Returns signed_url (the URL with signatures), x_bogus, x_gnarly, user_agent, and cookies fields. Always use the returned User-Agent when making the final request to TikTok.

Parameters

NameTypeRequiredDescription
urlstringYesThe TikTok URL to sign

Response

response.json
{ "status_code": 0, "data": { "signed_url": "...", "x_bogus": "...", "x_gnarly": "...", "user_agent": "...", "cookies": "..." } }
POST /webcast/sign_url - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/sign_url?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://webcast.tiktok.com/...' })
});
const data = await res.json();
console.log(data.data.signed_url);
GET/webcast/check_alive

Check if one or more TikTok users are currently live streaming. Returns live status, room ID, stream title, and viewer count for each user.

Lookup methods: Pass unique_id (username) for single-user lookups, or room_ids (comma-separated) to check multiple rooms at once. At least one parameter is required.

Response data: Each entry includes room_id, alive (boolean), title, and userCount. Use this to build monitoring dashboards, trigger alerts when creators go live, or validate a stream before connecting via WebSocket.

Performance: This endpoint is lightweight and cached - ideal for polling. Combine with bulk_live_check for monitoring large lists of creators.

Parameters

NameTypeRequiredDescription
room_idsstringNoComma-separated room IDs
unique_idstringNoTikTok username (without @)

Response

response.json
{ "status_code": 0, "data": [{ "room_id": "...", "alive": true, "title": "...", "userCount": 1234 }] }
GET /webcast/check_alive - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/check_alive?apiKey=YOUR_KEY&unique_id=username');
const { data } = await res.json();
console.log(data[0].alive ? 'Live!' : 'Offline');
GET/webcast/rate_limits

Check your current API key's rate limit status, tier information, and remaining quota across all features.

What's returned: Your current tier (free/pro/ultra), API request limits (per-minute sliding window), WebSocket connection limits, bulk check capacity, and feed daily quota. Also includes reset_at timestamp for when limits refresh.

Use cases: Monitor quota consumption in production, display remaining capacity in dashboards, or implement client-side throttling to avoid hitting limits.

Headers: Every API response also includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers - but this endpoint gives a comprehensive overview of all your limits in one call.

Response

response.json
{ "status_code": 0, "data": { "tier": "basic", "api": { "limit": 30, "remaining": 28, "reset_at": 1234567890 }, "websocket": { "limit": 10, "current": 2 } } }
GET /webcast/rate_limits - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/rate_limits?apiKey=YOUR_KEY');
const { data } = await res.json();
console.log(`${data.api.remaining}/${data.api.limit} requests remaining`);
POST/webcast/fetch

Fetch live stream events via HTTP long-polling. Returns the same real-time data as WebSocket (chat, gifts, likes, battles) but over HTTP. Uses TikTok's binary protobuf protocol and returns decoded events.

How it works: The API signs and fetches TikTok's internal polling endpoint, decodes the protobuf response, and returns structured event data. Pass a cursor from the previous response for continuous polling.

Identification: Provide either unique_id (username) or room_id. If using unique_id, the server resolves the room ID automatically.

WebSocket vs Fetch: WebSocket connections are preferred for real-time use - they deliver events instantly with lower latency. Use /webcast/fetch when WebSocket is not possible (serverless environments, HTTP-only infrastructure) or for one-off data snapshots.

Parameters

NameTypeRequiredDescription
unique_idstringNoTikTok username
room_idstringNoRoom ID (alternative to unique_id)
cursorstringNoPagination cursor from previous response

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "alive": true, "message_count": 5, "raw_data": "base64...", "cursor": "" } }
POST /webcast/fetch - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/fetch?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_id: 'username' })
});
const { data } = await res.json();
console.log(`Messages: ${data.message_count}`);
POST/webcast/room_info

Get comprehensive information about a live stream room including the host's profile, stream title, viewer count, start time, and stream configuration.

Response data: Returns owner profile (nickname, uniqueId, profilePictureUrl, follower count), room metadata (title, user_count, like_count, create_time), stream URLs, cover images, and room status.

Identification: Provide either unique_id (username) or room_id. Returns an error if the user is not currently live.

Use cases: Pre-flight checks before WebSocket connection, building stream info cards/embeds, monitoring dashboards, or extracting the room ID for use with other endpoints like rankings or gift_info.

Parameters

NameTypeRequiredDescription
unique_idstringNoTikTok username
room_idstringNoRoom ID

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "alive": true, "title": "...", "user_count": 500, "owner": {...}, "like_count": 1234, "share_count": 56 } }
POST /webcast/room_info - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/room_info?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_id: 'username' })
});
const { data } = await res.json();
console.log(`${data.title} - ${data.user_count} viewers`);
POST/webcast/room_video

Get live stream video playback URLs in multiple formats and quality levels. Returns HLS (.m3u8), FLV, and direct origin URLs suitable for embedding or processing.

Stream formats: hls_pull_url for adaptive bitrate (best for web players), flv_pull_url for low-latency playback, and origin URLs for the highest quality source stream. Multiple resolutions are available (SD, HD, FULL_HD).

Use cases: Building custom live stream players, recording/archiving streams, feeding audio to transcription services (used internally by our Live Captions feature), or creating multi-stream monitoring walls.

Important: Stream URLs are time-limited and will expire. Re-fetch periodically if you need to maintain long-running playback. The hls format provides the most reliable playback across browsers and devices.

Parameters

NameTypeRequiredDescription
unique_idstringNoTikTok username
room_idstringNoRoom ID

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "alive": true, "stream_urls": { "origin": { "hls": "...", "flv": "..." }, "sd": {...} }, "default_quality": "origin" } }
POST /webcast/room_video - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/room_video?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_id: 'username' })
});
const { data } = await res.json();
const hlsUrl = data.stream_urls?.origin?.hls;
POST/webcast/bulk_live_check

Check live status for multiple TikTok users in a single request. Returns the same data as check_alive but for up to 100 users simultaneously.

Batch limits: Free: 1 user, Pro: up to 50 users, Ultra: up to 100 users per request. Pass usernames as a JSON array in the request body.

Response data: Returns an array with each user's unique_id, room_id, alive status, title, and userCount. Users who are offline return alive: false with an empty room_id.

Use cases: Creator monitoring dashboards that track dozens of streamers, automated alert systems, multi-stream aggregators, or periodically scanning talent rosters to detect who's live.

Parameters

NameTypeRequiredDescription
unique_idsstring[]YesArray of TikTok usernames

Response

response.json
{ "status_code": 0, "data": { "user1": true, "user2": false, "user3": true } }
POST /webcast/bulk_live_check - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/bulk_live_check?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_ids: ['user1', 'user2', 'user3'] })
});
const { data } = await res.json();
Object.entries(data).forEach(([user, live]) => console.log(`${user}: ${live}`));
POST/webcast/ws_credentials

Get pre-signed WebSocket connection credentials for establishing a direct connection to TikTok's live stream WebSocket servers. Returns everything needed to connect without using the managed proxy.

What's returned: A signed websocket_url (with X-Bogus), cookies (ttwid, session), user_agent, room_id, and cluster_region. Use these to create your own WebSocket connection directly to TikTok.

When to use: Advanced users building custom WebSocket clients who need direct TikTok connections (without using our managed proxy). Most users should use the managed WebSocket connection (wss://api.tik.tools) or the Node.js SDK instead.

Important: Direct connections count toward TikTok's per-IP WebSocket limit (~4 concurrent). If you need more, use our managed proxy which distributes connections across multiple IPs.

Parameters

NameTypeRequiredDescription
unique_idstringYesTikTok username

Response

response.json
{ "status_code": 0, "data": { "ws_url": "wss://...", "cookies": "ttwid=...", "room_id": "...", "ws_host": "...", "cluster_region": "US_TTP" } }
POST /webcast/ws_credentials - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/ws_credentials?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_id: 'username' })
});
const { data } = await res.json();
console.log('WS URL:', data.ws_url);
POST/webcast/sign_websocket

Sign a TikTok WebSocket URL with X-Bogus parameters for direct connection to TikTok's webcast-ws servers. This is the WebSocket-specific equivalent of sign_url.

How it works: Provide a room_id and the API generates a fully signed WebSocket URL targeting the correct regional TikTok WebSocket server (webcast-ws.tiktok.com, webcast-ws.us.tiktok.com, etc.).

Response: Returns signed_url (the complete wss:// URL), cookies, and user_agent. Connect using these credentials with the provided cookies in the WebSocket handshake headers.

Use case: Building custom WebSocket clients in languages without our SDK, or when you need fine-grained control over the WebSocket lifecycle. The SDK handles this internally - most users won't need this endpoint directly.

Parameters

NameTypeRequiredDescription
room_idstringYesTikTok room ID
cursorstringNoPagination cursor

Response

response.json
{ "status_code": 0, "data": { "signed_url": "wss://...", "x_bogus": "...", "x_gnarly": "...", "user_agent": "...", "cookies": "..." } }
POST /webcast/sign_websocket - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/sign_websocket?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ room_id: '7123456789' })
});
const { data } = await res.json();
// Connect with: new WebSocket(data.signed_url)
POST/webcast/resolve_user_ids

Resolve numeric TikTok user IDs to their corresponding usernames (unique_id/display_id). Accepts up to 20 user IDs per request with server-side caching for fast lookups.

When you need this: TikTok's internal APIs and WebSocket events often send numeric user IDs (like 6892636847263982593) instead of readable usernames. This endpoint converts them back to @username format.

Caching: Results are cached server-side for 24 hours. Repeated lookups for the same user IDs are instant and don't count toward rate limits.

Response data: Returns an array of { user_id, unique_id, nickname, avatar_url } objects. Users whose IDs can't be resolved (deleted accounts, banned users) are returned with unique_id: null.

Parameters

NameTypeRequiredDescription
user_idsstring[]YesArray of numeric user IDs (max 20)

Response

response.json
{ "status_code": 0, "data": { "123456": { "userId": "123456", "username": "john_doe", "cached": false } } }
POST /webcast/resolve_user_ids - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/resolve_user_ids?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ user_ids: ['107955', '6789012345'] })
});
const { data } = await res.json();
Object.values(data).forEach(u => console.log(`${u.userId} → @${u.username}`));
POST/authentication/jwt

Generate a JWT (JSON Web Token) for secure frontend WebSocket connections. JWTs allow your client-side code to connect without exposing your API key.

Security model: Generate JWTs server-side using your API key, then pass the jwtKey to your frontend. The JWT can be scoped to specific creators (allowed_creators) and limited to a set number of concurrent connections.

Expiry: Tokens expire after expire_after seconds (default: 3600 = 1 hour). After expiry, the client must request a new token from your backend.

Use cases: Web applications where the frontend connects directly to wss://api.tik.tools?uniqueId=USERNAME&jwtKey=TOKEN. This keeps your API key on the server while letting browsers connect to the WebSocket.

Parameters

NameTypeRequiredDescription
expire_afternumberNoSeconds until expiry (default: 3600)
allowed_creatorsstring[]NoRestrict to specific creators
max_websocketsnumberNoMax concurrent WS connections (default: 1)

Response

response.json
{ "status_code": 0, "data": { "token": "eyJ..." } }
POST /authentication/jwt - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/authentication/jwt?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ expire_after: 3600, allowed_creators: ['streamer1'] })
});
const { data } = await res.json();
// Use data.token for WebSocket: wss://api.tik.tools?jwtKey=TOKEN
GET/webcast/rankings

Get real-time leaderboard data for a live room - top gifters, online audience rankings, and engagement scores. Uses the "sign-and-return" pattern for authenticated data.

Data available: In-room top gifters (online_audience - ranked by diamonds sent this session), all-time gifter leaderboard (anchor_rank_list), and entrance configuration (ranking tabs, timer info, class/league badges).

Authentication: For full leaderboard data, include your TikTok session cookies via x-cookie-header. Without authentication, the endpoint returns limited ranking data.

Response pattern: Returns a signed_url that you fetch with session cookies to get TikTok's ranking data. Each rank entry includes user (nickname, avatar, follower count), score (diamonds), and rank position.

Parameters

NameTypeRequiredDescription
room_idstringNoTikTok room ID
unique_idstringNoTikTok username (alternative to room_id)

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "rankings": [...] } }
GET /webcast/rankings - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/rankings?unique_id=username&apiKey=YOUR_KEY');
const { data } = await res.json();
console.log(data.rankings);
POST/webcast/room_id

Resolve a TikTok username to their current live room ID. The server resolves the unique_id to a room_id on your behalf - no client-side page parsing needed.

How it works: The server checks its cache first (30-minute TTL). For Pro/Ultra/Admin tiers, resolution uses a residential proxy for reliable results. For other tiers, the server attempts direct resolution (may fail from datacenter IPs).

Freshness guarantee (Pro+): If a cached room ID is found but the user is no longer live on that room, the server automatically invalidates all cache layers and re-resolves via proxy. This ensures you always get the current room ID, even if a streamer went offline and started a new stream (which creates a new room ID). When this happens, the response includes stale_fix: true.

Response data: Returns unique_id, room_id, alive (whether the user is currently live), cached (whether the result came from server cache), and optionally stale_fix (if a stale cached room was detected and re-resolved). Use the returned room_id with other endpoints like sign_websocket, rankings, gift_info, etc.

Use cases: When you only have a username and need the room_id for other API calls. Many endpoints accept unique_id directly, but some (like sign_websocket) require the room ID. This endpoint eliminates the need for client-side TikTok page parsing. Safe to poll every 5-10 minutes - cached results are instant and re-resolution only triggers when needed.

Parameters

NameTypeRequiredDescription
unique_idstringYesTikTok username (without @)

Response

response.json
{ "status_code": 0, "data": { "unique_id": "username", "room_id": "7123456789", "alive": true, "cached": false, "stale_fix": false } }
POST /webcast/room_id - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/room_id?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ unique_id: 'username' })
});
const { data } = await res.json();
console.log(`Room ID: ${data.room_id}, Live: ${data.alive}`);
GET/webcast/room_cover

Get the high-quality cover image (thumbnail) URL of an active live stream. Returns the same image TikTok displays on the live feed before a user taps to watch.

Image quality: Returns the highest resolution available from TikTok's CDN. Cover images are typically 720x960 or higher, served as JPEG/WebP from TikTok's image CDN.

Use cases: Building live stream galleries, social media embeds, notification cards with stream previews, or monitoring dashboards that show stream thumbnails alongside viewer counts.

Note: Cover images are set by the streamer before going live. If no custom cover is set, TikTok uses a default or auto-generated thumbnail. Returns an error if the user is not currently live.

Parameters

NameTypeRequiredDescription
unique_idstringNoTikTok username
room_idstringNoTikTok room ID

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "cover_url": "https://..." } }
GET /webcast/room_cover - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/room_cover?unique_id=username&apiKey=YOUR_KEY');
const { data } = await res.json();
console.log(data.cover_url);
GET/webcast/hashtag_list

Get currently trending live stream hashtags from TikTok. Returns hashtag names, live viewer counts, and associated metadata.

Response data: Each hashtag includes id, title (the hashtag text), user_count (total viewers across all streams using this hashtag), and related metadata. Results are sorted by popularity.

Use cases: Discover trending topics for content strategy, build hashtag explorers, analyze live streaming trends over time, or filter the feed by popular hashtags.

Pagination: Use the count parameter to control results per page (default: 20, max: 50). The endpoint uses TikTok's internal trending algorithm, so results update frequently as trending topics shift.

Parameters

NameTypeRequiredDescription
countnumberNoNumber of results (default: 20, max: 50)

Response

response.json
{ "status_code": 0, "data": [{ "id": "...", "title": "#gaming", "user_count": 15000 }, ...] }
GET /webcast/hashtag_list - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/hashtag_list?count=10&apiKey=YOUR_KEY');
const { data } = await res.json();
data.forEach(tag => console.log(tag.title));
GET/webcast/gift_info

Get the complete list of gifts available in a live room, including gift names, diamond costs, animated thumbnails, and gift types. Uses the "sign-and-return" pattern.

Response data: Each gift entry includes id, name, diamond_count (cost in diamonds), icon (thumbnail URL), type (1=standard, 2=animated, etc.), and combo/repeat information.

Use cases: Build gift catalogs for your application, calculate the real-money value of gifts (1 diamond ≈ $0.005 USD), display gift icons in chat overlays, or track which gifts are available in different regions.

Note: Gift availability varies by region and room. Some gifts are event-exclusive or require specific room configurations. The response returns all currently available gifts for the specified room.

Parameters

NameTypeRequiredDescription
room_idstringNoTikTok room ID
unique_idstringNoTikTok username

Response

response.json
{ "status_code": 0, "data": { "room_id": "...", "gifts": [{ "id": 1, "name": "Rose", "diamond_count": 1 }, ...] } }
GET /webcast/gift_info - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/gift_info?unique_id=username&apiKey=YOUR_KEY');
const { data } = await res.json();
data.gifts.forEach(g => console.log(`${g.name}: ${g.diamond_count} diamonds`));
POST/webcast/chat

Send a chat message to an active TikTok live stream room on behalf of an authenticated user. Requires valid TikTok session cookies - the message is sent as the logged-in user.

Authentication required: You must include TikTok session cookies via the x-cookie-header header. Get your sessionid from browser DevTools → Application → Cookies → tiktok.com.

How it works: The API signs the chat request with X-Bogus, attaches your session cookies, and sends the message to TikTok's chat endpoint. The message appears in the live room as if you typed it in the TikTok app.

Rate limiting: TikTok enforces internal chat rate limits (~1 message per 2 seconds). Sending too fast may result in temporary chat mutes. The API returns status_code: 0 on success.

Parameters

NameTypeRequiredDescription
room_idstringYesTarget room ID
textstringYesChat message text

Response

response.json
{ "status_code": 0, "data": { "status_code": 0 } }
POST /webcast/chat - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/chat?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES'
  },
  body: JSON.stringify({ room_id: '7123456789', text: 'Hello!' })
});
console.log(await res.json());
GET/webcast/user_earnings

Retrieve TikTok LIVE earnings data for a creator including diamonds received, coin equivalent, and period breakdowns. This is an authenticated endpoint that proxies TikTok's creator earnings API.

Authentication required: You must include TikTok session cookies via x-cookie-header. Only works when the session belongs to the creator whose earnings are being requested (you can't view other people's earnings).

Response data: Returns diamonds (total received), coins (equivalent coin value), and period breakdown. Diamond-to-USD conversion: 1 diamond ≈ $0.005 USD.

Use cases: Creator dashboards showing real-time earnings, financial analytics for agency talent management, or automated earnings reports for multi-stream operations.

Parameters

NameTypeRequiredDescription
unique_idstringYesTikTok username
periodstringNoPeriod filter: "daily" (default)

Response

response.json
{ "status_code": 0, "data": { "diamonds": 1500, "coins": 75000, "period": "daily" } }
GET /webcast/user_earnings - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/user_earnings?unique_id=creator&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
const { data } = await res.json();
console.log(`Diamonds: ${data.diamonds}`);
GET/webcast/feedBasic+

Discover currently live TikTok LIVE streams. Uses a two-step "sign-and-return" pattern - the API returns a signed URL with headers and cookies that you fetch from YOUR own IP to get the actual TikTok feed data.

Authentication: Include your TikTok session_id cookie for personalized, populated results. Without it, results are anonymous and limited (~5 rooms).

Channels: 87 = Recommended - the main "For You" infinite scroll feed, 86 = Suggested - sidebar host recommendations (shown while watching), 89 or 1111006 = Gaming, 42 = Following (requires session).

Geo-targeting: Feed results are determined by the IP address making the final TikTok fetch (Step 2), NOT by the region parameter. Since you fetch the signed URL from your own client, you'll see content relevant to your geographic location. The region param is passed to TikTok but has minimal effect on results.

Pagination: The API automatically switches to TikTok's "load more" mode when you pass a max_time cursor. Fetch the signed URL → parse the TikTok JSON response → extract data.extra.max_time → pass it as max_time in your next call. Each page returns ~6-15 rooms; keep paginating for continuous discovery. The response also includes a load_more_url template - just replace {MAX_TIME} with the cursor.

Rate limits: Pro: 100 calls/day. Ultra: 2,000 calls/day. Response includes feed_remaining and feed_limit fields.

Response data: Each room includes owner.display_id (username), owner.nickname (display name), title, user_count (viewers), owner.avatar_thumb (profile photo), id_str (room ID), and more.

Parameters

NameTypeRequiredDescription
session_idstringNoYour TikTok sessionid cookie - strongly recommended. Get from browser DevTools → Application → Cookies → tiktok.com. Without it, results are sparse.
channel_idstringNoFeed channel: 87 = Recommended "For You" (default), 86 = Suggested sidebar, 89 or 1111006 = Gaming, 42 = Following
countnumberNoRooms per page (default: 20, max: 50)
max_timestringNoPagination cursor from previous TikTok response (data.extra.max_time). Omit or "0" for first page.
regionstringNoHint passed to TikTok (default: US). Note: actual results are geo-targeted by the IP making the final fetch, not this param.
ttwidstringNoTikTok ttwid visitor cookie. Server provides one if omitted.
ms_tokenstringNoTikTok msToken cookie (optional, a placeholder is used if omitted).

Response

response.json
{
  "status_code": 0,
  "signed_url": "https://webcast.tiktok.com/webcast/feed/?...",
  "method": "GET",
  "headers": { "User-Agent": "...", "Referer": "https://www.tiktok.com/", ... },
  "cookies": "ttwid=...; sessionid=...; sessionid_ss=...",
  "region": "US",
  "channel_id": "87",
  "feed_remaining": 99,
  "feed_limit": 100,
  "note": "Fetch signed_url from your client/IP with these headers and cookies."
}

// After fetching signed_url, TikTok returns:
{
  "status_code": 0,
  "data": [{
    "data": {
      "id_str": "7123456789",
      "title": "🔴 Live Now!",
      "user_count": 1250,
      "owner": {
        "display_id": "streamer_name",
        "nickname": "Display Name",
        "avatar_thumb": { "url_list": ["https://..."] }
      }
    }
  }, ...],
  "extra": { "max_time": "1773128824428" }
}
GET /webcast/feed - Node.js
Node.js
Python
cURL
Java
Go
C#
// Step 1: Get signed URL with session for populated results
const res = await fetch(
  'https://api.tik.tools/webcast/feed?' + new URLSearchParams({
    apiKey: 'YOUR_KEY',
    session_id: 'YOUR_TIKTOK_SESSION_ID',  // from browser cookies
    region: 'US',
    channel_id: '87',  // 87=recommended, 86=suggested, 1111006=gaming
    count: '20',
  })
);
const { signed_url, headers, cookies, feed_remaining, feed_limit } = await res.json();
console.log(`Quota: ${feed_remaining}/${feed_limit} calls remaining`);

// Step 2: Fetch TikTok data from YOUR IP
const tikRes = await fetch(signed_url, {
  headers: { ...headers, Cookie: cookies }
});
const feed = await tikRes.json();

// Step 3: Parse live rooms
for (const entry of feed.data) {
  const room = entry.data;
  console.log(`🔴 @${room.owner.display_id} (${room.owner.nickname})`);
  console.log(`   "${room.title}" - ${room.user_count} viewers`);
}

// Step 4: Load more (pagination)
const nextCursor = feed.extra?.max_time;
if (nextCursor) {
  const page2 = await fetch(
    'https://api.tik.tools/webcast/feed?' + new URLSearchParams({
      apiKey: 'YOUR_KEY', session_id: 'YOUR_SESSION_ID',
      region: 'US', max_time: nextCursor, count: '20',
    })
  );
  // ... repeat Step 2-3
}
GET/webcast/live_analytics/video_list

List historical live stream recordings for a TikTok account. Returns past streams with metadata including title, duration, viewer count, and stream date. Requires authenticated TikTok session cookies.

Authentication required: Include session cookies via x-cookie-header. Only accessible for the account that owns the session - you cannot view another creator's video history.

Response data: Each entry includes video_id (stream identifier), title, duration (seconds), viewer_count (peak viewers), create_time (start timestamp), and engagement metrics.

Use cases: Building creator analytics dashboards, tracking streaming performance over time, generating stream history reports, or identifying a specific video_id for use with the video_detail endpoint.

Parameters

NameTypeRequiredDescription
unique_idstringYesTikTok username
countnumberNoNumber of results (default: 20)

Response

response.json
{ "status_code": 0, "data": [{ "video_id": "...", "title": "...", "duration": 3600, "viewer_count": 1200 }, ...] }
GET /webcast/live_analytics/video_list - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/live_analytics/video_list?unique_id=creator&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
const { data } = await res.json();
data.forEach(v => console.log(`${v.title}: ${v.viewer_count} viewers`));
GET/webcast/live_analytics/video_detail

Get granular analytics for a specific past live stream session. Returns detailed performance metrics including total views, peak concurrent viewers, gifts received, new followers gained, and engagement rates. Requires authenticated TikTok session cookies.

Authentication required: Include session cookies via x-cookie-header. Access is restricted to the account's own streams.

Response data: Includes views (total), duration (seconds), peak_viewers, gifts (total diamond value), new_followers, likes, comments, and period-specific breakdowns. The video_id comes from the video_list endpoint.

Use cases: Post-stream analytics reports, A/B testing different stream formats, tracking creator growth metrics, or building agency reporting dashboards that aggregate performance across multiple creators.

Parameters

NameTypeRequiredDescription
video_idstringYesVideo/stream ID

Response

response.json
{ "status_code": 0, "data": { "video_id": "...", "duration": 3600, "views": 12000, "gifts": 350, "peak_viewers": 800 } }
GET /webcast/live_analytics/video_detail - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/live_analytics/video_detail?video_id=VID123&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
const { data } = await res.json();
console.log(`Duration: ${data.duration}s, Peak: ${data.peak_viewers}`);
GET/webcast/live_analytics/user_interactions

Get the real-time online audience roster for a live room, ranked by gift score (diamonds sent during this session). Returns each viewer's rank, score, and full profile. Requires authenticated TikTok session cookies.

How it works: Uses the "sign-and-return" pattern. The API returns a signed_url that you fetch with your session cookies to get TikTok's audience data. The anchor_id (host's user ID) is auto-resolved from the room_id.

Response data: Each entry includes rank (1-based position), score (diamonds sent this session), and user profile with nickname, display_id, id_str, avatar_thumb, and follow_info (follower/following counts).

Use cases: Identifying top supporters in real-time, building live leaderboard overlays, tracking viewer engagement and spending patterns, or providing viewer analytics for agency clients.

Parameters

NameTypeRequiredDescription
room_idstringYesRoom ID of the stream
user_idstringNoFilter to specific user ID
countnumberNoNumber of results (default: 50)

Response

response.json
{ "status_code": 0, "signed_url": "https://...", "anchor_id": "...", "note": "Fetch signed_url with your session cookies" }

// After fetching signed_url with session cookies, TikTok returns:
{ "data": { "ranks": [{ "rank": 1, "score": 192, "user": { "nickname": "...", "display_id": "...", "id_str": "..." } }], "total": 49 } }
GET /webcast/live_analytics/user_interactions - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://api.tik.tools/webcast/live_analytics/user_interactions?room_id=7123456789&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
const { signed_url, headers, anchor_id } = await res.json();

// Fetch from your IP with your session
const tikRes = await fetch(signed_url, {
  headers: { ...headers, Cookie: `sessionid=YOUR_SESSIONID; ${headers.Cookie || ''}` }
});
const { data } = await tikRes.json();
data.ranks.forEach(r => console.log(`#${r.rank} ${r.user.nickname}: ${r.score} pts`));
GET/webcast/moderation/mutes

Manage muted users in a live room. GET to list, PUT to mute, DELETE to unmute. Requires TikTok session.

Parameters

NameTypeRequiredDescription
room_idstringYesTarget room ID
user_idstringNoUser ID to mute/unmute (PUT/DELETE)
durationnumberNoMute duration in seconds (PUT, 0 = permanent)

Response

response.json
{ "status_code": 0, "data": { "muted_users": [{ "user_id": "...", "duration": 300 }] } }
GET /webcast/moderation/mutes - Node.js
Node.js
Python
cURL
Java
Go
C#
// List muted users
const res = await fetch('https://api.tik.tools/webcast/moderation/mutes?room_id=7123456789&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
console.log(await res.json());
GET/webcast/moderation/bans

Manage banned users in a live room. GET to list, PUT to ban, DELETE to unban. Requires TikTok session.

Parameters

NameTypeRequiredDescription
room_idstringYesTarget room ID
user_idstringNoUser ID to ban/unban (PUT/DELETE)

Response

response.json
{ "status_code": 0, "data": { "banned_users": [{ "user_id": "...", "username": "..." }] } }
GET /webcast/moderation/bans - Node.js
Node.js
Python
cURL
Java
Go
C#
// List banned users
const res = await fetch('https://api.tik.tools/webcast/moderation/bans?room_id=7123456789&apiKey=YOUR_KEY', {
  headers: { 'x-cookie-header': 'sessionid=YOUR_TIKTOK_COOKIES' }
});
console.log(await res.json());
GET/api/live/connect

Bundled endpoint - fetches both a scoped JWT token and stream video URLs in a single request. Ideal for frontend apps that need to open a WebSocket and play video simultaneously. Rate limited to 10 req/min.

Parameters

NameTypeRequiredDescription
uniqueIdstringYesTikTok username (without @)

Response

response.json
{ "token": "eyJ...", "wsUrl": "wss://api.tik.tools", "uniqueId": "streamer", "stream": { "room_id": "...", "alive": true, "stream_urls": { "origin": { "hls": "...", "flv": "..." } }, "default_quality": "origin" } }
GET /api/live/connect - Node.js
Node.js
Python
cURL
Java
Go
C#
const res = await fetch('https://tik.tools/api/live/connect?uniqueId=username');
const data = await res.json();
// data.token - short-lived JWT for WebSocket auth
// data.wsUrl  - WebSocket server URL
// data.stream - video URLs (HLS/FLV)
const ws = new WebSocket(`${data.wsUrl}?uniqueId=username&jwtKey=${data.token}`);
POST/captcha/solve/puzzleBasic+

Solve a TikTok puzzle (slider) CAPTCHA. Send base64-encoded background and piece images. Returns the slide X position.

Parameters

NameTypeRequiredDescription
puzzlestringYesBase64-encoded background image (PNG/JPEG)
piecestringYesBase64-encoded puzzle piece image (PNG/JPEG)

Response

response.json
{ "status_code": 0, "data": { "slide_x_proportion": 0.42, "slide_x_px": 168, "confidence": 0.95, "solve_time_ms": 12 } }
POST /captcha/solve/puzzle - Node.js
Node.js
Python
cURL
Java
Go
C#
const fs = require('fs');
const bg = fs.readFileSync('captcha-bg.png').toString('base64');
const piece = fs.readFileSync('captcha-piece.png').toString('base64');
const res = await fetch('https://api.tik.tools/captcha/solve/puzzle?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ puzzle: bg, piece })
});
const { data } = await res.json();
console.log(`Slide to X=${data.slide_x_px}px`);
POST/captcha/solve/rotateBasic+

Solve a TikTok rotate (whirl) CAPTCHA. Send base64-encoded outer ring and inner images. Returns the rotation angle.

Parameters

NameTypeRequiredDescription
outerstringYesBase64-encoded outer ring image (PNG/JPEG)
innerstringYesBase64-encoded inner rotated image (PNG/JPEG)

Response

response.json
{ "status_code": 0, "data": { "angle": 127, "confidence": 0.82, "solve_time_ms": 45 } }
POST /captcha/solve/rotate - Node.js
Node.js
Python
cURL
Java
Go
C#
const fs = require('fs');
const outer = fs.readFileSync('outer.png').toString('base64');
const inner = fs.readFileSync('inner.png').toString('base64');
const res = await fetch('https://api.tik.tools/captcha/solve/rotate?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ outer, inner })
});
const { data } = await res.json();
console.log(`Rotate ${data.angle}°`);
POST/captcha/solve/shapesBasic+

Solve a TikTok shapes (3D matching) CAPTCHA. Send a base64-encoded image with a grid of shapes. Returns the two matching shape coordinates.

Parameters

NameTypeRequiredDescription
imagestringYesBase64-encoded CAPTCHA image with shape grid (PNG/JPEG)

Response

response.json
{ "status_code": 0, "data": { "point1": { "x": 85, "y": 120 }, "point2": { "x": 245, "y": 120 }, "confidence": 0.78, "solve_time_ms": 30 } }
POST /captcha/solve/shapes - Node.js
Node.js
Python
cURL
Java
Go
C#
const fs = require('fs');
const image = fs.readFileSync('shapes.png').toString('base64');
const res = await fetch('https://api.tik.tools/captcha/solve/shapes?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ image })
});
const { data } = await res.json();
console.log(`Match: (${data.point1.x},${data.point1.y}) ↔ (${data.point2.x},${data.point2.y})`);
POST/webcast/ranklist/regionalBasic+

Get regional LIVE leaderboard rankings - daily, hourly, popular, or league. Returns a signed URL that the client fetches with their own TikTok session cookie. Requires Pro or Ultra tier.

Parameters

NameTypeRequiredDescription
unique_idstringNoTikTok username (auto-resolves room_id and anchor_id)
room_idstringNoRoom ID (alternative to unique_id)
anchor_idstringNoAnchor/owner user ID. Auto-resolved if unique_id is used.
rank_typestringNoRanking period: "1" = Hourly, "8" = Daily (default), "15" = Popular LIVE, "16" = League
typestringNo"list" (default) for rankings, "entrance" for available tabs
gap_intervalstringNoGap interval filter (default: "0")

Response

response.json
{
  "status_code": 0,
  "action": "fetch_signed_url",
  "signed_url": "https://webcast.tiktok.com/webcast/ranklist/list/v2/?...",
  "method": "POST",
  "headers": { "User-Agent": "...", "Content-Type": "application/x-www-form-urlencoded" },
  "body": "room_id=123&rank_type=8&anchor_id=456&gap_interval=0",
  "cookies": "ttwid=...",
  "note": "POST this URL with your sessionid cookie from your browser/IP."
}
POST /webcast/ranklist/regional - Node.js
Node.js
Python
cURL
Java
Go
C#
// Step 1: Get signed URL from the API
const res = await fetch('https://api.tik.tools/webcast/ranklist/regional?apiKey=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    room_id: '7607695933891218198',
    anchor_id: '7444599004337652758',
    rank_type: '8'  // Daily
  })
});
const signData = await res.json();

// Step 2: Fetch from YOUR IP with YOUR session cookie
const tikResp = await fetch(signData.signed_url, {
  method: signData.method,
  headers: { ...signData.headers, Cookie: `sessionid=YOUR_SESSIONID; ${signData.cookies}` },
  body: signData.body
});
const { data } = await tikResp.json();
data.rank_view.ranks.forEach((r, i) =>
  console.log(`${i+1}. ${r.user.nickname} - ${r.score} pts`)
);

WebSocket Events

All event types sent over the WebSocket connection.

chatA viewer sent a chat message.

Fields

NameTypeDescription
userWebcastUserThe user who sent the message
commentstringThe chat message text
starredobject | undefinedPresent only for starred (paid highlighted) messages. Contains { claps: number, score: number }

Example Payload

chat.json
{ "event": "chat", "data": { "type": "chat", "user": { "id": "123", "nickname": "John", "uniqueId": "john123" }, "comment": "Hello!", "starred": { "claps": 3, "score": 1200 } } }
likeA viewer liked the stream.

Fields

NameTypeDescription
userWebcastUserThe user who liked
likeCountnumberNumber of likes in this event
totalLikesnumberTotal likes on the stream

Example Payload

like.json
{ "event": "like", "data": { "type": "like", "user": { "id": "123", "uniqueId": "fan99" }, "likeCount": 15, "totalLikes": 4200 } }
giftA viewer sent a virtual gift.

Fields

NameTypeDescription
userWebcastUserThe gifter
giftIdnumberGift identifier
giftNamestringDisplay name of the gift
repeatCountnumberNumber of gifts in combo
diamondCountnumberDiamond value per gift
repeatEndbooleanWhether the gift combo has ended

Example Payload

gift.json
{ "event": "gift", "data": { "type": "gift", "user": { "uniqueId": "generous" }, "giftName": "Rose", "repeatCount": 5, "diamondCount": 1, "repeatEnd": true } }
memberA viewer joined the live stream.

Fields

NameTypeDescription
userWebcastUserThe user who joined
actionstringJoin action type

Example Payload

member.json
{ "event": "member", "data": { "type": "member", "user": { "uniqueId": "viewer1" }, "action": "join" } }
socialA social action occurred (follow, share).

Fields

NameTypeDescription
userWebcastUserThe user
actionstringSocial action (follow, share)

Example Payload

social.json
{ "event": "social", "data": { "type": "social", "user": { "uniqueId": "newfan" }, "action": "follow" } }
roomUserSeqPeriodic viewer count update.

Fields

NameTypeDescription
totalViewersnumberTotal unique viewers
viewerCountnumberCurrent concurrent viewers

Example Payload

roomUserSeq.json
{ "event": "roomUserSeq", "data": { "type": "roomUserSeq", "totalViewers": 15000, "viewerCount": 342 } }
subscribeA viewer subscribed to the streamer.

Fields

NameTypeDescription
userWebcastUserThe subscriber
subMonthnumberSubscription month count

Example Payload

subscribe.json
{ "event": "subscribe", "data": { "type": "subscribe", "user": { "uniqueId": "subscriber1" }, "subMonth": 3 } }
emoteChatA viewer sent an emote in chat.

Fields

NameTypeDescription
userWebcastUserThe user
emoteIdstringEmote identifier
emoteUrlstringURL of the emote image

Example Payload

emoteChat.json
{ "event": "emoteChat", "data": { "type": "emoteChat", "user": { "uniqueId": "emojifan" }, "emoteId": "123", "emoteUrl": "https://..." } }
battleLive battle status update between streamers.

Fields

NameTypeDescription
battleIdstringBattle identifier
statusnumberBattle status code
battleDurationnumberDuration in seconds
teamsBattleTeam[]Array of competing teams

Example Payload

battle.json
{ "event": "battle", "data": { "type": "battle", "battleId": "456", "status": 1, "teams": [{ "hostUserId": "1", "score": 100 }] } }
questionA viewer asked a Q&A question.

Fields

NameTypeDescription
userWebcastUserThe user who asked
questionTextstringThe question text

Example Payload

question.json
{ "event": "question", "data": { "type": "question", "user": { "uniqueId": "curious" }, "questionText": "What game is this?" } }
controlStream control event (e.g. stream ended).

Fields

NameTypeDescription
actionnumberControl action code (3 = stream ended)

Example Payload

control.json
{ "event": "control", "data": { "type": "control", "action": 3 } }
envelopeTreasure box / envelope event.

Fields

NameTypeDescription
envelopeIdstringEnvelope identifier
diamondCountnumberDiamond value

Example Payload

envelope.json
{ "event": "envelope", "data": { "type": "envelope", "envelopeId": "789", "diamondCount": 50 } }
roomPinA chat message was pinned/starred by the host or a moderator.

Fields

NameTypeDescription
userWebcastUserThe user who wrote the pinned message
commentstringThe pinned comment text
actionnumberPin action: 1 = pin, 2 = unpin
durationSecondsnumberHow long the pin lasts (e.g. 60)
pinnedAtnumberTimestamp when pinned (ms)
originalMsgTypestringOriginal message type (e.g. "WebcastChatMessage")
originalMsgIdstringID of the original chat message
operatorUserIdstringUser ID of who pinned the message

Example Payload

roomPin.json
{ "event": "roomPin", "data": { "type": "roomPin", "user": { "uniqueId": "viewer1", "nickname": "Viewer" }, "comment": "Great stream!", "action": 1, "durationSeconds": 60, "pinnedAt": 1773564373063, "originalMsgType": "WebcastChatMessage", "originalMsgId": "7617400904630995734", "operatorUserId": "7444599004337652758" } }

Rate Limits

Rate limits are applied per API key on a 1-minute sliding window.

TierAPI Req/minWS ConnsWS DurationWS ConnectsBulk Check
Sandbox515 min5/day1
Basic6038 hours150/day10
ProUnlimited508 hoursUnlimited50
Ultra3005008 hoursUnlimited500

Rate limit headers are included in every response:

Headers
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1234567890

⚠️ WebSocket Connection Limit - 4 per IP

TikTok enforces a limit of approximately 4 concurrent WebSocket connections per IP address. Exceeding this may result in rate limiting or temporary IP bans by TikTok's infrastructure.

For Pro and Ultra users building multi-stream applications (monitoring 5+ streams simultaneously): ensure each client connects from their own IP address, or use proxy rotation to distribute connections across multiple IPs. Our API allows up to {50/500} connections per API key, but the connections should be spread across different source IPs.

WebSocket Close Codes

Custom close codes used when the WebSocket connection is terminated.

CodeNameDescription
1000NORMALNormal closure
4005STREAM_ENDThe live stream ended
4006NO_MESSAGES_TIMEOUTNo messages received for 60 seconds
4400INVALID_OPTIONSMissing or invalid connection parameters
4401INVALID_AUTHInvalid API key or JWT
4403NO_PERMISSIONJWT does not allow access to this creator
4404NOT_LIVEThe user is not currently live
4429TOO_MANY_CONNECTIONSExceeded WebSocket connection limit
4500TIKTOK_CLOSEDUpstream TikTok connection closed
4555MAX_LIFETIMEConnection exceeded 8-hour max lifetime
4556WEBCAST_FETCH_ERRORFailed to fetch webcast data

Live Captions

Real-time speech-to-text transcription for TikTok LIVE streams. AI-powered with speaker diarization, multi-language support, and sub-second latency.

WebSocketMulti-LanguageSpeaker DiarizationTranslation

Connection

WebSocket URL
wss://api.tik.tools/captions?uniqueId=USERNAME&apiKey=YOUR_KEY&language=en&translate=en&diarization=true&max_duration_minutes=60

Query Parameters

NameTypeRequiredDescription
uniqueIdstringYesTikTok username to caption
apiKeystringYesYour API key
languagestringNoSource language hint (empty = auto-detect)
translatestringNoTarget translation language code. Only ONE language per session (multi-translate rejected)
diarizationbooleanNoEnable speaker identification (default: true)
max_duration_minutesnumberNoAuto-disconnect after N minutes (default: 60, max: 300). Forces reconnect to prevent runaway sessions.

Events

TypeFieldsDescription
captiontext, speaker, isFinal, languageReal-time caption text (partial and final)
translationtext, speaker, targetLanguageTranslated caption text
statusstatus, messageSession status updates (connecting, transcribing, ended)
creditstotal, used, remainingCredit balance update (sent every 30s)
credits_lowremaining, percentageLow credit warning (≤20% remaining)
errorcode, messageError event

Example Payload

caption event
{ "type": "caption", "text": "Hello everyone, welcome to my stream!", "speaker": "Speaker 1", "isFinal": true, "language": "en" }

Code Examples

Live Captions - Node.js
Node.js
Python
cURL
import WebSocket from 'ws';

const ws = new WebSocket(
  'wss://api.tik.tools/captions?uniqueId=streamer&apiKey=YOUR_KEY&translate=en&max_duration_minutes=120'
);

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  switch (msg.type) {
    case 'caption':
      const prefix = msg.speaker ? `[${msg.speaker}] ` : '';
      console.log(`${prefix}${msg.text}${msg.isFinal ? ' ✓' : '...'}`);
      break;
    case 'translation':
      console.log(`  → ${msg.text}`);
      break;
    case 'credits':
      console.log(`Credits: ${msg.remaining}/${msg.total} min remaining`);
      break;
    case 'status':
      console.log(`Status: ${msg.status}`);
      break;
  }
});

SDK Usage

SDK - Node.js
import { TikTokCaptions } from '@tiktool/live';

const captions = new TikTokCaptions({
  apiKey: process.env.TIKTOOL_API_KEY,
  uniqueId: 'streamer_name',
  translate: 'en',
  diarization: true,
});

captions.on('caption', (event) => {
  console.log(`[${event.speaker}] ${event.text}`);
});

captions.on('translation', (event) => {
  console.log(`  → ${event.text}`);
});

captions.on('credits', (event) => {
  console.log(`${event.remaining}/${event.total} min remaining`);
});

captions.on('credits_low', (event) => {
  console.warn(`Low credits! ${event.remaining} min left`);
});

await captions.start();
// captions.stop() to end

Pricing - Credit Top-Ups

1 Credit = 1 minute of audio transcribed/translated into ONE language. Translation to a second language requires a separate session and burns separate credits.

PackageCreditsPricePer Credit
Starter1,000$10$0.010
Creator ⭐5,000$35$0.007
Agency20,000$100$0.005
Pay-as-you-go add-ons

Caption credits are pay-as-you-go add-ons: Starter (1,000 credits / $10), Creator (5,000 credits / $35), Agency (20,000 credits / $100). Requires Basic tier or higher.

🎤
Try it live

See captions in action on a real TikTok LIVE stream at tik.tools/captions

Unreal Engine Plugin

Native Unreal Engine plugin with full Blueprint and C++ support. Access TikTok LIVE data directly inside your UE project - no HTTP calls, no external processes.

UE 5.4+Blueprint ReadyC++ API15+ Events

Installation

Project Structure
YourProject/
├── Plugins/
│   └── TikToolLive/
│       ├── TikToolLive.uplugin
│       └── Source/
│           └── TikToolLive/
│               ├── Public/
│               │   ├── TikToolLiveSubsystem.h
│               │   ├── TikToolSettings.h
│               │   └── TikToolTypes.h
│               └── Private/
│                   └── TikToolLiveSubsystem.cpp
  1. Copy the TikToolLive folder into your project's Plugins/ directory
  2. Regenerate project files (right-click .uproject → Generate Visual Studio project files)
  3. Open the editor → Edit → Plugins → verify TikToolLive is enabled

Project Settings

Configure via Edit → Project Settings → Plugins → TikTool Live:

SettingTypeDefaultDescription
ApiKeyFString""Your TikTool API key
DefaultUniqueIdFString""TikTok username (without @)
bAutoConnectboolfalseConnect automatically on game start
bAutoReconnectbooltrueReconnect on disconnection
MaxReconnectAttemptsint325Max reconnect retries
HeartbeatIntervalfloat30.0Seconds between heartbeats
bDebugLoggingboolfalseEnable verbose log output

Blueprint Quick Start

Zero C++ required. Three steps to receive live events in any Blueprint:

  1. Search for "Get TikTool Live Subsystem" from any Blueprint node graph
  2. Call Connect (or enable Auto Connect in Project Settings)
  3. Bind to events: drag from the subsystem → Assign OnChatEvent, Assign OnGiftEvent, etc.

Connection API

FunctionReturnsDescription
Connect(UniqueId)voidConnect to a TikTok LIVE stream. Uses DefaultUniqueId if empty.
Disconnect()voidClose the WebSocket connection
IsConnected()boolCheck if currently connected
GetRoomId()FStringGet the current room ID
GetViewerCount()int32Current concurrent viewer count
GetEventCount()int32Total events received this session

Events

All events are BlueprintAssignable multicast delegates. Bind in Blueprint (Assign node) or C++ (AddDynamic):

DelegatePayloadDescription
OnChatEventFTikToolChatEventChat message received
OnGiftEventFTikToolGiftEventGift sent by viewer
OnLikeEventFTikToolLikeEventLikes received
OnMemberEventFTikToolMemberEventViewer joined stream
OnFollowEventFTikToolFollowEventNew follower
OnShareEventFTikToolShareEventStream shared
OnSubscribeEventFTikToolSubscribeEventSubscription
OnViewerCountUpdateFTikToolViewerEventViewer count changed
OnBattleUpdateFTikToolBattleEventBattle status update
OnEmoteChatEventFTikToolEmoteChatEventEmote in chat
OnQuestionEventFTikToolQuestionEventQ&A question
OnEnvelopeEventFTikToolEnvelopeEventTreasure box / envelope
OnStreamEnd-Stream ended
OnConnected-Successfully connected
OnDisconnected-Connection lost

C++ Example

MyChatActor.cpp - C++
#include "TikToolLiveSubsystem.h"

void AMyChatActor::BeginPlay()
{
    Super::BeginPlay();
    auto* TikTool = GetGameInstance()->GetSubsystem<UTikToolLiveSubsystem>();
    if (!TikTool) return;

    // Bind to chat events
    TikTool->OnChatEvent.AddDynamic(this, &AMyChatActor::HandleChat);
    TikTool->OnGiftEvent.AddDynamic(this, &AMyChatActor::HandleGift);

    // Connect (uses DefaultUniqueId from Project Settings)
    TikTool->Connect();
}

void AMyChatActor::HandleChat(const FTikToolChatEvent& Event)
{
    UE_LOG(LogTemp, Log, TEXT("%s: %s"),
        *Event.User.Nickname, *Event.Comment);
}

void AMyChatActor::HandleGift(const FTikToolGiftEvent& Event)
{
    UE_LOG(LogTemp, Log, TEXT("%s sent %s x%d"),
        *Event.User.Nickname, *Event.GiftName, Event.RepeatCount);
}