JSPM

  • Created
  • Published
  • Downloads 105
  • Score
    100M100P100Q80332F
  • License MIT

TikTok LIVE API SDK — Real-time chat, gifts, battles, follows, likes & 18+ event types from any TikTok livestream via WebSocket. Zero dependencies. Works in Node.js, Bun, Deno, Cloudflare Workers & Durable Objects.

Package Exports

  • @tiktool/live

Readme

@tiktool/live

TikTok LIVE API SDK for Node.js, Bun, Deno, and Cloudflare Workers

npm version License: MIT Node.js TypeScript Downloads

Real-time TikTok LIVE events — chat messages, gifts, follows, likes, battles, viewer counts, and 18+ event types — streamed directly to your application via WebSocket.

Quick Start · Events · API Utilities · REST API · Pricing · Get API Key


Why @tiktool/live?

  • Direct WebSocket connection to TikTok from your own IP — events are never proxied through third-party servers
  • Zero dependencies — built-in protobuf parser, universal WebSocket resolution, gzip decompression
  • Universal runtime support — Node.js 18+, Bun, Deno, Cloudflare Workers, Durable Objects, and browsers
  • Full TypeScript — complete type definitions for all 18+ event types with IDE autocompletion
  • Battle-tested — production-ready with auto-reconnect, heartbeat management, and error recovery
  • Generous free tier — 2,500 requests/day, 1 WebSocket connection, no credit card required

⚡ Quick Start

npm install @tiktool/live

Get your free API key at tik.tools — no credit card required. The free tier includes WebSocket signing, live status checks, and 2,500 requests/day.

import { TikTokLive } from '@tiktool/live';

const live = new TikTokLive({
    uniqueId: 'username',
    apiKey: 'YOUR_API_KEY',
});

live.on('chat', e => console.log(`${e.user.uniqueId}: ${e.comment}`));
live.on('gift', e => console.log(`${e.user.uniqueId} sent ${e.giftName} (${e.diamondCount}💎)`));
live.on('member', e => console.log(`${e.user.uniqueId} joined the stream`));
live.on('roomUserSeq', e => console.log(`Viewers: ${e.viewerCount}`));

await live.connect();

Architecture

    Your App                   api.tik.tools                  TikTok
  +-----------+              +--------------+           +--------------+
  |           |-- sign_url -->  Signs URL   |           |              |
  |   SDK     |<-- X-Bogus --|  (1 req)     |           |   WebSocket  |
  |           |              |              |           |   Server     |
  |           |------------- Connect directly --------->|              |
  |           |<------------ Live events (protobuf) <---|              |
  +-----------+              +--------------+           +--------------+
                             ^ Only signing             ^ Direct from
                               touches our API            YOUR IP

The SDK calls the sign server once per connection to generate a cryptographic signature, then connects directly to TikTok's WebSocket server from your IP address. All event data flows directly between your app and TikTok — never through our infrastructure.


📡 Events

live.on('chat', (event) => {
    event.user.uniqueId;   // string
    event.user.nickname;   // string
    event.comment;         // string
});

live.on('event', (event) => {
    console.log(event.type, event);
});

Event Reference

Event Type Description Key Fields
chat ChatEvent Chat message received user, comment, emotes
member MemberEvent User joined the stream user, action
like LikeEvent User liked the stream user, likeCount, totalLikes
gift GiftEvent Gift sent to streamer user, giftName, diamondCount, repeatCount, combo
social SocialEvent Follow or share event user, action ('follow' / 'share')
roomUserSeq RoomUserSeqEvent Viewer count update viewerCount, totalViewers
battle BattleEvent Battle started/ended battleId, status, teams
battleArmies BattleArmiesEvent Battle scores update battleId, teams (with scores)
subscribe SubscribeEvent New subscriber user, subMonth
emoteChat EmoteChatEvent Emote message user, emoteId, emoteUrl
envelope EnvelopeEvent Treasure chest envelopeId, diamondCount
question QuestionEvent Q&A question user, questionText
control ControlEvent Stream control signal action (3 = stream ended)
room RoomEvent Room status change status
liveIntro LiveIntroEvent Stream intro displayed roomId, title
rankUpdate RankUpdateEvent Ranking update rankType, rankList
linkMic LinkMicEvent Link Mic event action, users
unknown UnknownEvent Unrecognized message method

