SFOLN

Catalogue / Social media data

TikTok User Videos Scraper

sfoln/tiktok-user-videos · Social media, Videos, Automation On request

Scrape the videos of public TikTok profiles, latest or most popular first: caption, date, duration, plays, likes, comments, shares, saves, music and hashtags, one JSON record per video. $0.40 per 1,000 videos + $0.003 per page. Up to 300 videos per profile; no login needed.

About

What it does

TikTok User Videos Scraper lists the videos of public TikTok profiles with one normalized record per video: video ID, URL, caption, creation date, duration, plays, likes, comments, shares, saves, cover image, music, hashtags, mentions and pinned / ad flags. Sort by latest or most popular. It's built for creator analytics, influencer vetting, campaign tracking, trend research and AI agents.

Price

Price per delivered record

EventPricePer 1,000Charged for
TikTok video
tiktok-video
$0.0004$0.40 / 1,000Charged once per TikTok video delivered as a dataset record. User summary records are never charged.
TikTok videos page
tiktok-videos-query
$0.003$3 / 1,000Charged once per page of a user's videos that delivered at least one video, or that the provider billed although it had no new videos (e.g. a private or empty profile). Covers the per-request upstream fee.

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~tiktok-user-videos/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"handles":["khaby.lame"],"maxVideosPerUser":10}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/tiktok-user-videos"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~tiktok-user-videos/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: List the 30 most popular TikTok videos of @khaby.lame with their plays, likes and posting dates.

Input

Input fields

Paste TikTok handles or profile URLs. Each profile produces one dataset record per video plus one summary record per profile.

FieldTypeDefaultMeaning
handles *arrayrequiredTikTok profiles
Handles (with or without @) or profile URLs such as https://www.tiktok.com/@khaby.lame. Duplicates are removed. Accounts on the Apify free plan can process up to 10 profiles per run.
maxVideosPerUserinteger30Max videos per profile
How many videos to return per profile (1–300). Each delivered video is one charged event, plus one page event per page fetched. Range 1–300.
sortBystring"latest"Sort order
latest = newest videos first; popular = most played first. One of "latest", "popular".
regionstring—Region
Optional 2-letter country code used to read the feed (default US). Try the creator's country if a profile that should have videos returns none.
maxUsersinteger100Max profiles
Safety cap on the number of profiles processed in this run. Range 1–1000.
concurrencyinteger4Concurrency
How many profiles are fetched in parallel (1–8). Range 1–8.
itemTimeoutSecsinteger900Time limit per input (seconds)
Pagination for one profile stops cleanly shortly before this limit (60–3600). Raise it for very large per-input limits. Range 60–3600.
includeRawbooleanfalseInclude raw upstream response
Attach the unmodified provider video object to each video record (very large output).
Example input
{
  "handles": [
    "khaby.lame"
  ],
  "maxVideosPerUser": 10
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The handle or profile URL as provided.
recordTypestringRecord type
video (one per delivered video, charged) | user (one summary per profile, never charged) e.g. "video"
handlestring | nullHandle
positionintegerPosition
videoIdstring | nullVideo ID
urlstring | nullURL
descriptionstring | nullCaption
createdAtstring | nullCreated at
ISO 8601 UTC
durationSecsnumber | nullDuration (s)
playsnumber | nullPlays
likesnumber | nullLikes
commentsnumber | nullComments
sharesnumber | nullShares
savesnumber | nullSaves
coverUrlstring | nullCover URL
musicTitlestring | nullMusic title
musicAuthorstring | nullMusic author
hashtagsarrayHashtags
mentionsarrayMentions
isPinnedboolean | nullPinned
isAdboolean | nullAd
isPaidPartnershipboolean | nullPaid partnership
regionstring | nullRegion
authorHandlestring | nullAuthor handle
authorIdstring | nullAuthor ID
profileUrlstringProfile URL
user records only.
sortBystringSort
user records only.
videosDeliveredintegerVideos delivered
user records only.
pagesFetchedintegerPages fetched
user records only.
pagesChargedintegerPages charged
user records only.
reachedEndbooleanReached end
user records only.
stopReasonstringStop reason
user records only.
statusstringStatus
ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan e.g. "ok"
chargedbooleanCharged
Video records: charged tiktok-video. user summary records are never charged themselves: the tiktok-videos-query page fees charged for the input (including empty pages the provider billed) are counted in pagesCharged.
chargedEventstringCharged event
errorobjectError
warningsarrayWarnings
sourcestringSource
fetchedAtstringFetched at
Example record
{
  "input": "stoolpresidente",
  "recordType": "video",
  "handle": "stoolpresidente",
  "position": 1,
  "videoId": "7517114944362499342",
  "url": "https://www.tiktok.com/@stoolpresidente/video/7517114944362499342",
  "description": "You can say whatever you want about the WNBA is but it's never boring",
  "createdAt": "2025-06-18T02:45:25.000Z",
  "durationSecs": 174,
  "plays": 559925,
  "likes": 59605,
  "comments": 587,
  "shares": 3424,
  "saves": 1565,
  "coverUrl": "https://p19-sign.tiktokcdn-us.com/…heic",
  "musicTitle": "original sound - stoolpresidente",
  "musicAuthor": "Dave Portnoy",
  "hashtags": [],
  "mentions": [],
  "isPinned": false,
  "isAd": false,
  "isPaidPartnership": false,
  "region": "US",
  "authorHandle": "stoolpresidente",
  "authorId": "6659752019493208069",
  "status": "ok",
  "charged": true,
  "chargedEvent": "tiktok-video",
  "source": "scrapecreators",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}

Machine-readable

This page for agents