Agency rank feeds in Discord: gaming ranks, creator ranks and 99+ movers across all 30 regions, copy-paste usernames for backstage. /ranks to start (Global Agency).
tiktok-live-api is the most complete, production-managed TikTok LIVE API for Python. Receive real-time chat, gifts, likes, viewers, follows, shares and battle events from any TikTok LIVE stream over a single WebSocket - plus AI live captions with 60+ language translation, 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. Zero maintenance, zero breakages.
99.9% uptime - Never breaks when TikTok updates. No protobuf, no reverse engineering, no maintenance required. Powered by the TikTool managed WebSocket API.
![]() |
TikTool offers a fully managed TikTok LIVE API - real-time events, AI captions, CAPTCHA solving, and more. Free Community tier (forever). No credit card required. |
🎤 Exclusive: Real-Time Live Captions - AI-powered speech-to-text with translation & speaker diarization. No other TikTok library offers this.
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.
- AI live captions and translation. Real-time speech-to-text with 60+ language translation and speaker labels, available on no other TikTok LIVE library.
- 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 Python and Node.js clients plus a plain WebSocket API for any language.
- Free Sandbox tier. Start building for free, upgrade only when you need higher limits or unmasked data.
Instantly connect to a live TikTok stream and print real-time events to your terminal.
pip install tiktok-live-api
python -m tiktok_live_apiOr connect to a specific stream: python -m tiktok_live_api @username
- Why tiktok-live-api?
- Getting Started
- Try It Now - Live Demo
- Events
- Live Captions (AI STT)
- Async Usage
- Chat Bot Example
- Other Languages
- Pricing
- Star History
- License
| tiktok-live-api | TikTokLive (isaackogan) | TikTok-Live-Connector (Node.js) | |
|---|---|---|---|
| Stability | ✅ Managed API, 99.9% uptime | ❌ Breaks on TikTok updates | ❌ Breaks on TikTok updates |
| Setup | ✅ 3 lines of code | ❌ Protobuf + reverse engineering | ❌ Protobuf + signing server |
| Live Captions (AI STT) | ✅ Real-time speech-to-text | ❌ Not available | ❌ Not available |
| Translation | ✅ 50+ languages | ❌ Not available | ❌ Not available |
| CAPTCHA Solving | ✅ Built-in (Pro+) | ❌ Manual | ❌ Manual |
| Feed Discovery | ✅ See who's live | ❌ Not available | ❌ Not available |
| Maintenance | ✅ Zero - we handle everything | ❌ You fix breakages | ❌ You fix breakages |
| Multi-Language | ✅ Python, Node.js, Java, Go, C# | Python only | Node.js only |
| Free Tier | ✅ 5,000 req/day, 3 concurrent WS, 60 connects/hr, 2h per WS | ✅ Free (when it works) | ✅ Free (when it works) |
pip install tiktok-live-apiGo to tik.tools → Sign up → Copy your API key. No credit card required.
from tiktok_live_api import TikTokLive
client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
@client.on("chat")
def on_chat(event):
print(f"{event['user']['uniqueId']}: {event['comment']}")
@client.on("gift")
def on_gift(event):
print(f"{event['user']['uniqueId']} sent {event['giftName']} ({event['diamondCount']} 💎)")
@client.on("roomUserSeq")
def on_viewers(event):
print(f"Viewers: {event['viewerCount']}")
client.run()That's it. No protobuf, no signing servers, no reverse engineering, no breakages.
Copy-paste, run, see real-time TikTok events in your terminal. Works on the free Community tier - 2h per WS, runs as long as the stream is live.
# demo.py - TikTok LIVE in real time
# pip install tiktok-live-api
from tiktok_live_api import TikTokLive
API_KEY = "YOUR_API_KEY" # Get free key → https://tik.tools
LIVE_USERNAME = "tv_asahi_news" # Any live TikTok username
client = TikTokLive(LIVE_USERNAME, api_key=API_KEY)
events = 0
@client.on("connected")
def on_connected(event):
print(f"\n✅ Connected to @{LIVE_USERNAME} - streaming events...\n")
@client.on("chat")
def on_chat(event):
global events; events += 1
print(f"💬 {event['user']['uniqueId']}: {event['comment']}")
@client.on("gift")
def on_gift(event):
global events; events += 1
print(f"🎁 {event['user']['uniqueId']} sent {event['giftName']} ({event.get('diamondCount', 0)}💎)")
@client.on("like")
def on_like(event):
global events; events += 1
print(f"❤️ {event['user']['uniqueId']} liked × {event.get('likeCount', 0)}")
@client.on("member")
def on_member(event):
global events; events += 1
print(f"👋 {event['user']['uniqueId']} joined")
@client.on("roomUserSeq")
def on_viewers(event):
global events; events += 1
print(f"👀 Viewers: {event['viewerCount']}")
@client.on("disconnected")
def on_disconnect(event):
print(f"\n📊 Disconnected. Received {events} events.\n")
# Press Ctrl+C to stop. Community tier caps each WebSocket at 2 hours.
client.run()🔌 Pure WebSocket version (no SDK)
# ws-demo.py - Pure WebSocket, zero dependencies
# pip install websockets
import asyncio, websockets, json
API_KEY = "YOUR_API_KEY"
LIVE_USERNAME = "tv_asahi_news"
async def listen():
url = f"wss://api.tik.tools?uniqueId={LIVE_USERNAME}&apiKey={API_KEY}"
events = 0
async with websockets.connect(url) as ws:
print(f"\n✅ Connected to @{LIVE_USERNAME} - streaming events...\n")
async for message in ws:
msg = json.loads(message)
events += 1
data = msg.get("data", {})
user = data.get("user", {}).get("uniqueId", "")
event = msg.get("event", "")
if event == "chat": print(f"💬 {user}: {data.get('comment', '')}")
elif event == "gift": print(f"🎁 {user} sent {data.get('giftName', '')}")
elif event == "like": print(f"❤️ {user} liked × {data.get('likeCount', 0)}")
elif event == "member": print(f"👋 {user} joined")
elif event == "roomUserSeq": print(f"👀 Viewers: {data.get('viewerCount', 0)}")
else: print(f"📦 {event}")
print(f"\n📊 Disconnected. Received {events} events.\n")
asyncio.run(listen())The WebSocket client streams live events. For everything else - leaderboards,
gaming ranks, recruiting, live status, gift catalogs, profiles - use the
TikTool REST client. Async, one method per endpoint, no extra dependencies.
import asyncio
from tiktok_live_api import TikTool, TikToolError
async def main():
api = TikTool(api_key="YOUR_KEY")
# Live status (single + bulk)
await api.live_status("charlidamelio")
await api.bulk_live_check(["user1", "user2", "user3"])
# Leaderboards + rankings
await api.leaderboard(region="US+")
await api.ranklist_gaming("US+")
await api.region_movers("US+") # entered top today, below cutoff now
# Recruiting (Global Agency) - find eligible creators
recruits = await api.eligible_creators(region="US+", limit=50, min_score=1000)
# Profiles + gifts
await api.profile_info("khaby.lame")
await api.gifts_by_country("US")
asyncio.run(main())Tier gating is enforced server-side: a call above your tier raises
TikToolError with .status == 403. Any endpoint not yet wrapped is reachable
via await api.request("/webcast/...", query={...}).
try:
await api.eligible_creators(region="US+")
except TikToolError as e:
if e.status == 403:
print("Upgrade required:", e)See the full endpoint + tier matrix.
Every event is dispatched by name. Each event payload extends the BaseEvent shape (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. hosts[].contributors[] sorted MVP first. v3 adds transactionId. |
battleItemCard |
Booster card: x2/x3 multipliers, gloves (crit), mist, thunder, extra-time, match-guide. Carries TikTok CDN overlay assets. |
battlePunishFinish |
Loser-side punishment screen ended. |
battleNotice |
PK notice (version-mismatch toast, invite-failure). |
battleGameplay |
PK mini-game state. |
linkLayer |
PK / link-mic negotiation. |
linkMicOpponentGift |
Per-gift breakdown from the OPPONENT side of a PK. |
linkScreenChange |
PK split-screen layout flip. |
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 auto-captions on the LIVE WebSocket. text, isFinal, startedAtMs, endsAtMs. Independent of the operator-managed TikTok Live Captions product. |
| 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. |
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. |
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.unknown- Fires when TikTok ships a method we don't yet model (forward-compat hook).
All events ship with full TypedDict annotations. Your IDE shows autocompletion for every field. See full per-event JSON examples + field tables.
from tiktok_live_api import TikTokLive
client = TikTokLive(unique_id="creator_username", api_key="tk_...")
@client.on("battle")
def on_battle(e):
print(f"PK status={e['status']} id={e['battleId']} duration={e['battleDuration']}s")
@client.on("battleArmies")
def on_armies(e):
print(f"Countdown: {e.get('secsRemaining')}s")
for host in e.get("hosts", []):
print(f" @{host['hostUserId']} total={host['teamTotalScore']}")
if host["contributors"]:
mvp = host["contributors"][0]
print(f" MVP {mvp['nickname']} score={mvp['score']}")
@client.on("battleItemCard")
def on_card(e):
if e["multiplier"] > 0:
print(f"x{e['multiplier']} booster from @{e['senderUniqueId']}")
else:
print(f"Effect {e['effect']} from @{e['senderUniqueId']} ({e['durationSec']}s)")
client.connect()Transcribe and translate any TikTok LIVE stream in real-time. This feature is unique to TikTool - no other TikTok library offers it.
from tiktok_live_api import TikTokCaptions
captions = TikTokCaptions(
"streamer_username",
api_key="YOUR_API_KEY",
translate="en", # translate to English (50+ languages)
diarization=True, # identify who is speaking
)
@captions.on("caption")
def on_caption(event):
speaker = event.get("speaker", "")
text = event["text"]
is_final = event.get("isFinal", False)
print(f"[{speaker}] {text}{' ✓' if is_final else '...'}")
@captions.on("translation")
def on_translation(event):
print(f" → {event['text']}")
captions.run()| 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 |
For integration with async frameworks (FastAPI, Django Channels, etc.):
import asyncio
from tiktok_live_api import TikTokLive
async def main():
client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
@client.on("chat")
async def on_chat(event):
print(f"{event['user']['uniqueId']}: {event['comment']}")
await client.connect()
asyncio.run(main())from tiktok_live_api import TikTokLive
client = TikTokLive("streamer_username", api_key="YOUR_API_KEY")
gift_leaderboard = {}
message_count = 0
@client.on("chat")
def on_chat(event):
global message_count
message_count += 1
msg = event["comment"].lower().strip()
user = event["user"]["uniqueId"]
if msg == "!hello":
print(f">> BOT: Welcome {user}! 👋")
elif msg == "!stats":
print(f">> BOT: {message_count} messages, {len(gift_leaderboard)} gifters")
elif msg == "!top":
top = sorted(gift_leaderboard.items(), key=lambda x: -x[1])[:5]
for i, (name, diamonds) in enumerate(top):
print(f" {i+1}. {name} - {diamonds} 💎")
@client.on("gift")
def on_gift(event):
user = event["user"]["uniqueId"]
diamonds = event.get("diamondCount", 0)
gift_leaderboard[user] = gift_leaderboard.get(user, 0) + diamonds
client.run()TikTool Live is available in every major language:
| Language | Package | Install |
|---|---|---|
| Python | tiktok-live-api | pip install tiktok-live-api |
| Node.js / TypeScript | @tiktool/live | npm install @tiktool/live |
| Any Language | WebSocket API | wss://api.tik.tools?uniqueId=USERNAME&apiKey=KEY |
Full documentation with examples in Java, Go, C#, cURL → tik.tools/docs
Instead of passing api_key directly, set it as an environment variable:
# Linux / macOS
export TIKTOOL_API_KEY=your_api_key_here
# Windows (PowerShell)
$env:TIKTOOL_API_KEY="your_api_key_here"from tiktok_live_api import TikTokLive
# Automatically reads TIKTOOL_API_KEY from environment
client = TikTokLive("streamer_username")
client.on("chat", lambda e: print(e["comment"]))
client.run()| Tier | Weekly | Monthly | Requests / day | Concurrent WS | Connects / hour |
|---|---|---|---|---|---|
| Sandbox / Community | Free | Free | 5,000 | 3 | 60 |
| Basic | $7 | $19 | 10,000 | 20 | Unlimited |
| Pro | $15 | $49 | 75,000 | 50 | Unlimited |
| Ultra | $45 | $149 | 300,000 | 250 | Unlimited |
| Global Agency | $119 | $399 | 1,000,000 | 500 | Unlimited |
Full pricing + checkout: https://tik.tools/pricing
Tier ladder (each includes everything below it): Sandbox -> Basic -> Pro -> Ultra -> Global Agency. Sandbox is free with reduced rate limits + masked identifiers on intelligence endpoints; paid tiers raise limits and unmask data. Outgoing webhooks need Basic+. The agency intelligence endpoints (gaming ranks, movers, eligible-creator finder, gifter intel) need Global Agency.
| Tier | Headline features |
|---|---|
| Sandbox / Community | All core webcast + signing endpoints, real-time WS events (chat, gifts, viewers, battles, 18+ types), masked identifiers on intelligence endpoints. Development + evaluation only. |
| Basic | Everything in Sandbox, plus outgoing webhooks and chat send. Higher rate limits and more concurrent WS. |
| Pro | Full unmasked Leaderboard API, Feed Discovery, user profiles, built-in CAPTCHA solving, priority chat. |
| Ultra | Everything in Pro, plus Gift Catalog, unmasked League Rankings, and peak-viewer / high-value-gift webhook events. |
| Global Agency | Everything in Ultra, plus Gaming Ranks (all regions), Live Gifter Firehose WS, unmasked Gifter Leaderboard, CRM + watchlist, follower-milestone webhooks, and IP allowlist. |
| Endpoint | Min tier |
|---|---|
| POST /webcast/sign_url | Sandbox |
| POST /webcast/sign_websocket | Sandbox |
| GET /webcast/ws_credentials | Sandbox |
| GET /webcast/fetch | Sandbox |
| GET /webcast/room_id | Sandbox |
| GET /webcast/room_info | Sandbox |
| GET /webcast/room_video | Sandbox |
| GET /webcast/room_cover | Sandbox |
| GET /webcast/check_alive | Sandbox |
| POST /webcast/bulk_live_check | Sandbox |
| GET /webcast/live_status | Sandbox |
| GET /webcast/live-counts | Sandbox |
| POST /webcast/resolve_user_ids | Sandbox |
| GET /webcast/rankings | Sandbox |
| GET /webcast/leaderboard | Sandbox |
| GET /webcast/leaderboard/league | Sandbox |
| GET /webcast/leaderboard/leagues | Sandbox |
| GET /webcast/gift_info | Sandbox |
| GET /webcast/gift_gallery | Sandbox |
| GET /webcast/hashtag_list | Sandbox |
| GET /webcast/user_earnings | Sandbox |
| GET /webcast/live_analytics/video_list | Sandbox |
| GET /webcast/live_analytics/video_detail | Sandbox |
| GET /webcast/live_analytics/user_interactions | Sandbox |
| GET /webcast/rate_limits | Sandbox |
| POST /authentication/jwt | Sandbox |
| GET /api/live/connect | Sandbox |
| POST /chat-send | Basic |
| GET/POST /api/webhooks | Basic |
| POST /api/webhooks/{id}/test | Basic |
| GET /ws/sweep | Basic |
| GET /webcast/feed | Pro |
| POST /webcast/ranklist/regional | Pro |
| GET /webcast/user_profile | Pro |
| GET /api/leaderboards/country/:slug | Pro |
| GET /webcast/gifts_by_country | Ultra |
| GET /api/leaderboards/leagues/:region | Ultra |
| GET /api/leaderboards/league/:region/:classType | Ultra |
| GET /webcast/ranklist/gaming | Global Agency |
| GET /webcast/ranklist/gaming_movers | Global Agency |
| GET /webcast/ranklist/region_movers | Global Agency |
| GET /webcast/eligible_creators | Global Agency |
| GET /api/gifters/top | Global Agency |
| GET /api/gifters/leaderboard | Global Agency |
| GET /api/gifters/profile | Global Agency |
Full docs with request/response shapes and examples: https://tik.tools/docs
Creators: real-time live events (gifts, chat, viewers), your own live status + room info, earnings + analytics, signed CDN/stream URLs that do not expire. Developers: drop-in signing (works as a tiktok-live-connector backend - point the sign base at api.tik.tools), one-WebSocket fan-out (your IP never touches TikTok), bulk live checks, leaderboards, webhooks (HMAC-signed live.start/live.end and more), SDKs across languages. Agencies (Global Agency): TikTok LIVE gaming ranks + creator ranks + 99+ movers across all 30 regions, eligible-creator recruiting finder, gifter intelligence (top gifters, profiles, leaderboards), and the Discord bot that posts copy-paste username batches for backstage.
Real-time gift event stream. Filter by region, league, or globally; cap by minimum diamond threshold.
import asyncio, json, websockets
API_KEY = "tk_..."
URL = f"wss://api.tik.tools/firehose/gifters?apiKey={API_KEY}&mode=region®ion=US%2B&min_diamonds=1000"
async def main():
async with websockets.connect(URL) as ws:
async for raw in ws:
evt = json.loads(raw)
# evt: { type:'gifter_alert', ts, gifter:{username,displayName,isAnonymous},
# creator:{uniqueId}, gift:{name,totalDiamonds}, region }
print(evt)
asyncio.run(main())Modes: global (all regions), region (single region code), league (region + league class, e.g. B2). Update the filter mid-stream by sending {"type":"update_filter","mode":"global","min_diamonds":5000} - no reconnect needed.
Get your free API key → tik.tools
If this project helps you, please consider giving it a ⭐ - it helps others discover it!
- 🌐 Website: tik.tools
- 📖 Documentation: tik.tools/docs
- 📦 Node.js SDK: @tiktool/live on npm
- 🐍 PyPI: tiktok-live-api
- 💻 GitHub (Node.js): tiktool/tiktok-live-api
This project is licensed under the MIT License - see the LICENSE file for details.
- TikTool - Creator & Maintainer - tik.tools
See also the full list of contributors who have participated in this project.


