STRUCTURED DATA API

TikTok Scraper API

A TikTok scraper you call over HTTP: send a TikTok video or profile URL to /data and get engagement counts, captions, hashtags, music and author stats back as JSON. No signing, tokens or headless browser on your side. Flat 15 credits per page.

2,000 free API credits · No credit card required

Scrape TikTok videos and profiles

Send the page's normal URL to /data. The page type is detected from the URL, and the response tells you which one it was in request_parameters.type.

Video

type: "video"

Caption, create time, likes, plays, comments, shares, saves and reposts, hashtags, mentions, music, video metadata, subtitles, tagged location and the author's profile stats. Photo slideshows included.

tiktok.com/@user/video/VIDEO_ID tiktok.com/@user/photo/VIDEO_ID tiktok.com/embed/v2/VIDEO_ID

Profile

type: "profile"

Username, nickname, bio and bio link, verified and private flags, followers, following, total likes, video count and account creation time.

tiktok.com/@user
These URLs return a 400 that isn't charged, with a message listing what is supported: hashtag pages (tiktok.com/tag/…), short links (vm.tiktok.com/…, tiktok.com/t/…), and search and the For You feed. More page types and sites are added over time, so don't validate URLs on your side — send the URL and handle the 400.

How to scrape TikTok with one API call

No selectors, proxies, or headless browser to run. The page-scraping options (js, proxy, headers…) don't apply; country picks the proxy country (default us).

curl -G "https://api.webscraping.ai/data" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "url=https://www.tiktok.com/@nike"
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.tiktok.com/@nike",
#                          "provider": "tiktok", "type": "profile"},
#   "parse_status": "ok",
#   "data": {
#     "name": "nike",
#     "nick_name": "Nike",
#     "profile_url": "https://www.tiktok.com/@nike",
#     "bio_link": "http://empli.fi/niketiktok",
#     "verified": true,
#     "private_account": false,
#     "fans": 9232397,
#     "following": 90,
#     "heart": 49085687,
#     "video": 1089,
#     ...
#   }
# }
# pip install webscraping_ai
# https://pypi.org/project/webscraping-ai/
from webscraping_ai import Client

client = Client(api_key="YOUR_API_KEY")
result = client.data("https://www.tiktok.com/@nike")
print(result["request_parameters"]["provider"], result["parse_status"])
print(result["data"])
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.tiktok.com/@nike",
#                          "provider": "tiktok", "type": "profile"},
#   "parse_status": "ok",
#   "data": {
#     "name": "nike",
#     "nick_name": "Nike",
#     "profile_url": "https://www.tiktok.com/@nike",
#     "bio_link": "http://empli.fi/niketiktok",
#     "verified": true,
#     "private_account": false,
#     "fans": 9232397,
#     "following": 90,
#     "heart": 49085687,
#     "video": 1089,
#     ...
#   }
# }
// npm install webscraping-ai
// https://www.npmjs.com/package/webscraping-ai
import { WebScrapingAI } from 'webscraping-ai';

const client = new WebScrapingAI({ apiKey: 'YOUR_API_KEY' });
const result = await client.data({ url: 'https://www.tiktok.com/@nike' });
console.log(result.request_parameters.provider, result.parse_status);
console.log(result.data);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.tiktok.com/@nike",
//                          "provider": "tiktok", "type": "profile"},
//   "parse_status": "ok",
//   "data": {
//     "name": "nike",
//     "nick_name": "Nike",
//     "profile_url": "https://www.tiktok.com/@nike",
//     "bio_link": "http://empli.fi/niketiktok",
//     "verified": true,
//     "private_account": false,
//     "fans": 9232397,
//     "following": 90,
//     "heart": 49085687,
//     "video": 1089,
//     ...
//   }
// }
<?php
// composer require webscraping-ai/webscraping-ai-php
// https://packagist.org/packages/webscraping-ai/webscraping-ai-php
require 'vendor/autoload.php';

use WebScrapingAI\Client;

$client = new Client('YOUR_API_KEY');
$result = $client->data(url: 'https://www.tiktok.com/@nike');
echo $result['request_parameters']['provider'], ' ', $result['parse_status'], "\n";
print_r($result['data']);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.tiktok.com/@nike",
//                          "provider": "tiktok", "type": "profile"},
//   "parse_status": "ok",
//   "data": {
//     "name": "nike",
//     "nick_name": "Nike",
//     "profile_url": "https://www.tiktok.com/@nike",
//     "bio_link": "http://empli.fi/niketiktok",
//     "verified": true,
//     "private_account": false,
//     "fans": 9232397,
//     "following": 90,
//     "heart": 49085687,
//     "video": 1089,
//     ...
//   }
// }
# gem install webscraping_ai
# https://rubygems.org/gems/webscraping_ai
require 'webscraping_ai'