Connection Events

Event Callback Description
connected () => void Successfully connected to the livestream
disconnected (code, reason) => void Disconnected from the livestream
roomInfo (info: RoomInfo) => void Room metadata received
error (error: Error) => void Connection or parsing error

🛠️ API Utilities

The SDK includes server-side utilities for calling TikTool REST endpoints. These handle the sign-and-return flow automatically — resolving usernames to room IDs, fetching signed URLs, and returning actual TikTok data.

callApi(options) — High-Level Helper

The easiest way to call any TikTool endpoint. Handles the full flow automatically:

import { callApi } from '@tiktool/live';

// Get stream video URLs for a user
const streamData = await callApi({
    apiKey: 'YOUR_API_KEY',
    endpoint: '/webcast/room_video',
    uniqueId: 'streamer_name',
});

// Get room info
const roomInfo = await callApi({
    apiKey: 'YOUR_API_KEY',
    endpoint: '/webcast/room_info',
    uniqueId: 'streamer_name',
});

// Use a custom server URL
const data = await callApi({
    serverUrl: 'https://your-server.com',
    apiKey: 'YOUR_API_KEY',
    endpoint: '/webcast/rankings',
    uniqueId: 'streamer_name',
    method: 'GET',
});

CallApiOptions

Option Type Default Description
apiKey string API key from tik.tools
endpoint string API path (e.g. '/webcast/room_video')
uniqueId string TikTok username to resolve
serverUrl string https://api.tik.tools Custom API server URL
method 'GET' | 'POST' 'POST' HTTP method
extraBody object Additional POST body fields

resolveRoomId(uniqueId) — Username to Room ID

Scrapes a TikTok live page to extract the room_id. Results are cached for 5 minutes. Returns null if the user is not live.

import { resolveRoomId } from '@tiktool/live';

const roomId = await resolveRoomId('streamer_name');
if (roomId) {
    console.log(`Room ID: ${roomId}`);
}

resolveLivePage(uniqueId) — Full Live Page Resolution

Returns all live page metadata including the room ID, session cookie (ttwid), and cluster region. Used internally by TikTokLive.connect(). Returns null if the user is not live.

import { resolveLivePage } from '@tiktool/live';

const info = await resolveLivePage('streamer_name');
if (info) {
    console.log(`Room: ${info.roomId}, Region: ${info.clusterRegion}`);
}

LivePageInfo

Field Type Description
roomId string Active room ID for the livestream
ttwid string Session cookie for WebSocket auth
clusterRegion string Server cluster region (e.g. 'us', 'eu')

fetchSignedUrl(response) — Execute Signed URL Response

Takes a sign-and-return API response and fetches the actual TikTok data from the signed URL.

import { fetchSignedUrl } from '@tiktool/live';

// After calling an API endpoint that returns action: 'fetch_signed_url'
const tikTokData = await fetchSignedUrl(apiResponse);

🧩 CAPTCHA Solver (Ultra)

Solve TikTok CAPTCHAs programmatically. Requires an Ultra tier API key.

solvePuzzle(apiKey, puzzleB64, pieceB64, serverUrl?) — Puzzle Slider

import { solvePuzzle } from '@tiktool/live';

const result = await solvePuzzle('YOUR_API_KEY', backgroundBase64, pieceBase64);
console.log(`Slide to X=${result.slideX}px (confidence: ${result.confidence})`);
Field Type Description
slideX number Pixel X position for the slider
confidence number Confidence score (0.0–1.0)
solveTimeMs number Time taken to solve in ms

solveRotate(apiKey, outerB64, innerB64, serverUrl?) — Rotate Whirl

import { solveRotate } from '@tiktool/live';

const result = await solveRotate('YOUR_API_KEY', outerBase64, innerBase64);
console.log(`Rotate ${result.angle}° (confidence: ${result.confidence})`);
Field Type Description
angle number Rotation angle in degrees (0–360)
confidence number Confidence score (0.0–1.0)
solveTimeMs number Time taken to solve in ms

