Python is the most popular language for web scraping and data analysis - and TikTok is one of the richest social-media datasets on the planet. In this tutorial we'll connect Python to the TikLiveAPI REST API to pull TikTok user profiles, posts, follower counts, and engagement metrics in just a few lines of code.
You'll learn how to:
X-Api-Key headerhttpx and async I/Orequests library: pip install requestsRegister a TikLiveAPI account, pick a credit plan, and copy your API key from the profile dashboard. The key is a single string that you pass on every request via the X-Api-Key header.
Keep secrets out of source control by reading the key from an environment variable:
export TIKLIVEAPI_KEY="paste-your-key-here"
Then in Python:
import os
API_KEY = os.environ["TIKLIVEAPI_KEY"]
BASE_URL = "https://api.tikliveapi.com"
HEADERS = {"X-Api-Key": API_KEY}
The /userinfo-by-username/ endpoint returns a user's display name, bio, follower and following counts, total likes, and avatar URLs in a single call.
import requests
def get_user(username: str) -> dict:
response = requests.get(
f"{BASE_URL}/userinfo-by-username/",
params={"username": username},
headers=HEADERS,
timeout=10,
)
response.raise_for_status()
return response.json()
profile = get_user("tiktok")
print(profile["user"]["nickname"])
print(f"Followers: {profile['stats']['followerCount']:,}")
print(f"Likes: {profile['stats']['heartCount']:,}")
print(f"Videos: {profile['stats']['videoCount']:,}")
Two things worth noting:
response.raise_for_status() throws on 4xx and 5xx - we'll wrap this for production below.dict - the user object holds profile data and stats holds the counters.Most analytics workflows need a user's posts, not just their profile. The /user-posts/ endpoint takes a numeric userid (not a username), so we first resolve the ID with the /userid/ endpoint:
def get_userid(username: str) -> str:
response = requests.get(
f"{BASE_URL}/userid/",
params={"username": username},
headers=HEADERS,
timeout=10,
)
response.raise_for_status()
return response.json()["id"]
def get_posts(userid: str, count: int = 30) -> list:
response = requests.get(
f"{BASE_URL}/user-posts/",
params={"userid": userid, "count": count},
headers=HEADERS,
timeout=15,
)
response.raise_for_status()
return response.json().get("videos", [])
userid = get_userid("tiktok")
videos = get_posts(userid, count=30)
for video in videos[:5]:
print(
f"{video['video_id']} "
f"views={video['play_count']:,} "
f"likes={video['digg_count']:,} "
f"comments={video['comment_count']:,}"
)
The /user-posts/ response returns a top-level videos array. Each video carries metrics as flat play_count, digg_count (likes), comment_count, share_count, and download_count fields - plus music_info, the no-watermark play URL, and the watermarked wmplay URL.
TikLiveAPI returns a cursor field you pass back to walk older posts, and a boolean hasMore that tells you when the end is reached. Here's a generator that yields every post the API will give you:
def all_posts(userid: str, page_size: int = 30):
cursor = "0"
while True:
response = requests.get(
f"{BASE_URL}/user-posts/",
params={"userid": userid, "count": page_size, "cursor": cursor},
headers=HEADERS,
timeout=15,
)
response.raise_for_status()
data = response.json()
for video in data.get("videos", []):
yield video
if not data.get("hasMore"):
return
cursor = data["cursor"]
count = sum(1 for _ in all_posts(userid))
print(f"Fetched {count} videos")
Hitting any social-media API at scale will eventually surface timeouts, transient 5xx errors, and rate limits. A small tenacity-backed wrapper handles all three:
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=1, max=30),
retry=retry_if_exception_type((requests.Timeout, requests.ConnectionError)),
)
def safe_get(path: str, params: dict) -> dict:
response = requests.get(
f"{BASE_URL}{path}",
params=params,
headers=HEADERS,
timeout=10,
)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", "5"))
raise requests.Timeout(f"Rate limited, retry in {retry_after}s")
response.raise_for_status()
return response.json()
Install with pip install tenacity. Exponential backoff with a hard cap on attempts is the gold standard for resilient API clients.
If you need to fetch hundreds of users - say, a daily influencer leaderboard - synchronous requests bottlenecks on network latency. httpx with asyncio can fetch 50-100 users concurrently:
import asyncio
import httpx
async def get_user_async(client: httpx.AsyncClient, username: str) -> dict:
response = await client.get(
"/userinfo-by-username/",
params={"username": username},
)
response.raise_for_status()
return response.json()
async def bulk_fetch(usernames: list) -> list:
limits = httpx.Limits(max_connections=20)
async with httpx.AsyncClient(
base_url=BASE_URL,
headers=HEADERS,
timeout=10,
limits=limits,
) as client:
return await asyncio.gather(
*[get_user_async(client, u) for u in usernames],
return_exceptions=True,
)
profiles = asyncio.run(bulk_fetch(["tiktok", "khaby.lame", "charlidamelio"]))
for profile in profiles:
if isinstance(profile, Exception):
print(f"Error: {profile}")
else:
print(profile["user"]["nickname"], profile["stats"]["followerCount"])
Two production tips:
return_exceptions=True lets one failing user not blow up the whole batch.max_connections below your plan's rate limit - 20 is safe on most tiers.Let's tie everything together. The script below tracks a list of usernames, pulls today's follower count, and appends to a CSV - a primitive but real analytics pipeline you can wire to cron:
import csv
from datetime import date
from pathlib import Path
TRACKED = ["tiktok", "khaby.lame", "charlidamelio", "willsmith"]
OUTPUT = Path("follower_history.csv")
def track_today():
rows = []
for username in TRACKED:
try:
profile = safe_get("/userinfo-by-username/", {"username": username})
stats = profile["stats"]
rows.append({
"date": date.today().isoformat(),
"username": username,
"followers": stats["followerCount"],
"likes": stats["heartCount"],
"video_count": stats["videoCount"],
})
except Exception as exc:
print(f"skip {username}: {exc}")
if not rows:
return
new_file = not OUTPUT.exists()
with OUTPUT.open("a", newline="") as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
if new_file:
writer.writeheader()
writer.writerows(rows)
if __name__ == "__main__":
track_today()
Schedule with cron, systemd timers, or GitHub Actions and you have daily growth data for every account on your list. Plug the CSV into Pandas, Grafana, or a Postgres warehouse and you are running real analytics.
This tutorial focused on user-level data, but TikLiveAPI exposes 37 endpoints across 10 categories. A few you will likely want next:
All of them follow the same pattern: GET request, X-Api-Key header, JSON response. The full reference lives in the documentation.
TikLiveAPI only returns data that is publicly visible on TikTok - the same information any logged-out user can see by visiting a profile. We do not bypass private accounts or login walls. That said, jurisdictions vary and you remain responsible for how you use the data: GDPR, CCPA, and TikTok's own terms of service still apply on your end.
Rate limits are credit-based, not per-second. Each API call costs one credit and your plan determines how many credits you have per month. There is no hard per-second cap, but bursting more than ~50 requests per second from a single key may briefly return 429 - the retry wrapper above handles this automatically.
TikTok itself does not expose historical follower data, so neither does this API. The follower-tracker script above is exactly how you build your own history: capture today's number daily, persist it, plot the delta over time.
No - TikLiveAPI handles all IP rotation, CAPTCHA solving, and session management server-side. Your script just calls api.tikliveapi.com directly with your API key. No residential proxies, no anti-bot infrastructure to maintain.
Yes - it is plain HTTPS+JSON. requests works for simple scripts, httpx handles both sync and async, and aiohttp works too. Pick whatever fits the rest of your stack.
You now have a working Python client for TikTok user data plus the patterns to scale it. Two natural follow-ups:
Building something interesting with TikTok data? We would love to hear about it - reach out on the contact page.
Ready to put what you read into code? Try our endpoints live or grab the full reference.