client = WebScrapingAI::Client.new(api_key: 'YOUR_API_KEY')
result = client.data('https://www.tiktok.com/@nike')
puts "#{result['request_parameters']['provider']} #{result['parse_status']}"
puts result['data'].inspect
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.tiktok.com/@nike",
#                          "provider": "tiktok", "type": "profile"},
#   "parse_status": "ok",
#   "data": {
#     "name": "nike",
#     "nick_name": "Nike",
#     "profile_url": "https://www.tiktok.com/@nike",
#     "bio_link": "http://empli.fi/niketiktok",
#     "verified": true,
#     "private_account": false,
#     "fans": 9232397,
#     "following": 90,
#     "heart": 49085687,
#     "video": 1089,
#     ...
#   }
# }
// go get github.com/webscraping-ai/webscraping-ai-go/v4
// https://pkg.go.dev/github.com/webscraping-ai/webscraping-ai-go/v4
package main

import (
    "context"
    "fmt"

    webscrapingai "github.com/webscraping-ai/webscraping-ai-go/v4"
)

func main() {
    client, _ := webscrapingai.NewClient(&webscrapingai.Config{APIKey: "YOUR_API_KEY"})
    res, _ := client.Data(context.Background(), &webscrapingai.DataOptions{
        URL: "https://www.tiktok.com/@nike",
    })
    fmt.Println(res.RequestParameters.Provider, res.ParseStatus)
    fmt.Println(string(res.Data)) // raw JSON; its shape depends on the provider and page type
}
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.tiktok.com/@nike",
//                          "provider": "tiktok", "type": "profile"},
//   "parse_status": "ok",
//   "data": {
//     "name": "nike",
//     "nick_name": "Nike",
//     "profile_url": "https://www.tiktok.com/@nike",
//     "bio_link": "http://empli.fi/niketiktok",
//     "verified": true,
//     "private_account": false,
//     "fans": 9232397,
//     "following": 90,
//     "heart": 49085687,
//     "video": 1089,
//     ...
//   }
// }
// Maven: ai.webscraping:webscraping-ai:4.2.0
// https://central.sonatype.com/artifact/ai.webscraping/webscraping-ai
import ai.webscraping.Client;
import ai.webscraping.Config;
import ai.webscraping.option.DataOptions;
import ai.webscraping.result.DataResult;

Client client = new Client(Config.builder().apiKey("YOUR_API_KEY").build());
DataResult result = client.data(DataOptions.builder()
    .url("https://www.tiktok.com/@nike")
    .build());
System.out.println(result.getRequestParameters().getProvider() + " " + result.getParseStatus());
System.out.println(result.getData());
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.tiktok.com/@nike",
//                          "provider": "tiktok", "type": "profile"},
//   "parse_status": "ok",
//   "data": {
//     "name": "nike",
//     "nick_name": "Nike",
//     "profile_url": "https://www.tiktok.com/@nike",
//     "bio_link": "http://empli.fi/niketiktok",
//     "verified": true,
//     "private_account": false,
//     "fans": 9232397,
//     "following": 90,
//     "heart": 49085687,
//     "video": 1089,
//     ...
//   }
// }
// dotnet add package WebScrapingAI
// https://www.nuget.org/packages/WebScrapingAI
using WebScrapingAI;

var client = new WebScrapingAIClient(new WebScrapingAIClientOptions { ApiKey = "YOUR_API_KEY" });
var result = await client.DataAsync(new DataRequest {
    Url = "https://www.tiktok.com/@nike",
});
Console.WriteLine($"{result.RequestParameters.Provider} {result.ParseStatus}");
Console.WriteLine(result.Data);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.tiktok.com/@nike",
//                          "provider": "tiktok", "type": "profile"},
//   "parse_status": "ok",
//   "data": {
//     "name": "nike",
//     "nick_name": "Nike",
//     "profile_url": "https://www.tiktok.com/@nike",
//     "bio_link": "http://empli.fi/niketiktok",
//     "verified": true,
//     "private_account": false,
//     "fans": 9232397,
//     "following": 90,
//     "heart": 49085687,
//     "video": 1089,
//     ...
//   }
// }

Trimmed, and the counts are illustrative — they change constantly. Fields a page doesn't expose come back as null, though some flags come back false and lists come back empty. data can be null when parse_status is parse_failed or not_found, so check it before reading fields.

What the TikTok scraper returns

The key fields per page type. Names are snake_case across every site; the full contract is in the API reference.

type: "video"

FieldWhat it holds
id, text, text_language, web_video_urlPost id, caption, its language and the canonical URL.
create_time, create_time_isoUnix seconds and the ISO timestamp.
digg_count, play_count, comment_count, share_count, collect_count, repost_countLikes, plays, comments, shares, saves and reposts.
hashtags, mentions, detailed_mentionsHashtags as {id, name, title, cover}; mentions as @handles and as objects.
is_slideshow, slideshow_image_links, media_urlsPhoto posts list their images; videos list the play URL.
video_metaheight, width, duration, cover_url, format, definition, subtitle_links.
music_metamusic_id, music_name, music_author, music_original, play_url.
author_metaThe author's name, nick_name, verified, signature, fans, following, heart, video.
location_created, location_meta, effect_stickers, is_adRegion, tagged place, effects used and the ad flag.

