Back to Blog

Track TikTok Follower Growth with Profile Snapshots

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

02-Sep-2026

TL;DR:

  • TikTok follower growth tracking starts when collection starts. The profile actor returns a current public count, not a historical series.
  • Every observation needs a collection status. A failed collection and an unchanged follower count are different outcomes.
  • Account identity should survive handle changes. Store account_id, sec_uid, and the observed unique_id together.
  • Growth is a difference between comparable snapshots. Subtract consecutive valid counts for the same account and keep both timestamps.
  • Follower growth does not identify its cause. A change cannot be attributed to one video or campaign without separate evidence.
  • Free to start. New Scrapeless accounts include free credit through the Scrapeless Dashboard.

Introduction: a profile count becomes useful after the second observation

A public follower count is a snapshot. It becomes a growth record only after the same account is collected again and the two valid observations are compared.

This tutorial builds a small TikTok follower growth tracking pipeline with the Scrapeless profile actor, Python, and SQLite. It preserves account identifiers, saves successful and failed collection states separately, calculates changes from consecutive valid snapshots, and produces rows for a creator growth dashboard.

The underlying profile fields and identity keys are covered in the TikTok profile scraper tutorial.

Pipeline at a Glance

Stage Action Durable output
Define Supply the accounts to track Account roster
Collect Request each current public profile Raw JSON or error record
Normalize Extract identity and statistics Profile snapshot row
Compare Join consecutive successful snapshots Follower-change row
Report Plot levels and changes Growth dashboard input

The pipeline creates history from the day it begins collecting. It does not reconstruct follower counts from dates before the first stored observation.

Prerequisites

  • A Scrapeless account and API token from the Scrapeless Dashboard
  • A user-maintained list of public TikTok usernames
  • A collection schedule appropriate for the reporting need
  • A live token in SCRAPELESS_API_KEY for the API block below

The complete example has a prerequisite gap because the reader must supply a live credential and account roster. The article does not embed credentials or present fabricated profile responses.

Stage 1: Define the Account Roster

A roster should contain a stable internal key, the current username, the business reason for tracking it, and whether the record remains active. Usernames are convenient request inputs, but they should not become the only database key.

The scraper.tiktok.user.detail actor accepts unique_id without the leading @. Its response can include account_id, unique_id, sec_uid, public profile fields, account flags, and a statistics object containing follower, following, friend, like, video, and liked-video counts.

Keep numeric-looking account IDs as strings. Preserve all three identifiers so a later handle change does not silently create a new history series.

Stage 2: Capture a Timestamped Profile Snapshot

Every collection attempt needs an application timestamp and a status. A successful row stores the returned identifiers and statistics. A failed attempt stores the account key, attempted time, and a concise error state without copying missing counts as zero.

Python's datetime documentation describes timezone-aware timestamps. Use one timezone standard in storage and apply display time zones only in the reporting layer.

TikTok's official user information documentation also treats user fields as a current response rather than an account-history feed. The Scrapeless pipeline therefore builds its own observation history.

Start Scraping with Scrapeless

Power up your web scraping and automation workflow with Scrapeless!
Sign up today and get $5 in free creditno credit card required.

Claim your free credit now in the Scrapeless Dashboard.

Stage 3: Store Success and Collection Gaps Separately

SQLite supports a compact append-only snapshot table. The SQLite table-constraint documentation explains the composite key used to prevent duplicate observations.

Note: The code below requires a live Scrapeless API token in SCRAPELESS_API_KEY and comma-separated public usernames in TIKTOK_USERNAMES.

python Copy
import json
import os
import sqlite3
from datetime import datetime, timezone
from urllib.error import HTTPError
from urllib.request import Request, urlopen

ENDPOINT = "https://api.scrapeless.com/api/v1/scraper/request"
TOKEN = os.environ["SCRAPELESS_API_KEY"]
USERNAMES = [v.strip().lstrip("@") for v in os.environ["TIKTOK_USERNAMES"].split(",") if v.strip()]


def get_profile(username):
    body = json.dumps({
        "actor": "scraper.tiktok.user.detail",
        "input": {"unique_id": username},
    }).encode()
    request = Request(
        ENDPOINT,
        data=body,
        headers={"x-api-token": TOKEN, "content-type": "application/json"},
        method="POST",
    )
    with urlopen(request, timeout=60) as response:
        return json.load(response)


