How to Scrape TikTok Channel Videos in 2026 using SocialKit API
Want to get a list of all videos from a TikTok profile programmatically? Whether you're building a competitor analysis tool, influencer vetting dashboard, or content monitoring system, pulling channel video data is something that keeps coming up.
The problem is that TikTok's video list is loaded dynamically using browser session tokens. A plain HTTP request to their internal API returns an empty body. You need a real browser to get the data, which makes rolling your own scraper painful to maintain.
This guide covers the straightforward way to do it using the TikTok Channel Videos API — one request, clean JSON back.
What You Get Back
Each video in the response includes:
- Video ID and direct TikTok URL
- Caption/description (up to 300 characters)
- Thumbnail image URL
- Duration in seconds
- Publish date (ISO 8601)
- Views, likes, comments, shares, and saves
The Endpoint
https://api.socialkit.dev/tiktok/channel-videos
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | TikTok profile URL, e.g. https://tiktok.com/@username |
access_key | string | Yes | Your API access key |
limit | number | No | Videos to return (default 30, max 100) |
cursor | string | No | Pagination cursor from a previous response |
Example Request
GET https://api.socialkit.dev/tiktok/channel-videos?access_key=<your-key>&url=https://www.tiktok.com/@khaby.lame&limit=30
Example Response
{
"success": true,
"data": {
"type": "tiktok_channel_videos",
"url": "https://www.tiktok.com/@khaby.lame",
"channelName": "khaby.lame",
"results": [
{
"videoId": "7312345678901234567",
"description": "Simplicity is the key 🔑 #learnfromkhaby #comedy",
"url": "https://www.tiktok.com/@khaby.lame/video/7312345678901234567",
"thumbnail": "https://p16-sign.tiktokcdn-us.com/...",
"duration": 14,
"createTime": "2026-06-10T12:34:56.000Z",
"views": 12500000,
"likes": 1430000,
"comments": 8200,
"shares": 45000,
"collects": 62000
}
],
"hasMore": true,
"cursor": "1749556496000"
}
}
Code Examples
JavaScript / Node.js
const axios = require('axios');
async function getTikTokChannelVideos(profileUrl, accessKey, limit = 30) {
const response = await axios.get('https://api.socialkit.dev/tiktok/channel-videos', {
params: { access_key: accessKey, url: profileUrl, limit }
});
return response.data;
}
// Basic usage
const data = await getTikTokChannelVideos('https://tiktok.com/@khaby.lame', 'your-key', 50);
console.log(`Got ${data.data.results.length} videos from @${data.data.channelName}`);
data.data.results.forEach(video => {
console.log(`${video.description.slice(0, 60)}...`);
console.log(` Views: ${video.views.toLocaleString()} | Likes: ${video.likes.toLocaleString()}`);
});
Python
import requests
def get_tiktok_channel_videos(profile_url, access_key, limit=30, cursor=None):
params = {
'access_key': access_key,
'url': profile_url,
'limit': limit,
}
if cursor:
params['cursor'] = cursor
response = requests.get('https://api.socialkit.dev/tiktok/channel-videos', params=params)
response.raise_for_status()
return response.json()
# Basic usage
data = get_tiktok_channel_videos('https://tiktok.com/@khaby.lame', 'your-key', limit=50)
for video in data['data']['results']:
print(f"{video['description'][:60]}...")
print(f" Views: {video['views']:,} | Likes: {video['likes']:,}")
PHP
<?php
function getTikTokChannelVideos($profileUrl, $accessKey, $limit = 30, $cursor = null) {
$params = [
'access_key' => $accessKey,
'url' => $profileUrl,
'limit' => $limit,
];
if ($cursor) {
$params['cursor'] = $cursor;
}
$url = 'https://api.socialkit.dev/tiktok/channel-videos?' . http_build_query($params);
$response = file_get_contents($url);
return json_decode($response, true);
}
$data = getTikTokChannelVideos('https://tiktok.com/@khaby.lame', 'your-key', 30);
foreach ($data['data']['results'] as $video) {
echo substr($video['description'], 0, 60) . "...\n";
echo " Views: " . number_format($video['views']) . "\n\n";
}
cURL
curl -X GET "https://api.socialkit.dev/tiktok/channel-videos?access_key=your-key&url=https://tiktok.com/@khaby.lame&limit=30"
Paginating Through a Full Channel
When hasMore is true in the response, there are more videos to fetch. Pass the cursor value from the response to get the next page.
async function getAllChannelVideos(profileUrl, accessKey, maxVideos = 200) {
let allVideos = [];
let cursor = null;
do {
const params = {
access_key: accessKey,
url: profileUrl,
limit: 100,
};
if (cursor) params.cursor = cursor;
const res = await axios.get('https://api.socialkit.dev/tiktok/channel-videos', { params });
const { results, hasMore, cursor: nextCursor } = res.data.data;
allVideos.push(...results);
cursor = hasMore ? nextCursor : null;
} while (cursor && allVideos.length < maxVideos);
return allVideos.slice(0, maxVideos);
}
Same thing in Python:
def get_all_channel_videos(profile_url, access_key, max_videos=200):
all_videos = []
cursor = None
while len(all_videos) < max_videos:
data = get_tiktok_channel_videos(profile_url, access_key, limit=100, cursor=cursor)
results = data['data']['results']
all_videos.extend(results)
if not data['data']['hasMore']:
break
cursor = data['data']['cursor']
return all_videos[:max_videos]
Real Use Cases
Find a Channel's Top Videos by Views
async function getTopVideos(profileUrl, accessKey, topN = 10) {
const data = await getTikTokChannelVideos(profileUrl, accessKey, 100);
return data.data.results
.sort((a, b) => b.views - a.views)
.slice(0, topN);
}
Monitor for New Uploads
Poll a channel on a schedule and compare video IDs against your stored list to detect new uploads.
import json
from datetime import datetime
def check_for_new_videos(profile_url, access_key, known_ids_file):
with open(known_ids_file) as f:
known_ids = set(json.load(f))
data = get_tiktok_channel_videos(profile_url, access_key, limit=30)
current_videos = data['data']['results']
new_videos = [v for v in current_videos if v['videoId'] not in known_ids]
if new_videos:
print(f"Found {len(new_videos)} new video(s)!")
for v in new_videos:
print(f" - {v['description'][:60]}...")
# Update known IDs
all_ids = known_ids | {v['videoId'] for v in current_videos}
with open(known_ids_file, 'w') as f:
json.dump(list(all_ids), f)
return new_videos
Calculate Average Engagement Rate
function calcEngagementRate(videos) {
if (!videos.length) return 0;
const total = videos.reduce((sum, v) => sum + v.likes + v.comments + v.shares, 0);
const totalViews = videos.reduce((sum, v) => sum + v.views, 0);
return totalViews > 0 ? ((total / totalViews) * 100).toFixed(2) : 0;
}
const data = await getTikTokChannelVideos('https://tiktok.com/@mkbhd', 'your-key', 50);
const rate = calcEngagementRate(data.data.results);
console.log(`Average engagement rate: ${rate}%`);
Why Not Roll Your Own Scraper?
TikTok's video list page requires a real browser session to load the video data. Their internal item_list API silently returns an empty body for unauthenticated direct HTTP requests. To get around this you need:
- Puppeteer or Playwright running in a headless browser
- Working around bot detection (residential proxies, stealth plugins, etc.)
- Network interception to catch the internal API responses
- Constant maintenance as TikTok changes their anti-bot logic
It's doable, but it breaks every few weeks. The API just handles it.
Pricing
Each API request costs 1 credit. Plans start at 20 free credits, with paid plans from $14/month.
- Free: 20 credits
- Starter: $19/month (4,000 credits)
- Standard: $29/month (12,000 credits)
- Ultimate: $95/month (50,000 credits)
- Enterprise and higher plans are also available
We also support Pay As You Go plans, so you can buy one-time credits that never expire.
Related TikTok APIs
- TikTok Channel Stats API - Follower count, total likes, bio, verification status
- TikTok Stats API - Per-video engagement stats
- TikTok Comments API - Pull comments from any video
- TikTok Transcript API - Get spoken text from a TikTok video
Free tools:
- TikTok Channel Videos Extractor - Try the API in your browser, no code needed
- TikTok Channel Data Extractor - Channel-level stats for any profile
Frequently Asked Questions
Does it work for private accounts?
No. Only public TikTok profiles are supported.
How fresh is the data?
Fetched live at request time. Views and likes reflect what's on TikTok right now.
Can I get more than 100 videos per request?
Not in a single request, but you can paginate using the cursor to walk through an entire channel's history.
What does the cursor value represent?
It's a timestamp that TikTok uses internally to page through a channel's video history. You don't need to parse it, just pass it back in the next request.
Do failed requests count against my quota?
No. Only successful requests are charged.
Get Started
Sign up at socialkit.dev and get 20 free credits. No credit card required.
API docs: docs.socialkit.dev/api-reference/tiktok-channel-videos-api