type: "profile"

FieldWhat it holds
id, sec_uid, name, nick_name, profile_urlAccount ids, @username and display name.
signature, bio_linkBio text and the link in bio.
verified, private_account, languageAccount flags.
fans, following, heart, video, friends, diggFollowers, following, total likes received, video count, friends. digg (videos liked) is usually 0 logged-out; treat it as unknown.
create_time, commerce_user_info, tt_sellerAccount creation time and the business/seller flags.

What's not included

Everything comes from what TikTok shows a logged-out visitor. That sets these limits.

No video list on profiles. A profile returns the account and its counts, not its videos; send each video URL separately.
Rounded play counts. TikTok shows logged-out visitors play_count rounded to 3 significant figures (1.23M), and the author stats on a video page are rounded the same way. Likes, comments, shares and saves on a video are exact, and so are a profile's followers, following, total likes and video count. A profile's digg (videos the account liked) usually reads 0 logged-out, so treat it as unknown.
No comments. comment_count is there; the comment text isn't.
No hashtag feeds or short links yet. Resolve a vm.tiktok.com link to its full URL first.
Need a page type or site that isn't supported? /ai/fields extracts the fields you describe in plain language from any public page, and /html returns the rendered HTML for your own parser.

Flat pricing: 15 credits per page

Every supported TikTok page type costs the same, with no extra charge for proxies or retries. That's about $1.74 per 1,000 pages on the $29 plan.

PlanPriceCreditsPages
Free $0 2,000 up to 133
Personal $29/mo 250,000 up to 16,666
Plus $99/mo 1,000,000 up to 66,666
Startup $249/mo 3,000,000 up to 200,000

The free plan's 2,000 credits renew monthly. All plans, including pay-as-you-go credits.

What's charged

Unsupported URL or page type: a 400, not charged.
Page couldn't be fetched: a 500, not charged.
Charged even without data: parse_status parse_failed (the page was fetched but couldn't be parsed) and not_found (the page doesn't exist) are successful requests and cost 15 credits, like ok.

Also from the terminal, AI agents, and n8n

CLI

webscraping-ai has a data command; pass - to read URLs from stdin, one per line.

webscraping-ai data 'https://www.tiktok.com/@nike'

MCP server

Claude, Cursor and other MCP clients get a webscraping_ai_data tool from the hosted MCP server (OAuth login, no API key to paste). Ask for a TikTok page's data in plain language and the agent calls it.

n8n

The WebScraping.AI n8n node has a Get Structured Data operation: feed it URLs from a sheet or a trigger and route the JSON onward, no code.

Frequently asked questions

What is a TikTok scraper?

A tool that reads public TikTok pages and returns their data in a structured form. Here it's an HTTP API: you send a TikTok video or profile URL to /data and get JSON back, with engagement counts, caption, hashtags, music and author stats for a video, or bio and follower counts for a profile.

Can it scrape TikTok comments?

Not the comment text. A video returns comment_count along with likes, plays, shares and saves; the comments themselves aren't on the public video page.

Can I get the videos from a TikTok profile?

Not from the profile URL: a profile returns the account, bio and counts (followers, following, total likes, video count), not the video feed. Send each video URL to /data to get that video's stats, caption, music and author.

Why is play_count a round number?

TikTok rounds view counts to 3 significant figures for logged-out visitors, and /data returns what the public page shows. Likes, comments, shares and saves on a video are exact.

Are photo slideshows supported?

Yes. /@user/photo/ID URLs return the same video type with is_slideshow true and the images in slideshow_image_links.

Is there a free TikTok scraper API?

Yes, for trying it out: the free plan includes 2,000 API credits every month, which covers 133 TikTok pages at 15 credits each. No credit card is needed. Paid plans start at $29/mo for 250,000 credits, or buy pay-as-you-go credits with no subscription from a $20 top-up (100,000 credits, about 6,666 pages).

How much does the TikTok Scraper API cost?

A flat 15 credits per page, for every supported TikTok page type. On the $29/mo plan (250,000 credits) that is up to 16,666 pages, or about $1.74 per 1,000. Unsupported URLs return a 400 and fetch failures a 500; neither is charged. parse_failed and not_found results are successful requests and are charged.

What happens if I send a URL you don't support?

You get a 400 that isn't charged, and its message lists what is supported. For pages /data doesn't cover, /ai/fields extracts the fields you describe from any public URL, and /html returns the rendered page for your own parser.

Other sites on the same endpoint

One API key, one request format, the same response envelope.

YouTube Scraper API Twitter (X) Scraper API LinkedIn Scraper API Instagram Scraper API Reddit Scraper API Google SERP API

Get TikTok data as JSON today

Get started with 2,000 free API credits. No credit card required.

Icon