Connect to any TikTok Live stream and receive real-time events in C#. No signing server, no API keys, no authentication required.
// Connect to a live stream — auth and room resolution handled internally
var client = new TikTokLiveClient("username_here");
// Subscribe to events — each carries fully decoded protobuf data
client.OnChat += msg =>
Console.WriteLine($"[chat] {msg.User?.Nickname}: {msg.Comment}");
client.OnGift += msg =>
Console.WriteLine($"[gift] {msg.User?.Nickname} sent {msg.GiftDetails?.GiftName} x{msg.RepeatCount} ({msg.GiftDetails?.DiamondCount} diamonds)");
client.OnLike += msg =>
Console.WriteLine($"[like] {msg.User?.Nickname} ({msg.TotalLikeCount} total)");
// Runs the whole session: completes only after the final disconnect (max retries
// exhausted or cancellation). OnConnected fires as soon as the room is resolved.
await client.RunAsync();dotnet add package PirateTok.Live
Targets netstandard2.0 — works with .NET 6+, .NET Framework 4.6.1+, Unity 2021+.
| Language | Install | Repo |
|---|---|---|
| Rust | cargo add piratetok-live-rs |
live-rs |
| Go | go get github.com/PirateTok/live-go |
live-go |
| Python | pip install piratetok-live-py |
live-py |
| JavaScript | npm install piratetok-live-js |
live-js |
| Java | com.piratetok:live |
live-java |
| Lua | luarocks install piratetok-live-lua |
live-lua |
| Elixir | {:piratetok_live, "~> 0.1"} |
live-ex |
| Dart | dart pub add piratetok_live |
live-dart |
| C | #include "piratetok.h" |
live-c |
| PowerShell | Install-Module PirateTok.Live |
live-ps1 |
| Shell | bpkg install PirateTok/live-sh |
live-sh |
- Zero signing dependency — no API keys, no signing server, no external auth
- 64 decoded event types — chat, gifts, likes, joins, follows, shares, battles, polls, and more
- Auto-reconnection — stale detection, exponential backoff, self-healing auth
- Enriched User data — badges, gifter level, moderator status, follow info, fan club
- Sub-routed convenience events —
OnFollow,OnShare,OnJoin,OnLiveEnded
var client = new TikTokLiveClient("username_here")
.CdnEu()
.Timeout(TimeSpan.FromSeconds(15))
.MaxRetries(10)
.StaleTimeout(TimeSpan.FromSeconds(90));| Method | Default | Description |
|---|---|---|
.Cdn(host) |
webcast-ws.tiktok.com |
Set custom CDN hostname |
.CdnEu() |
— | Shorthand for EU CDN (webcast-ws.eu.tiktok.com) |
.CdnUs() |
— | Shorthand for US CDN (webcast-ws.us.tiktok.com) |
.Timeout(TimeSpan) |
10s | HTTP request timeout for ttwid fetch, online check, room info |
.HeartbeatInterval(TimeSpan) |
10s | Interval between WSS heartbeat frames (also sent as heartbeat_duration) |
.MaxRetries(int) |
5 | Maximum consecutive failed attempts before giving up (reset after a 30s healthy session) |
.StaleTimeout(TimeSpan) |
60s | Close and reconnect if no data arrives within this window |
.Proxy(string) |
none | HTTP/HTTPS/SOCKS5 proxy URL — applies to all HTTP requests and WSS |
.Proxy(IWebProxy) |
none | Same, but accepts a System.Net.IWebProxy instance directly |
.UserAgent(string) |
random | Override the random UA pool with a fixed user agent |
.Cookies(string) |
none | Append session cookies alongside ttwid in WSS cookie header ("sessionid=xxx; sid_tt=xxx") |
.Language(string) |
system | Override language sent in WSS URL params (auto-detected from system locale) |
.Region(string) |
system | Override region sent in WSS URL params (auto-detected from system locale) |
.Compress(bool) |
true |
Disable gzip compression for WSS payloads (trades bandwidth for CPU) |
// Normal rooms
var info = await TikTokLiveClient.FetchRoomInfoAsync(
"ROOM_ID",
TimeSpan.FromSeconds(10));
// 18+ rooms — pass session cookies from browser DevTools
var info = await TikTokLiveClient.FetchRoomInfoAsync(
"ROOM_ID",
TimeSpan.FromSeconds(10),
cookies: "sessionid=abc; sid_tt=abc");The top-viewers box (usually top 3) rides on every RoomUserSeq event — no cookies needed:
client.OnRoomUserSeq += msg =>
{
foreach (var c in msg.TopViewers())
Console.WriteLine($"#{c.Rank} {c.User?.Nickname} ({c.Score})");
};The full audience roster is a separate call. TikTok gates it behind a login, so session cookies are
required for this call only — without them it throws SessionRequiredException:
var room = await TikTokLiveClient.CheckOnlineAsync("username_here", TimeSpan.FromSeconds(10));
var audience = await TikTokLiveClient.FetchRoomAudienceAsync(
room.RoomId, room.AnchorId, TimeSpan.FromSeconds(10),
cookies: "sessionid=abc; sid_tt=abc");
// audience.Total, audience.Anonymous, audience.Viewers (rank, score, username, follower count, ...)Pass null as the anchor ID to resolve it from room info (one extra request).
- Resolves username to room ID via TikTok JSON API
- Fetches a ttwid cookie (retried up to 8× — TikTok only sets it intermittently) and opens a direct WSS connection
- Protobuf heartbeats every 10s
- Decodes protobuf stream into typed C# objects via protobuf-net
- Auto-reconnects on stale/dropped connections, reusing ttwid + UA; both rotate only on DEVICE_BLOCKED or a connection that died within 30s
dotnet run --project examples/BasicChat -- <username> # connect + print chat events
dotnet run --project examples/OnlineCheck -- <username> # check if user is live
dotnet run --project examples/StreamInfo -- <username> # fetch room metadata + stream URLs
dotnet run --project examples/GiftTracker -- <username> # track gifts with diamond totals
dotnet run --project examples/GiftStreak -- <username> # track gift streaks with per-event deltas
dotnet run --project examples/ProfileLookup -- <username> # fetch user profile via SIGI scrape
dotnet run --project examples/Audience -- <username> "sessionid=...; sid_tt=..." # full viewer roster (login required)Deterministic cross-lib validation against binary WSS captures. Requires testdata from a separate repo:
git clone https://github.com/PirateTok/live-testdata testdata
dotnet testReplay tests fail if testdata is not found — they never pass on missing data. Set PIRATETOK_TESTDATA to point to a custom location.
Offline unit tests (ttwid retry, reconnect budget, top viewers, audience parsing) live in tests/UnitTests and need no network.
None currently tracked.
0BSD