database = sqlite3.connect("tiktok-profile-history.sqlite3")
database.execute("""
CREATE TABLE IF NOT EXISTS profile_snapshots (
    roster_username TEXT NOT NULL,
    collected_at TEXT NOT NULL,
    collection_status TEXT NOT NULL,
    account_id TEXT,
    unique_id TEXT,
    sec_uid TEXT,
    followers INTEGER,
    following INTEGER,
    likes INTEGER,
    videos INTEGER,
    error_code TEXT,
    raw_json TEXT,
    PRIMARY KEY (roster_username, collected_at)
)
""")

for username in USERNAMES:
    collected_at = datetime.now(timezone.utc).isoformat()
    try:
        profile = get_profile(username)
        statistics = profile.get("statistics") or {}
        database.execute(
            "INSERT INTO profile_snapshots VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
            (
                username, collected_at, "success",
                str(profile.get("account_id") or ""), profile.get("unique_id"),
                profile.get("sec_uid"), statistics.get("followers"),
                statistics.get("following"), statistics.get("likes"),
                statistics.get("videos"), None,
                json.dumps(profile, ensure_ascii=False),
            ),
        )
    except HTTPError as error:
        database.execute(
            "INSERT INTO profile_snapshots VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
            (username, collected_at, "failed", None, None, None, None, None, None, None,
             str(error.code), None),
        )

database.commit()
database.close()

The collection_status column keeps a gap visible. It prevents a reporting query from treating an unavailable observation as no follower change.

Stage 4: Calculate Growth From Consecutive Valid Snapshots

Follower growth is the later valid count minus the earlier valid count for the same account_id. Keep the start and end timestamps, both source counts, the difference, and the elapsed duration.

Use account identity before username when joining. If an observed username changes while account_id remains stable, keep one series and retain the handle recorded on each snapshot. If identity fields conflict, stop the join and send the row for review.

SQL window functions can pair successful rows without overwriting the original observations:

sql Copy
SELECT
  account_id,
  unique_id,
  collected_at,
  followers,
  followers - LAG(followers) OVER (
    PARTITION BY account_id ORDER BY collected_at
  ) AS follower_change
FROM profile_snapshots
WHERE collection_status = 'success' AND followers IS NOT NULL;

The result measures change between stored observations. It is not a daily growth rate unless the observations are separated by the exact interval the report labels.

Stage 5: Build the Creator Growth Dashboard

A useful dashboard shows data quality beside growth:

  • Latest valid follower count and its collection time
  • Change since the previous valid snapshot
  • Change across a clearly labeled reporting interval
  • Number of successful observations and collection gaps
  • Current observed username plus stable account ID
  • First stored observation date, which defines the history boundary

Plot follower level and follower change separately. A level chart shows the accumulated series; a change chart makes collection gaps and sudden differences easier to review.

Handle Profile Data Responsibly

Public profile statistics can still be personal data. Limit the account roster to the stated purpose, restrict raw-response access, and define when old snapshots should be removed. The NIST Privacy Framework provides a structure for identifying and managing collection risk.

Do not infer audience demographics, follower identities, or the cause of growth from the profile response. A count change can coincide with a campaign or post, but coincidence is not attribution.

Scrapeless exposes the profile actor through Scraping API. Check the current pricing page before setting the account count and schedule.

Conclusion: history begins with a recorded baseline

TikTok follower growth tracking needs a stable account identity, timestamped valid counts, and explicit collection gaps. Once the baseline exists, consecutive snapshots can support a growth curve without claiming unavailable platform history or assigning the change to one piece of content.

Ready to Build a Profile Statistics Tracker?

Join the Scrapeless Discord or Telegram community to compare snapshot schemas. Create an account in the Scrapeless Dashboard when the account roster is ready.

FAQ

Q: Can a TikTok follower tracker recover historical counts?

The workflow cannot recover counts from before collection began. Its first successful observation becomes the baseline for later comparisons.

Q: What is the difference between no growth and a collection failure?

No growth means two valid snapshots contain the same follower count. A collection failure means the later count is unknown and no difference should be calculated.

Q: Can follower growth be attributed to one TikTok video?

Follower growth cannot be attributed to one video from profile snapshots alone. Attribution requires a separate experiment or first-party campaign evidence.

Q: Does the workflow expose follower identities or demographics?

The profile actor returns public account statistics, not follower lists or audience demographics.

Q: Do I need to manage a proxy or profile-page parser?

The actor handles its collection surface behind the API request. The caller manages the roster, schedule, storage, comparisons, and reporting.

Q: Is collecting public follower counts legal?

Legality depends on jurisdiction, purpose, access method, data, and applicable terms. Minimize collection, document the purpose, and obtain legal advice for the specific use.

At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.

Most Popular Articles

Catalogue