Take the number after /video/ in a TikTok URL, send it to /v2/tiktok/app/video, and you get the video's post time, stats, length and MP4 links for 2 credits. TikTok's own Display API returns video details only for the videos of users who sign in to your app.
What TikTok's Display API returns
TikTok's Display API has three calls: user info, video list and video query. They read the videos of users who sign in to your app, and /v2/video/query/ returns that user's videos filtered by ID.
What one call returns
One call returns a video's author, post time, stats, length and playback links. We make ToolzerHub. Our TikTok API reads public TikTok data with one API key. /v2/tiktok/app/video takes aweme_id, the video ID, and costs 2 credits.
curl "https://api.toolzerhub.com/v2/tiktok/app/video?aweme_id=7701302261489700148" \
-H "x-api-key: $TOOLZERHUB_API_KEY"
One video, trimmed:
{
"data": {
"aweme_detail": {
"aweme_id": "7701302261489700148",
"desc": "Funny,raw,unfiltered…😅Updated skincare routine🫶 telling you ",
"create_time": 1793099174,
"author": {
"unique_id": "_d_vine"
},
"statistics": {
"play_count": 871810,
"digg_count": 165685,
"comment_count": 747,
"share_count": 913,
"collect_count": 10706
},
"video": {
"duration": 488934,
"width": 576,
"height": 1024,
"play_addr": {
"url_list": [
"https://v19.tiktokcdn-us.com/5beeca2d4510dcc391ceaf9e958fa51..."
]
}
}
}
}
}
create_time is a Unix timestamp, video.duration is in milliseconds and digg_count is likes. The link in play_addr served the MP4 itself: 28.8 MB for this 8-minute video. If you only need plays, likes, comments and shares, /v1/tiktok/video returns them for 1 credit from the author's username and the video_id, without the post time or file links.
Get many videos to CSV
The script takes tiktok.com/@user/video/<id> URLs or bare IDs, pulls the ID out of each, and writes one row per video with the post time, length and stats.
import csv
import os
import re
import sys
import time
from datetime import datetime, timezone
import requests
API = "https://api.toolzerhub.com/v2/tiktok/app/video"
HEADERS = {"x-api-key": os.environ.get("TOOLZERHUB_API_KEY", "")}
FIELDS = ["video_id", "author", "posted", "seconds", "plays", "likes", "comments", "shares",
"saves", "description", "url"]
def cell(value):
# A leading = + - or @ would run as a formula when the CSV opens in a spreadsheet.
return "'" + value if isinstance(value, str) and value[:1] in ("=", "+", "-", "@") else value
def get(video_id, tries=4):
# 429 and 503 are worth a retry; the body or the Retry-After header says how long to wait.
for attempt in range(tries):
r = requests.get(API, params={"aweme_id": video_id}, headers=HEADERS, timeout=120)
if r.status_code in (429, 503) and attempt < tries - 1:
wait = int(((r.json().get("error") or {}).get("details") or {}).get("retryAfter") or r.headers.get("Retry-After") or 5 * (attempt + 1))
time.sleep(min(wait, 60))
continue
r.raise_for_status()
return (r.json().get("data") or {}).get("aweme_detail")
def row(v):
stats, author = v.get("statistics") or {}, v.get("author") or {}
posted = v.get("create_time")
return {
"video_id": v["aweme_id"], "author": author.get("unique_id"),
"posted": datetime.fromtimestamp(posted, timezone.utc).isoformat() if posted else "",
"seconds": round((v.get("video") or {}).get("duration", 0) / 1000, 1),
"plays": stats.get("play_count"), "likes": stats.get("digg_count"),
"comments": stats.get("comment_count"), "shares": stats.get("share_count"),
"saves": stats.get("collect_count"),
"description": cell((v.get("desc") or "").replace("\n", " ")),
"url": f"https://www.tiktok.com/@{author.get('unique_id')}/video/{v['aweme_id']}",
}
def main(links, out="tiktok_videos.csv"):
# A video ID is the number after /video/ in the URL; a bare ID works too.
ids = [m.group(1) for s in links.split(",")
if (m := re.search(r"/video/(\d+)", s) or re.fullmatch(r"\s*(\d{15,25})\s*", s))]
if not ids:
sys.exit("no video ID found: pass tiktok.com/@user/video/<id> URLs or the IDs themselves")
saved = 0
with open(out, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=FIELDS)
writer.writeheader()
for video_id in ids:
v = get(video_id)
if not v:
print(video_id, "-> not available")
continue
writer.writerow(row(v))
saved += 1
print(video_id, "->", (v.get("statistics") or {}).get("play_count"), "plays")
print(f"saved {saved} of {len(ids)} videos to {out}")
if __name__ == "__main__":
if not HEADERS["x-api-key"] or len(sys.argv) < 2:
sys.exit("usage: TOOLZERHUB_API_KEY=... python tiktok_videos.py URL_OR_ID[,URL_OR_ID] [file.csv]")
main(*sys.argv[1:])
export TOOLZERHUB_API_KEY=your_key
python tiktok_videos.py "https://www.tiktok.com/@musiced13/video/7701640406185889046,https://www.tiktok.com/@codingwithalexz/video/7691531865009704223,https://www.tiktok.com/@foodreviewclub/video/7702446687217798422,https://www.tiktok.com/@jessreadsalott/video/7702389725012790548,https://www.tiktok.com/@alexaaliftss/video/7666151163787611406,7700297051380174093"
7701640406185889046 -> 628073 plays
7691531865009704223 -> 3451 plays
7702446687217798422 -> 88895 plays
7702389725012790548 -> 10505 plays
7666151163787611406 -> 8336 plays
7700297051380174093 -> 3531735 plays
saved 6 of 6 videos to tiktok_videos.csv
What came out
Six videos took 12 seconds, and all six came back.
| Author | Length (s) | Plays | Likes | Comments | Saves |
|---|---|---|---|---|---|
| musiced13 | 60.3 | 628,073 | 84,393 | 446 | 5,022 |
| codingwithalexz | 33.4 | 3,451 | 213 | 5 | 202 |
| foodreviewclub | 178.2 | 88,895 | 3,152 | 108 | 533 |
| jessreadsalott | 78.4 | 10,505 | 1,665 | 2 | 103 |
| alexaaliftss | 27.1 | 8,336 | 1,080 | 3 | 173 |
| brothers.cucina | 19.0 | 3,531,735 | 184,724 | 1,891 | 25,423 |
Counts change between reads, so store the read time next to them.
What it costs
Each video is 2 credits, so the run above cost 12 credits and 1,000 videos cost 2,000. You get 100 free credits a month; $19 buys 10,000 credits that never expire, and plans for higher volume cover longer lists. Set your key and your first video is a CSV row in seconds.
To list one account's videos, see TikTok API get user videos; for the comments under a video, see TikTok API get comments. For the creator's exact followers and likes, see the TikTok user info API.
We are not affiliated with TikTok or ByteDance.