To tell whether a particular TikTok video is gaining traction, compare its public metrics with its own previous snapshot. A one-time search shows views and reactions accumulated so far; collecting the same discovered videos again reveals the change between runs. Here’s a minimal, working Python pipeline: query search, save metrics to CSV, and calculate the delta.
What does this monitoring measure?
This script is suitable for a marketer, analyst, or developer who needs a list of videos found on a topic and a verifiable observation history. For example, a team might regularly track videos about a product launch or a specific audience query and see which videos gained views, likes, comments, or shares since the previous check.

The key unit of comparison is a video identified by aweme_id. Each record stores the collection time, ID, description, URL, author name, and any available counters. The two snapshots are then matched by ID, so the increase in views for one video isn’t mixed up with the accumulated views of another.
The results describe only videos returned by a particular search query on a particular run. Search results may change, and some statistics fields may be absent. It’s therefore useful to retain the snapshots themselves and their collection times, and to treat the report as observations of videos already found—not as a complete catalog of posts on the topic.
How does collection through the API work?
The TikTok Scraper API documentation describes the GET route /searchVideo. The required search parameter is the keyword string; additional parameters include count, region, sort_by, and date_posted. Pass the API key as license_key. The reference lists https://tiktok.evelode.com as the base endpoint.
The response contains an outer status and a tiktok object. Search results may contain videos in tiktok.aweme_list or inside tiktok.search_item_list[].aweme_info. The handler below supports both formats. Metrics come from statistics, including play_count, digg_count, comment_count, and share_count; missing values are stored as blank rather than replaced with zero.
The endpoint reference lists cursor for paging through search results and specifies the allowed options for date_posted and sort_by. For simple, repeatable monitoring, start by fetching one results page and recording the response; add pagination only if needed. If you do need it, pass the returned cursor without modifying it.
Working example in Python
Install the Requests library with python -m pip install requests and set the key in the JSONSCRAPER_TIKTOK_LICENSE_KEY environment variable. The script accepts a search phrase as an argument and appends the snapshots it finds to a single CSV file. The code is compatible with Python 3.8+.
import csv
import os
import sys
from datetime import datetime, timezone
from pathlib import Path
import requests
BASE_URL = "https://tiktok.evelode.com/searchVideo"
CSV_PATH = Path("tiktok_video_snapshots.csv")
FIELDS = [
"collected_at", "aweme_id", "author", "description", "share_url",
"play_count", "digg_count", "comment_count", "share_count",
]
def extract_items(payload):
"""Support the observed search response layouts."""
data = payload.get("tiktok") or {}
items = data.get("aweme_list") or []
if items:
return items
found = []
for result in data.get("search_item_list") or []:
info = result.get("aweme_info")
if info:
found.append(info)
return found
def main():
key = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")
if not key:
raise SystemExit("Set JSONSCRAPER_TIKTOK_LICENSE_KEY first")
if len(sys.argv) < 2:
raise SystemExit('Usage: python collect.py "search phrase"')
params = {
"license_key": key,
"keyword": sys.argv[1],
"count": 20,
"region": "US",
"sort_by": "relevance",
"date_posted": "this-week",
}
response = requests.get(BASE_URL, params=params, timeout=30)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("API returned a non-ok outer status")
data = payload.get("tiktok") or {}
items = extract_items(payload)
collected_at = datetime.now(timezone.utc).isoformat()
rows = []
for item in items:
stats = item.get("statistics") or {}
author = item.get("author") or {}
rows.append({
"collected_at": collected_at,
"aweme_id": item.get("aweme_id"),
"author": author.get("unique_id") or author.get("nickname"),
"description": item.get("desc"),
"share_url": item.get("share_url"),
"play_count": stats.get("play_count"),
"digg_count": stats.get("digg_count"),
"comment_count": stats.get("comment_count"),
"share_count": stats.get("share_count"),
})
write_header = not CSV_PATH.exists()
with CSV_PATH.open("a", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=FIELDS)
if write_header:
writer.writeheader()
writer.writerows(rows)
print("Saved", len(rows), "returned videos")
print("has_more:", data.get("has_more"), "cursor:", data.get("cursor"))
if __name__ == "__main__":
main()
For example, run python collect.py "product-related query". The library adds the key to the URL parameters; the script doesn’t print it in the terminal. Don’t save the full request URL in publicly accessible logs, since it contains the key. For production systems, use a secrets manager and restrict access to the snapshot file.
How do you calculate growth between runs?
The script deliberately writes every observation rather than overwriting previous values. The following small analyzer matches the latest pair of snapshots for each video and prints the difference in the counters. If a metric has no value in either record, the result is marked as unavailable.

import csv
from collections import defaultdict
from pathlib import Path
rows_by_video = defaultdict(list)
with Path("tiktok_video_snapshots.csv").open(encoding="utf-8", newline="") as file:
for row in csv.DictReader(file):
if row["aweme_id"]:
rows_by_video[row["aweme_id"]].append(row)
metrics = ("play_count", "digg_count", "comment_count", "share_count")
for video_id, snapshots in rows_by_video.items():
snapshots.sort(key=lambda row: row["collected_at"])
if len(snapshots) < 2:
continue
previous, latest = snapshots[-2], snapshots[-1]
changes = {}
for metric in metrics:
old, new = previous[metric], latest[metric]
changes[metric] = int(new) - int(old) if old and new else None
print(video_id, changes, latest["share_url"])
The delta is the difference between two saved values, not a growth rate measured at a guaranteed interval. If runs happen at different intervals, calculate the elapsed time between collected_at values and compare growth over the actual period. Counters can change between observations; the saved timestamps show exactly when the values used were obtained.
How do you automate and interpret the report?
For a daily report, schedule the collection on a server or in CI, set a fixed list of search phrases, and save the CSV or load its rows into a database. On repeat runs, deduplicate records within each snapshot by aweme_id if the results contain duplicates. For historical records, store the original JSON alongside normalized columns; this makes it easier to reprocess data if the report schema changes.
A useful table displays the video ID and URL, author, description, collection time, and deltas for individual metrics. Sorting by view growth answers a question about reach, while growth in comments or shares can highlight a different kind of response. Don’t combine these measures into a single score without an explicit rule: each counter has its own meaning.
A scheduler can send the report by email, to a spreadsheet, or to an internal channel, but that step is handled by your infrastructure—the example above only collects and analyzes the data. For more complete collection, you can page through the results, save the cursor, and stop when the API indicates there are no more pages. The search cursor is an opaque value in the response; don’t calculate it yourself. Even paging through results describes the returned data and doesn’t guarantee a comprehensive list of all matching posts.
The expected practical result is a reproducible observation log and a table of changes for the videos found. This helps identify which posts changed their public counters between checks and gives a specialist specific links to review in context. Product details and API access are available on the TikTok Scraper API page.
What should you check before scheduling a run?
- Make sure the outer response status is
okbefore processingtiktok. - Check both search-item formats; if no list is present, the collection should return no results rather than fail.
- Save original values and timestamps. A missing metric should remain missing.
- Use the same queries and parameters to make snapshot comparisons easier to interpret; record any configuration changes alongside the report.
- Monitor run frequency, HTTP errors, and history size, and comply with applicable platform rules and data-processing requirements.
In short, to observe results, repeat the same search, identify videos by aweme_id, and compare saved metrics over time. This approach answers a narrow, practical question—which of the videos already found changed their public counters between two checks—while keeping the original data available for auditing and further processing.