Scrape TikTok without login: videos from hashtags, sounds, profiles and video links, with views, likes, comments, shares, saves, author follower counts, music and hashtags as flat columns. Add each video's comments, filter by date, or get only new videos on a schedule.
Versions follow MAJOR.MINOR.PATCH (src/version.py); Apify shows MAJOR.MINOR from .actor/actor.json.
Every run logs its version and records it in the RUN_STATS key-value record.
0.1.2 (2026-10-20)
A profile's list of latest videos (its embed page) is retried when TikTok answers "too many requests" (HTTP 429),
as every other page already was. Before, one 429 there ended the profile with no videos.
No change to output fields or price.
0.1.1 (2026-10-16)
A run that returns nothing (every input bad, private, blocked or unreachable, or an empty input) now ends
SUCCEEDED with an empty dataset and the reason as its status message and in the log, instead of FAILED. Only an
unexpected error still fails the run. RUN_STATS keeps the reason as before.
No change to output fields or price.
0.1.0 (2026-10-14)
First release.
Videos from hashtags (TikTok's own hashtag page, read in a headless browser because its list needs the page's
request signing), sounds (the same way), profiles (the ~10 latest from the profile's embed card, each video page
read in full) and video or photo links (short links resolved), as one flat row per video.
Comments per video and replies per comment as rows of their own, tied to the video by videoId.
Optional profile rows with exact follower, following, like and video counts.
Free filters: only videos newer than a date or age (profile videos skipped by the upload time in their id, before
fetching), and only new since the last run (per hashtag, sound, profile and video, remembered 120 days).
Charged per row through two events: video (videos and profile rows) and comment (comments and replies); the
dataset item event is unpriced, so a row is charged once. "Max results per run" and the maximum cost per run are
honoured across both, before the work.
Failure isolation: a failing source, video page or comment thread only affects itself; every source's outcome
(returned, skipped by filters, why a list ended, TikTok's reason for a failure) is in RUN_STATS.
Sources and terms (ACTOR-CHECKLIST 0 and 6): TikTok publishes no API for this; the actor reads tiktok.com's own
public pages and the requests they make (/@user, /embed/@user, /@user/video/<id>, /tag/<name>,
/music/<name>-<id>, /api/comment/list/, /api/comment/list/reply/, and in the browser /api/challenge/item_list/
and /api/music/item_list/). robots.txt (read 2026-10-14) allows /tag and /music for every crawler and disallows
/embed/@, /search? and some APIs; TikTok's Terms of Service (https://www.tiktok.com/legal/page/us/terms-of-service/en ,
read 2026-10-14) apply to visitors without an account (§3.2) and forbid extracting data by automated means without
written approval (§3.4). Read anyway under Michael's platform exception (PLAN.md "Exclusions lifted", 2026-10-14):
logged out only, no accounts or cookies of anyone's, polite pace, takedown on request; the README says so.