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. For deeper coverage of backoff, queues, and credit budgeting, see our guide to building resilient pipelines around TikTok API rate limits.
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:
Working in another stack? The same auth, pagination, and retry patterns are covered in our PHP scraping tutorial and its Node.js counterpart.
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.