Agency rank feeds in Discord: gaming ranks, creator ranks and 99+ movers across all 30 regions, copy-paste usernames for backstage. Run /ranks to start (Agency).
tiktok-live-api is the most complete, production-managed TikTok LIVE API for Node.js and TypeScript. Connect to any TikTok LIVE stream over a single WebSocket and receive real-time chat messages, gifts, likes, follows, viewer counts, shares and battle events, with an Unreal Engine plugin and SDKs in multiple languages. Managed signing works out of the box: no third-party sign server, no keys to configure. Powered by the TikTool managed API.
Docs and dashboard: tik.tools | Python SDK: tik.tools/guides/python-tiktok-live | WebSocket API: tik.tools/websocket
This package is not affiliated with or endorsed by TikTok. It connects to the TikTool Live managed API service - 99.9% uptime, no reverse engineering, no maintenance required. Also available for Python and any language via WebSocket.
The premium managed alternative for TikTok LIVE data. What you get out of the box:
- Managed signing infrastructure. Signing runs on our servers and works immediately - no third-party sign server to run, no separate key to configure.
- Unreal Engine plugin. Drive avatars, overlays and gameplay directly from live chat, gifts and battles.
- Agency and leaderboard intelligence. Gifter leaderboards, gaming and creator ranks across regions, and eligible-creator discovery.
- Multi-language SDKs. First-class Node.js and Python clients plus a plain WebSocket API for any language.
- Free 7-day Sandbox evaluation. Try the API free for 7 days from account creation, then pick a paid plan at tik.tools/pricing.
npm install tiktok-live-api# or with yarn / pnpm / bun
yarn add tiktok-live-api
pnpm add tiktok-live-api
bun add tiktok-live-apiimport { TikTokLive } from 'tiktok-live-api';
const client = new TikTokLive('streamer_username', { apiKey: 'YOUR_API_KEY' });
client.on('chat', (event) => {
console.log(`${event.user.uniqueId}: ${event.comment}`);
});
client.on('gift', (event) => {
console.log(`${event.user.uniqueId} sent ${event.giftName} (${event.diamondCount} 💎)`);
});
client.on('like', (event) => {
console.log(`${event.user.uniqueId} liked (total: ${event.totalLikes})`);
});
client.on('follow', (event) => {
console.log(`${event.user.uniqueId} followed!`);
});
client.on('roomUserSeq', (event) => {
console.log(`${event.viewerCount} viewers watching`);
});
client.connect();That's it. No complex setup, no protobuf, no reverse engineering, no breakages when TikTok updates.
Copy-paste this into a file and run it. Connects to a live TikTok stream and prints every event in real time. Works during the free 7-day Sandbox evaluation - 2 hours per WebSocket connection.
Save as demo.mjs and run with node demo.mjs:
// demo.mjs - TikTok LIVE in real time
// npm install tiktok-live-api
import { TikTokLive } from 'tiktok-live-api';
const API_KEY = 'YOUR_API_KEY'; // Get an API key - https://tik.tools/pricing
const LIVE_USERNAME = 'tv_asahi_news'; // Any live TikTok username
const client = new TikTokLive(LIVE_USERNAME, { apiKey: API_KEY });
let events = 0;
client.on('chat', e => { events++; console.log(`💬 ${e.user.uniqueId}: ${e.comment}`); });
client.on('gift', e => { events++; console.log(`🎁 ${e.user.uniqueId} sent ${e.giftName} (${e.diamondCount}💎)`); });
client.on('like', e => { events++; console.log(`❤️ ${e.user.uniqueId} liked × ${e.likeCount}`); });
client.on('member', e => { events++; console.log(`👋 ${e.user.uniqueId} joined`); });
client.on('follow', e => { events++; console.log(`➕ ${e.user.uniqueId} followed`); });
client.on('roomUserSeq', e => { events++; console.log(`👀 Viewers: ${e.viewerCount}`); });
client.on('connected', () => console.log(`\n✅ Connected to @${LIVE_USERNAME} - streaming events...\n`));
client.on('disconnected', () => console.log(`\n📊 Disconnected. Received ${events} events.\n`));
client.connect();
// Press Ctrl+C to stop. Sandbox allows 2 hours per WebSocket connection.🔌 Pure WebSocket version (no SDK, any language)
// ws-demo.mjs - Pure WebSocket, zero SDK
// npm install ws
import WebSocket from 'ws';
const API_KEY = 'YOUR_API_KEY';
const LIVE_USERNAME = 'tv_asahi_news';
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} - streaming events...\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📊 Disconnected. Received ${events} events.\n`));
// Press Ctrl+C to stop. Sandbox allows 2 hours per WebSocket connection.const { TikTokLive } = require('tiktok-live-api');
const client = new TikTokLive('streamer_username', { apiKey: 'YOUR_API_KEY' });
client.on('chat', (e) => console.log(`${e.user.uniqueId}: ${e.comment}`));
client.connect();- Go to tik.tools
- Sign up (no credit card required)
- Copy your API key
New accounts start on Sandbox, a free 7-day evaluation counted from the day the account was created: 20 requests/minute, 5,000 requests/day, 3 concurrent WebSocket connections, 60 new WebSocket connects per hour and 2 hours per WebSocket connection. After 7 days the key is refused (WebSocket close 4401 "Evaluation period ended", REST 403) until the account moves to a paid plan (Basic and up, see tik.tools/pricing).
Instead of passing apiKey directly, you can set it as an environment variable:
# Linux / macOS
export TIKTOOL_API_KEY=your_api_key_here
# Windows (CMD)
set TIKTOOL_API_KEY=your_api_key_here
# Windows (PowerShell)
$env:TIKTOOL_API_KEY="your_api_key_here"import { TikTokLive } from 'tiktok-live-api';
// Automatically reads TIKTOOL_API_KEY from environment
const client = new TikTokLive('streamer_username');
client.on('chat', (e) => console.log(e.comment));
client.connect();The WebSocket client streams live events. For everything else - leaderboards,
gaming ranks, recruiting, live status, gift catalogs, profiles - use the
TikTool REST client. One method per endpoint, fully promise-based.
import { TikTool } from 'tiktok-live-api';
const api = new TikTool({ apiKey: 'YOUR_KEY' });
// Live status (single + bulk)
await api.liveStatus('charlidamelio');
await api.bulkLiveCheck(['user1', 'user2', 'user3']);
// Leaderboards + rankings
await api.leaderboard({ region: 'US+' });
await api.ranklistGaming('US+');
await api.regionMovers('US+'); // entered top today, below cutoff now
// Recruiting (Agency) - find eligible creators
await api.eligibleCreators({ region: 'US+', limit: 50, min_score: 1000 });
// Profiles + gifts
await api.profileInfo('khaby.lame');
await api.userProfile('khaby.lame');
await api.giftsByCountry('US');Tier gating is enforced server-side: a call above your tier throws a
TikToolError with status === 403. Any endpoint not yet wrapped is reachable
via api.request('/webcast/...', { query }).
import { TikTool, TikToolError } from 'tiktok-live-api';
try {
await api.eligibleCreators({ region: 'US+' });
} catch (e) {
if (e instanceof TikToolError && e.status === 403) {
console.log('Upgrade required:', e.message);
}
}Method groups: signing/connection, live status, rankings/leaderboards, gifts, user/profile, content/feed, live analytics, moderation, CAPTCHA solver, captions (legacy). See the full endpoint + tier matrix.
Every event is dispatched by name. client.on('chat', e => ...) is fully typed end-to-end. Each event payload extends BaseEvent (type, timestamp, msgId, optional protoVersion: 1 | 2 | 3).
| Event | Description |
|---|---|
connected |
WebSocket open. |
disconnected |
WebSocket close. |
roomInfo |
One-shot post-connect: { roomId, wsHost, clusterRegion, connectedAt }. |
chat |
Chat message. user, comment, emotes, optional starred. v3 adds language (auto-detected ISO 639-1) + messageUuid (moderation correlation). |
gift |
Virtual gift. giftId, giftName, diamondCount, repeatCount, repeatEnd, giftType. v3 adds transactionId (dedup key), senderUserId, relationship (joinDayNumber, fromUser, toUser). |
like |
Like batch. likeCount, totalLikes. |
member |
Viewer joined. v3 adds actionCode, entrySource ("homepage_hot-live_cell", "follow-tab", ...), entryAction ("draw"/"click"), entryType ("rec" = algorithmic). |
social |
Follow / share. |
roomUserSeq |
Periodic viewer count tick. |
subscribe |
A viewer subscribed. |
| Event | Description |
|---|---|
battle |
PK lifecycle. status (1=ACTIVE, 2=STARTING, 3=ENDED, 4=PREPARING), battleDuration, teams. v3 adds extraHostUserIds, layoutSubtype. |
battleArmies |
Per-host MVP breakdown ticking through the PK. hosts[].contributors[] sorted MVP first. v3 adds transactionId. |
battleItemCard |
Booster card: x2 / x3 multipliers, gloves (crit), mist, thunder, extra-time, match-guide. Includes overlay assets from TikTok's CDN. |
battlePunishFinish |
Loser-side punishment screen ended. |
battleNotice |
PK notice (version-mismatch toast, invite-failure). |
battleGameplay |
PK mini-game state (Whack-A-Mole, Tic-Tac-Toe variants). |
linkLayer |
PK / link-mic negotiation (invite, cancel, accept, source change). |
linkMicOpponentGift |
Per-gift breakdown from the OPPONENT side of a PK. |
linkScreenChange |
PK split-screen layout flip (1v1 / 1vN / cohost mode swap). |
cohostLayoutUpdate |
Cohost layout subtype change. |
linkMic, linkMicLayoutState, link |
Generic link-mic envelopes. |
competition, competitionContributor |
Cross-stream competition + per-contributor breakdown. |
guestShowdown |
Guest showdown lifecycle. |
| Event | Description |
|---|---|
caption |
NEW in v3. TikTok native captions, delivered on the standard LIVE WebSocket when TikTok provides them for the stream. text, isFinal, startedAtMs, endsAtMs. |
| Event | Description |
|---|---|
goalUpdate |
Stream goal progress (subscriber / gift / watch-time goals). |
commentTray |
Comment tray UI state change. |
roomPin |
A chat got pinned by the host or a moderator. |
hostBoard |
Host leaderboard board update. |
privilegeAdvance |
Viewer privilege tier-up notification with overlay assets. |
anchorToolModification |
Creator modified a panel/widget. |
inRoomBanner |
In-room activity banner. |
roomSticker |
Room-wide sticker drop. |
bottomMessage |
Bottom-bar safety / risk notice. |
accessRecall, roomVerify |
Content-classification recheck events. |
smbBoard |
SMB (small-business) board overlay. |
streamStatus |
Stream status flip. |
shareRevenueNotice |
Share-revenue subscriber count change. |
capsule |
TikTok service-plus pin reminder. |
hotRoom |
TikTok promoted the room to a high-traffic slot. |
linkMicAnchorGuide |
Anchor (creator) guide nudges. |
| Event | Description |
|---|---|
imDelete |
Chat moderation delete. Correlate via chat.messageUuid (v3). |
unauthorizedMember |
Unauthorized viewer hit a gated feature. |
barrage |
Raw barrage feed (announcements, special effects). |
superFan, superFanJoin, superFanBox |
Super-fan lifecycle. |
emoteChat |
Inline emote message. |
| Event | Description |
|---|---|
giftPanelUpdate |
Real-time gift catalog change. Cache-bust your local catalog. |
giftDynamicRestriction |
Per-room gift availability flip / age-gating. |
giftGallery |
Host-side gift wall snapshot. |
giftUnlock |
Host unlocked a gated gift. |
viewerPicksUpdate |
TikTok-promoted viewer-pick gift highlights. |
oecLiveShopping, oecLiveManager, oecLiveBillboard |
OEC live-shopping events. |
ecShortItemRefresh |
Lucky-bag drop refreshed. |
| Event | Description |
|---|---|
aiSummary |
TikTok AI summary of the room (entry-time recap, multi-language). |
poll, shortTouch |
In-stream poll lifecycle. |
rankText, rankUpdate, hourlyRank |
Rank events. |
question, questionSelected, questionSlideDown |
Q&A round events. |
pictionaryUpdate, pictionaryEnd, pictionaryExit |
Drawing-game round events. |
fansEvent, fanTicket |
Fan-club events. |
envelope, envelopePortal |
Red-envelope drops + multi-room portal chain. |
gameMoment, gameServerFeature |
TikTok Gaming live integration. |
groupLiveMemberNotify |
Group-live member join / leave. |
perception |
Perception event (mute cancel, TikTok hint signal). |
control, room, liveIntro |
Stream control + room metadata. |
event- Fires for every decoded event (dump-to-queue pattern).unknown- Fires when TikTok ships a method we don't yet model (forward-compat hook).
All events are fully typed with TypeScript interfaces. Your IDE will show autocompletion for every field. See full per-event JSON examples + field tables.
import { TikTokLive } from 'tiktok-live-api';
const client = new TikTokLive({ uniqueId: 'creator_username', apiKey: 'tk_...' });
client.on('battle', e => console.log('PK', e.status, e.battleId, 'duration=', e.battleDuration));
client.on('battleArmies', e => {
console.log('Countdown:', e.secsRemaining, 's');
for (const host of e.hosts ?? []) {
console.log(`@${host.hostUserId} team total=${host.teamTotalScore}`);
const mvp = host.contributors[0];
if (mvp) console.log(` MVP @${mvp.nickname} score=${mvp.score}`);
}
});
client.on('battleItemCard', e => {
if (e.multiplier > 0) console.log(`x${e.multiplier} booster from @${e.senderUniqueId}`);
else console.log(`Effect ${e.effect} from @${e.senderUniqueId} (${e.durationSec}s)`);
});
await client.connect();The Live Captions service is no longer offered to new customers. It remains available for existing caption customers, and the TikTokCaptions client stays in this package for them. For free captions on any stream, use the caption event from TikTok native captions (see Native captions above).
import { TikTokCaptions } from 'tiktok-live-api';
const captions = new TikTokCaptions('streamer_username', { apiKey: 'YOUR_API_KEY', translate: 'en' });
captions.on('caption', (event) => console.log(event.text));
captions.connect();| Event | Description | Key Fields |
|---|---|---|
caption |
Real-time caption text | text, speaker, isFinal, language |
translation |
Translated caption | text, sourceLanguage, targetLanguage |
credits |
Credit balance update | total, used, remaining |
credits_low |
Low credit warning | remaining, percentage |
status |
Session status | status, message |
import { TikTokLive } from 'tiktok-live-api';
const client = new TikTokLive('streamer_username', { apiKey: 'YOUR_API_KEY' });
const giftLeaderboard = new Map<string, number>();
let messageCount = 0;
client.on('chat', (event) => {
messageCount++;
const msg = event.comment.toLowerCase().trim();
const user = event.user.uniqueId;
if (msg === '!hello') {
console.log(`>> BOT: Welcome ${user}! 👋`);
} else if (msg === '!stats') {
console.log(`>> BOT: ${messageCount} messages, ${giftLeaderboard.size} gifters`);
} else if (msg === '!top') {
const top = [...giftLeaderboard.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
top.forEach(([name, diamonds], i) => {
console.log(` ${i + 1}. ${name} - ${diamonds} 💎`);
});
}
});
client.on('gift', (event) => {
const user = event.user.uniqueId;
const diamonds = event.diamondCount || 0;
giftLeaderboard.set(user, (giftLeaderboard.get(user) || 0) + diamonds);
});
client.connect();This package ships with full TypeScript support. All events are typed:
import { TikTokLive, ChatEvent, GiftEvent } from 'tiktok-live-api';
const client = new TikTokLive('streamer', { apiKey: 'KEY' });
// Full autocompletion - your IDE knows the type of `event`
client.on('chat', (event: ChatEvent) => {
console.log(event.user.uniqueId); // ✓ typed
console.log(event.comment); // ✓ typed
});
client.on('gift', (event: GiftEvent) => {
console.log(event.giftName); // ✓ typed
console.log(event.diamondCount); // ✓ typed
});| Option | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
process.env.TIKTOOL_API_KEY |
Your TikTool API key |
autoReconnect |
boolean |
true |
Auto-reconnect on disconnect |
maxReconnectAttempts |
number |
5 |
Max reconnection attempts |
Methods:
client.on(event, handler)- Register event handlerclient.off(event, handler)- Remove event handlerclient.connect()- Connect to stream (returns Promise)client.disconnect()- Disconnect from streamclient.connected- Whether currently connectedclient.eventCount- Total events received
| Option | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
process.env.TIKTOOL_API_KEY |
Your TikTool API key |
translate |
string |
undefined |
Target translation language |
diarization |
boolean |
true |
Enable speaker identification |
maxDurationMinutes |
number |
60 |
Auto-disconnect timer |
Methods:
captions.on(event, handler)- Register event handlercaptions.off(event, handler)- Remove event handlercaptions.connect()- Start receiving captions (returns Promise)captions.disconnect()- Stop receiving captionscaptions.connected- Whether currently connected
| tiktok-live-api | tiktok-live-connector | TikTokLive (Python) | |
|---|---|---|---|
| Type | Managed agency-grade platform | Self-hosted client | Self-hosted client |
| Hosting | ✓ Fully managed, 99.9% uptime | You run the client; signing via paid backend | You run the client; signing via paid backend |
| TypeScript | ✓ First-class, fully typed | ✓ Typed | N/A (Python) |
| Unreal Engine plugin | ✓ | ✗ | ✗ |
| Gifter Intel (LTV, archetypes) | ✓ | ✗ | ✗ |
| Live Leaderboards (real-time) | ✓ Regional + global | ✗ | ✗ |
| Battle History + Per-Match Timeline | ✓ | ✗ | ✗ |
| League Rankings (Diamond Rush) | ✓ | ✗ | ✗ |
| Real-time Discord + Telegram Alerts | ✓ | ✗ | ✗ |
| Sniper Gap (live battle tracker) | ✓ | ✗ | ✗ |
| Agency CRM + Watchlists | ✓ | ✗ | ✗ |
| Public Profile Pages (creator + gifter) | ✓ Indexed | ✗ | ✗ |
| CAPTCHA Solving | ✓ Built-in (Pro+) | Via signing backend | Via signing backend |
| Feed Discovery | ✓ See who's live | ✗ | ✗ |
| Free evaluation | 7 days (Sandbox): 20 req/min, 5,000 req/day, 3 concurrent WS, 60 connects/hr, 2h per WS | ✓ MIT-licensed | ✓ MIT-licensed |
| ESM + CJS | ✓ Both supported | ✓ | N/A (Python) |
Tier is enforced server-side by your API key. Snapshot below; the full feature matrix lives at tik.tools/pricing.
| Tier | Weekly | Monthly | Req/min | Req/day | Concurrent WS | Connects/hr | WS max duration | Bulk check |
|---|---|---|---|---|---|---|---|---|
| Sandbox (7-day evaluation) | - | - | 20 | 5,000 | 3 | 60 | 2h | 5/req |
| Basic | $7 | $19 | 30 | 10,000 | 20 | Unlimited | 8h | 10/req |
| Pro | $15 | $49 | 120 | 75,000 | 50 | Unlimited | 12h | 50/req |
| Ultra | $45 | $149 | 300 | 300,000 | 250 | Unlimited | 24h | 100/req |
| Agency | $119 | $399 | 1,000 | 1,000,000 | 500 | Unlimited | 24h | 200/req |
- Sandbox (free 7-day evaluation from account creation, then a paid plan is required): 20 req/min, 5,000 req/day, 3 concurrent WS, 60 new connects/hr, 2h per WS, masked leaderboards, read-only gift catalog sample. Designed for devs building apps - upgrade when you need real usernames or more than ~5 connections (TikTok's per-IP limit). No datacenter proxies; calls come from your own IP.
- Basic ($7/wk - $19/mo): 30 req/min, 10,000 req/day, 20 concurrent WS, 8h per WS, datacenter proxies, masked leaderboards.
- Pro ($15/wk - $49/mo): 120 req/min, 75,000 req/day, 50 concurrent WS, 12h per WS, unmasked leaderboards, Feed Discovery, regional leaderboard signed URLs.
- Ultra ($45/wk - $149/mo): 300 req/min, 300,000 req/day, 250 concurrent WS, 24h per WS, Gift Catalog API (full TikTok gift catalog continuously re-synced), League Rankings unmasked, CSV exports, 99.5% uptime SLA.
- Agency ($119/wk - $399/mo): Everything in Ultra plus Live Gifter Firehose WS (region / league / global filters + min-diamond threshold), VIP Telegram alerts, VIP Web Vault (unmasked historical visual access), gifter intel unmasked, 500 concurrent WS.
Real-time gift event stream from our Dragonfly fan-out. Filter by region, league, or globally; cap by minimum diamond threshold. Mid-stream filter updates supported via update_filter frame, no reconnect needed.
const ws = new WebSocket(
`wss://api.tik.tools/firehose/gifters?apiKey=${KEY}&mode=region®ion=US%2B&min_diamonds=1000`
)
ws.on('message', (raw) => {
const evt = JSON.parse(raw)
// evt: { type:'gifter_alert', ts, gifter:{username,displayName,isAnonymous},
// creator:{uniqueId}, gift:{name,totalDiamonds}, region }
})
// Update filter without reconnect
ws.send(JSON.stringify({ type: 'update_filter', mode: 'global', min_diamonds: 5000 }))Modes: global (all regions), region (single region code), league (region + league class, e.g. B2).
- Python:
pip install tiktok-live-api - Any language: Connect via WebSocket:
wss://api.tik.tools?uniqueId=USERNAME&apiKey=KEY - Unreal Engine: Native C++/Blueprint plugin
- 🌐 Website: tik.tools
- 📖 Documentation: tik.tools/docs
- 🐍 Python SDK: pypi.org/project/tiktok-live-api
- 💻 GitHub: github.com/tiktool/tiktok-live-api
MIT