TikTok Analytics API Overview
Build TikTok analytics into your app with our developer-friendly API. Track any public TikTok video and get hourly performance snapshots without dealing with TikTok’s official API restrictions.
No TikTok Business Account or API approval required. Start building in minutes.
Why Developers Choose Us
Official TikTok API
ContentStats.io API
TikTok’s Requirements:
🔴 Business account verification
🔴 App review (2-8 weeks wait)
🔴 Strict content policies
🔴 Limited to own videos
🔴 Rate limits + quotas
🔴 Complex OAuth flow
Our Approach:
✅ Simple API key auth
✅ Instant access
✅ Track ANY public video
✅ Hourly updates
✅ RESTful design
Quick Integration
Get started with 3 lines of code:
JavaScript/TypeScript
Python
Go
Ruby
const response = await fetch ( 'https://contentstats.io/api/v1/videos/track' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-API-Key' : process . env . CONTENTSTATS_API_KEY
},
body: JSON . stringify ({
video_link: 'https://www.tiktok.com/@user/video/123' ,
duration_days: 7
})
});
const data = await response . json ();
console . log ( 'Video ID:' , data . id );
API Endpoints
Track Video
POST /api/v1/videos/track
Start tracking a TikTok video.
Request:
{
"video_link" : "https://www.tiktok.com/@user/video/1234567890" ,
"duration_days" : 7
}
Response:
{
"id" : "cm5abc123" ,
"video_link" : "https://www.tiktok.com/@user/video/1234567890" ,
"platform" : "tiktok" ,
"status" : "monitoring" ,
"estimated_cost" : 2.52
}
Get Video Data
Retrieve snapshots.
Response:
{
"id" : "cm5abc123" ,
"snapshots" : [
{
"snapshot_time" : "2024-01-29T10:00:00Z" ,
"views" : "1250000" ,
"likes" : "185000" ,
"comments" : "4200" ,
"shares" : "12500" ,
"saves" : "8900"
}
]
}
List Videos
GET /api/v1/videos?platform=tiktok
Get all tracked videos filtered by platform.
Stop Tracking
POST /api/v1/videos/{id}/stop
Stop tracking early to save credits.
Full API Reference View complete API documentation with all endpoints
Integration Examples
React Integration
import { useState , useEffect } from 'react' ;
interface TikTokSnapshot {
views : string ;
likes : string ;
comments : string ;
shares : string ;
saves : string ;
snapshot_time : string ;
}
function TikTokTracker () {
const [ videoId , setVideoId ] = useState < string >( '' );
const [ snapshots , setSnapshots ] = useState < TikTokSnapshot []>([]);
const trackVideo = async ( url : string ) => {
const response = await fetch ( '/api/track-tiktok' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ video_link: url , duration_days: 7 })
});
const data = await response . json ();
setVideoId ( data . id );
};
useEffect (() => {
if ( ! videoId ) return ;
const fetchSnapshots = async () => {
const response = await fetch ( `/api/videos/ ${ videoId } ` );
const data = await response . json ();
setSnapshots ( data . snapshots );
};
// Poll every 5 minutes for new snapshots
const interval = setInterval ( fetchSnapshots , 5 * 60 * 1000 );
fetchSnapshots ();
return () => clearInterval ( interval );
}, [ videoId ]);
return (
< div >
< input
placeholder = "TikTok URL"
onBlur = { ( e ) => trackVideo ( e . target . value ) }
/>
{ snapshots . map (( snap , i ) => (
< div key = { i } >
< p > Views: { snap . views } </ p >
< p > Likes: { snap . likes } </ p >
< p > Time: {new Date ( snap . snapshot_time ). toLocaleString () } </ p >
</ div >
)) }
</ div >
);
}
Next.js API Route
// app/api/track-tiktok/route.ts
import { NextRequest , NextResponse } from 'next/server' ;
export async function POST ( request : NextRequest ) {
const { video_link , duration_days } = await request . json ();
const response = await fetch ( 'https://contentstats.io/api/v1/videos/track' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-API-Key' : process . env . CONTENTSTATS_API_KEY !
},
body: JSON . stringify ({ video_link , duration_days })
});
const data = await response . json ();
return NextResponse . json ( data );
}
Python Flask Integration
from flask import Flask, request, jsonify
import requests
import os
app = Flask( __name__ )
@app.route ( '/api/track-tiktok' , methods = [ 'POST' ])
def track_tiktok ():
data = request.get_json()
response = requests.post(
'https://contentstats.io/api/v1/videos/track' ,
headers = {
'Content-Type' : 'application/json' ,
'X-API-Key' : os.environ[ 'CONTENTSTATS_API_KEY' ]
},
json = {
'video_link' : data[ 'video_link' ],
'duration_days' : data.get( 'duration_days' , 7 )
}
)
return jsonify(response.json())
@app.route ( '/api/videos/<video_id>' , methods = [ 'GET' ])
def get_video ( video_id ):
response = requests.get(
f 'https://contentstats.io/api/v1/videos/ { video_id } ' ,
headers = { 'X-API-Key' : os.environ[ 'CONTENTSTATS_API_KEY' ]}
)
return jsonify(response.json())
Data Structure
Snapshot Object
interface Snapshot {
id : string ;
snapshot_id : string ;
snapshot_time : string ; // ISO 8601
views : string ; // BigInt as string
likes : string ;
comments : string ;
shares : string | null ;
saves : string | null ;
provider : string ;
}
Rate Limiting
Plan Rate Limit Concurrent Videos Free 60 req/min 10 Pro 300 req/min 100 Enterprise Custom Unlimited
Rate limit headers included in every response:
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
Error Handling
try {
const response = await fetch ( 'https://contentstats.io/api/v1/videos/track' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-API-Key' : process . env . CONTENTSTATS_API_KEY
},
body: JSON . stringify ({ video_link , duration_days: 7 })
});
if ( ! response . ok ) {
const error = await response . json ();
switch ( response . status ) {
case 401 :
throw new Error ( 'Invalid API key' );
case 402 :
throw new Error ( `Insufficient balance: ${ error . balance } ` );
case 404 :
throw new Error ( 'Video not found or private' );
case 429 :
throw new Error ( 'Rate limit exceeded' );
default :
throw new Error ( error . error || 'Unknown error' );
}
}
const data = await response . json ();
return data ;
} catch ( error ) {
console . error ( 'TikTok tracking failed:' , error . message );
}
Webhook Integration (Coming Soon)
Subscribe to events:
{
"events" : [ "snapshot.created" , "tracking.completed" ],
"url" : "https://your-app.com/webhooks/contentstats" ,
"secret" : "whsec_your_secret"
}
Best Practices
Cache video data locally to reduce API calls: const cache = new Map ();
async function getVideo ( id ) {
if ( cache . has ( id )) {
return cache . get ( id );
}
const data = await fetchVideo ( id );
cache . set ( id , data );
return data ;
}
Validate TikTok URLs before tracking: function isValidTikTokUrl ( url ) {
const patterns = [
/ ^ https: \/\/ ( www \. ) ? tiktok \. com \/ @ [ \w.- ] + \/ video \/ \d + / ,
/ ^ https: \/\/ vm \. tiktok \. com \/ [ \w ] + / ,
/ ^ https: \/\/ ( www \. ) ? tiktok \. com \/ t \/ [ \w ] + /
];
return patterns . some ( pattern => pattern . test ( url ));
}
Don’t poll faster than hourly — snapshots update every hour: // Bad: Polling every minute
setInterval ( fetchSnapshots , 60 * 1000 ); // ❌
// Good: Polling every hour
setInterval ( fetchSnapshots , 60 * 60 * 1000 ); // ✅
Check balance before tracking to avoid errors: const usage = await fetch ( 'https://contentstats.io/api/v1/usage' , {
headers: { 'X-API-Key' : apiKey }
}). then ( r => r . json ());
if ( usage . balance_usd < estimatedCost ) {
throw new Error ( 'Insufficient balance' );
}
Testing
Test with different video types:
const testCases = [
{
name: 'Viral video' ,
url: 'https://www.tiktok.com/@charlidamelio/video/...' ,
expected: { platform: 'tiktok' , status: 'monitoring' }
},
{
name: 'Small creator' ,
url: 'https://www.tiktok.com/@user/video/...' ,
expected: { platform: 'tiktok' , status: 'monitoring' }
}
];
for ( const test of testCases ) {
const result = await trackVideo ( test . url );
console . assert ( result . platform === test . expected . platform );
}
Batch requests : Track multiple videos in parallel
Use webhooks : Get notified instead of polling (coming soon)
Cache aggressively : Snapshots don’t change after creation
Filter early : Use query parameters to reduce response size
Explore analytics APIs for other platforms:
Next Steps