DEV Community

Cover image for Pull real-time TikTok LIVE data in 5 lines (typed JS + Python SDK)
Anonymous Angels
Anonymous Angels

Posted on Originally published at toktikhq.com

Pull real-time TikTok LIVE data in 5 lines (typed JS + Python SDK)

Public TikTok LIVE data — who's ranking right now, who's gifting the most, what's happening inside a room this second — is awkward to fetch and easy to get wrong. Anonymous scraping breaks, the shapes are undocumented, and nothing tells you how fresh or how complete an answer actually is.

TokTik is a typed, metered API over observed public TikTok LIVE activity, with official SDKs for JavaScript/TypeScript and Python. Every REST response carries a provenance envelope so you always know what you're looking at, and there's a realtime event stream for chat / gift / like frames over WebSocket.

Here's the whole "hello world."

Independent project — not affiliated with, or endorsed by, TikTok. The data is observed from public LIVE surfaces and labelled as such; it is not an official TikTok feed, and it covers a stated, expanding Coverage Set rather than all of TikTok.

REST in 5 lines

JavaScript / TypeScript

npm i @toktikhq/sdk-js
Enter fullscreen mode Exit fullscreen mode
import { TokTikClient } from "@toktikhq/sdk-js";

const client = new TokTikClient({ apiKey: process.env.TOKTIK_API_KEY! });

const board = await client.rankings.official({ board: "hourly", region: "VN" });
console.log(board.provenance.freshness, board.data.board.entries);
Enter fullscreen mode Exit fullscreen mode

Python

pip install toktik
Enter fullscreen mode Exit fullscreen mode
from toktik import TokTikClient

client = TokTikClient(api_key="ttk_live_...")
board = client.rankings.official(board="hourly", region="VN")
print(board["provenance"], board["data"]["board"]["entries"])
Enter fullscreen mode Exit fullscreen mode

Same surface in both languages: official observed rankings (hourly / daily / regional boards), movers, gifter and whale leaderboards, creator lookups and changes, videos and comments. Arguments are the language-native casing (camelCase in JS, snake_case in Python); the SDK maps them to the wire names, and a wrong key is a hard 400 rather than a silently ignored filter.

Provenance is part of the answer

Much of this data is observed, not officially published — so pretending it's ground truth is a bug. Every data method returns { data, provenance }, and the SDK never strips the envelope:

  • freshness — near_realtime / stale / historical
  • source — where the observation came from
  • coverageStatus — whether this slice is inside the Coverage Set

Branch on it before you trust a number:

const board = await client.rankings.official({ board: "daily", region: "US" });

if (board.provenance.freshness === "historical") {
  // last snapshot is old — label it in your UI instead of showing it as "now"
}
for (const entry of board.data.board.entries) {
  console.log(entry.rank, entry.creator.handle);
}
Enter fullscreen mode Exit fullscreen mode

That envelope is the difference between "a ranking" and "a ranking you can honestly put in front of a customer."

Realtime — the differentiator

Rankings are a snapshot; a LIVE room is a firehose. client.live.stream(...) gives you the firehose in three lines and owns the parts that are genuinely annoying:

const stream = await client.live.stream(["@some.creator"], {
  onEvent:  (f) => console.log(f.event, f.data),          // chat | gift | like | ...
  onStatus: (f) => console.log(f.status, f.reason),        // queued | active | offline | unavailable
  onError:  (e) => console.error(e),
  onReconnect: () => console.log("resumed"),
});
Enter fullscreen mode Exit fullscreen mode

What the SDK handles for you:

  • Handshake token lifetime — it mints a short-lived token per connection, so an expiry mid-stream costs a reconnect, not a dead socket.
  • Secure token transport — the token rides in the WebSocket subprotocol, never in the URL (URLs get logged; tokens shouldn't).
  • Reconnect with resume — backoff-with-jitter, then resubscribe on resume, so a blip doesn't drop your subscriptions.

The statuses are deliberately honest: queued means "we've accepted the creator but aren't attached yet," active means frames are flowing, offline / unavailable mean exactly what they say — no faking a live feed that isn't there.

Python gets the same stream as an async iterator:

pip install "toktik[realtime]"    # adds the websockets dependency
Enter fullscreen mode Exit fullscreen mode
import asyncio
from toktik import TokTikClient, EventFrame

async def main():
    client = TokTikClient(api_key="ttk_live_...")
    async for frame in await client.live.stream(["@some.creator"]):
        if isinstance(frame, EventFrame):
            print(frame.event, frame.data)   # chat / gift / like / ...

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

Errors that mean something

A non-2xx raises TokTikApiError, which keeps the status distinguishable instead of collapsing everything into one exception — because the right reaction is different each time:

import { TokTikClient, TokTikApiError } from "@toktikhq/sdk-js";

try {
  await client.creators.get("someone");
} catch (error) {
  if (error instanceof TokTikApiError) {
    error.isPaymentRequired; // 402 — out of credits; retrying won't help, top up
    error.isForbidden;       // 403 — your key lacks the scope this resource is sold under
    error.isUnauthorized;    // 401 — bad or expired key
    error.retryable;         // true only for 429 + 5xx — safe to back off and retry
  }
}
Enter fullscreen mode Exit fullscreen mode

Python mirrors it: is_payment_required (402), is_forbidden (403), is_rate_limited (429), and retryable, each carrying status, code, and request_id. 402 means buy credits, 403 means the key is missing a scope, 429 means back off — three very different fixes, three distinguishable errors.

Start

There's a free tier to kick the tyres, then metered credits — prepaid, no surprise invoices. Point your key at the quickstart above and you have observed rankings, gifter leaderboards, and a realtime LIVE stream behind one typed client.

TokTik is an independent product. It is not affiliated with or endorsed by TikTok; its data is observed from public surfaces, labelled with provenance, and bounded to a stated Coverage Set.

Top comments (0)