solveShapes(apiKey, imageB64, serverUrl?) — 3D Shape Matching

import { solveShapes } from '@tiktool/live';

const result = await solveShapes('YOUR_API_KEY', imageBase64);
console.log(`Match: (${result.point1.x},${result.point1.y}) ↔ (${result.point2.x},${result.point2.y})`);
Field Type Description
point1 {x, y} First matching shape center
point2 {x, y} Second matching shape center
confidence number Confidence score (0.0–1.0)
solveTimeMs number Time taken to solve in ms

🌐 REST API Endpoints

The sign server at api.tik.tools exposes a full REST API alongside WebSocket signing. Endpoints use a sign-and-return pattern — when called with a unique_id, they return instructions for resolving the room ID; when called with a room_id, they return a signed URL to fetch data directly from TikTok. Use callApi() to handle this automatically.

Endpoint Description
POST /webcast/sign_url Generate X-Bogus signed URL
GET /webcast/check_alive Check if a user is currently live
GET /webcast/room_info Detailed room metadata (title, viewers, streamer info)
GET /webcast/room_id Resolve username to room ID
GET /webcast/room_cover Get stream cover image URL
GET /webcast/room_video Get HLS/FLV stream URLs
GET /webcast/rankings In-stream contribution rankings
GET /webcast/gift_info Available gifts and diamond values
GET /webcast/hashtag_list Trending live hashtags
GET /webcast/bulk_live_check Check multiple users' live status in one request
POST /webcast/fetch Fetch protobuf messages via HTTP polling
GET /webcast/ws_credentials Get WebSocket connection credentials
POST /webcast/sign_websocket Sign a WebSocket URL
GET /webcast/resolve_user_ids Resolve display names to user IDs
POST /webcast/chat Send chat messages (requires session cookies)
GET /webcast/user_earnings Streamer earnings data (requires session cookies)
GET /webcast/feed Live feed discovery
GET /webcast/live_analytics/* Video list, video detail, user interactions
GET /webcast/moderation/* Mute and ban management
POST /authentication/jwt Generate scoped JWT for frontend WebSocket access
POST /captcha/solve/puzzle Solve puzzle slider CAPTCHA (Pro+)
POST /captcha/solve/rotate Solve rotate whirl CAPTCHA (Pro+)
POST /captcha/solve/shapes Solve 3D shape matching CAPTCHA (Pro+)

Full API documentation: tik.tools/docs


💰 Pricing

All plans include signatures and full WebSocket support. Higher tiers unlock priority routing, CAPTCHA solving, and increased throughput.

Free Pro Ultra
Weekly Free $15/wk $45/wk
Monthly Free $48/mo $169/mo
Yearly Free $39/mo $149/mo
Daily Requests 2,500 50,000 250,000
WebSocket Connections 3 50 1,000
Endpoints All All All
CAPTCHA Solver 50/day 500/day
Uptime SLA 99.5%
Priority Routing
Overage $0.001/req $0.0005/req
Support Community Email Dedicated

Get your Free API key at tik.tools.


Examples

Chat Bot

import { TikTokLive } from '@tiktool/live';

const live = new TikTokLive({
    uniqueId: 'streamer_name',
    apiKey: 'YOUR_API_KEY',
});

live.on('chat', (e) => {
    if (e.comment.toLowerCase() === '!hello') {
        console.log(`Hello, ${e.user.nickname}!`);
    }
});

live.on('gift', (e) => {
    if (e.repeatEnd) {
        const total = e.diamondCount * e.repeatCount;
        console.log(`${e.user.uniqueId} sent ${e.repeatCount}x ${e.giftName} (${total} diamonds)`);
    }
});

await live.connect();

Real-Time OBS Overlay

import { TikTokLive } from '@tiktool/live';
import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });
const live = new TikTokLive({
    uniqueId: 'streamer_name',
    apiKey: 'YOUR_API_KEY',
});

live.on('event', (event) => {
    for (const client of wss.clients) {
        client.send(JSON.stringify(event));
    }
});

await live.connect();
console.log('Forwarding TikTok LIVE events → ws://localhost:8080');

Gift Leaderboard

import { TikTokLive, GiftEvent } from '@tiktool/live';

const live = new TikTokLive({
    uniqueId: 'streamer_name',
    apiKey: 'YOUR_API_KEY',
});

const leaderboard = new Map<string, number>();

live.on('gift', (e: GiftEvent) => {
    if (e.repeatEnd) {
        const total = e.diamondCount * e.repeatCount;
        const current = leaderboard.get(e.user.uniqueId) || 0;
        leaderboard.set(e.user.uniqueId, current + total);

        const sorted = [...leaderboard.entries()].sort((a, b) => b[1] - a[1]);
        console.clear();
        console.log('🏆 Gift Leaderboard');
        sorted.slice(0, 10).forEach(([user, diamonds], i) => {
            console.log(`${i + 1}. ${user}: ${diamonds} 💎`);
        });
    }
});

await live.connect();

Battle Monitor

import { TikTokLive } from '@tiktool/live';

const live = new TikTokLive({
    uniqueId: 'streamer_name',
    apiKey: 'YOUR_API_KEY',
});

live.on('battle', (e) => {
    console.log(`Battle ${e.battleId} — Status: ${e.status}`);
    for (const team of e.teams) {
        console.log(`  Team ${team.hostUserId}: ${team.score} points (${team.users.length} members)`);
    }
});

live.on('battleArmies', (e) => {
    for (const team of e.teams) {
        const host = team.hostUser?.uniqueId || team.hostUserId;
        console.log(`  ${host}: ${team.score} points`);
    }
});

await live.connect();

Frontend JWT Authentication

const data = await fetch('https://tik.tools/api/live/connect?uniqueId=streamer')
    .then(r => r.json());

const ws = new WebSocket(`${data.wsUrl}?uniqueId=streamer&jwtKey=${data.token}`);

ws.onmessage = (event) => {
    const parsed = JSON.parse(event.data);
    console.log(parsed.type, parsed);
};

🔧 Configuration

new TikTokLive(options)

Option Type Default Description
uniqueId string TikTok username (without @)
apiKey string API key from tik.tools
signServerUrl string https://api.tik.tools Custom sign server URL
autoReconnect boolean true Auto-reconnect on disconnect
maxReconnectAttempts number 5 Maximum reconnect attempts
heartbeatInterval number 10000 Heartbeat interval in milliseconds
debug boolean false Enable debug logging
webSocketImpl any Auto-detected Custom WebSocket implementation

Instance Properties

Property Type Description
connected boolean Current connection status
eventCount number Total events received
roomId string Active room ID

Instance Methods

Method Returns Description
connect() Promise<void> Connect to a livestream
disconnect() void Gracefully disconnect
on(event, handler) this Listen for events
once(event, handler) this Listen for a single event
off(event, handler) this Remove event listener

TypeScript

Full TypeScript support with generic type inference on all event handlers:

import { TikTokLive, ChatEvent, GiftEvent, BattleEvent } from '@tiktool/live';

const live = new TikTokLive({
    uniqueId: 'username',
    apiKey: 'YOUR_API_KEY',
});

live.on('chat', (event: ChatEvent) => {
    const username: string = event.user.uniqueId;
    const message: string = event.comment;
});

live.on('gift', (event: GiftEvent) => {
    const diamonds: number = event.diamondCount;
    const isCombo: boolean = event.combo;
});

live.on('battle', (event: BattleEvent) => {
    const teams: typeof event.teams = event.teams;
    const score: number = teams[0].score;
});

All event types, user interfaces, and configuration options are fully exported for use in your application's type system.


Runtime Compatibility

Runtime Version WebSocket Notes
Node.js ≥ 22 Native No additional packages needed
Node.js 18–21 ws package npm i ws
Bun ≥ 1.0 Native Full support
Deno ≥ 1.x Native Full support
Cloudflare Workers Native Full support
Browsers Modern Native Via bundled connect endpoint

License

MIT © TikTool