Back to Blog

How to Scrape TikTok Posts and Analytics via API

By EternalSocial Team4 {minutes} min read

TikTok is one of the hardest platforms to scrape. Its web interface is heavily JavaScript-rendered, it uses device fingerprinting, and it rotates its internal API signatures constantly. Building and maintaining a TikTok scraper in-house is a full-time job.

EternalSocial abstracts all of that behind a simple REST API. You make an HTTP request with a username or video ID, and you get structured JSON data back — profiles, videos, engagement metrics, comments, and more.

This guide covers every TikTok endpoint in the EternalSocial API with practical examples you can use right away.

Prerequisites

You need an EternalSocial API key. Sign up for a free trial to get one. All requests use the same auth pattern:

Authorization: Bearer YOUR_API_KEY

Base URL for all endpoints:

https://api.eternalsocial.dev/v1

Fetching TikTok Profiles

The profile endpoint returns a creator's public information: display name, bio, follower count, following count, total likes, video count, verification status, and profile image.

Request

curl -X GET "https://api.eternalsocial.dev/v1/tiktok/profile/charlidamelio" \
  -H "Authorization: Bearer YOUR_API_KEY"

TypeScript Example

const response = await fetch(
  "https://api.eternalsocial.dev/v1/tiktok/profile/charlidamelio",
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);

const profile = await response.json();

console.log(profile.data.username); // "charlidamelio"
console.log(profile.data.displayName); // "Charli D'Amelio"
console.log(profile.data.followers); // 155000000
console.log(profile.data.totalLikes); // 11400000000
console.log(profile.data.videoCount); // 2400
console.log(profile.data.isVerified); // true

Response Fields

The profile object includes:

  • username — TikTok handle (without @)
  • displayName — Display name
  • bio — Profile biography
  • followers — Follower count
  • following — Following count
  • totalLikes — Cumulative likes across all videos
  • videoCount — Total published videos
  • profilePicUrl — Avatar image URL
  • isVerified — Blue checkmark status
  • isPrivate — Whether the account is private

Profile data is the foundation for influencer databases, competitor tracking, and audience research.

Extracting Video Posts

The posts endpoint returns a user's published videos with full metadata: description, view count, like count, comment count, share count, music info, hashtags, and creation timestamp.

Request

curl -X GET "https://api.eternalsocial.dev/v1/tiktok/posts/charlidamelio?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

TypeScript Example

const response = await fetch(
  "https://api.eternalsocial.dev/v1/tiktok/posts/charlidamelio?limit=20",
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);

const { data, pagination } = await response.json();

for (const video of data) {
  console.log(`Video: ${video.id}`);
  console.log(`Description: ${video.description?.substring(0, 80)}...`);
  console.log(`Views: ${video.viewCount.toLocaleString()}`);
  console.log(`Likes: ${video.likeCount.toLocaleString()}`);
  console.log(`Comments: ${video.commentCount.toLocaleString()}`);
  console.log(`Shares: ${video.shareCount.toLocaleString()}`);
  console.log(`Music: ${video.musicTitle}`);
  console.log(`Hashtags: ${video.hashtags.join(", ")}`);
  console.log("---");
}

Pagination

TikTok creators can have thousands of videos. Use cursor-based pagination to fetch them all:

let cursor: string | undefined;
const allVideos = [];

do {
  const url = new URL(
    "https://api.eternalsocial.dev/v1/tiktok/posts/charlidamelio"
  );
  url.searchParams.set("limit", "50");
  if (cursor) url.searchParams.set("cursor", cursor);

  const response = await fetch(url.toString(), {
    headers: { Authorization: "Bearer YOUR_API_KEY" },
  });

  const { data, pagination } = await response.json();
  allVideos.push(...data);
  cursor = pagination.nextCursor;
} while (cursor);

console.log(`Fetched ${allVideos.length} total videos`);

Calculating Engagement Rate

One of the most common analytics tasks is calculating engagement rate for TikTok videos:

function calculateEngagementRate(video: {
  viewCount: number;
  likeCount: number;
  commentCount: number;
  shareCount: number;
}): number {
  const totalEngagement =
    video.likeCount + video.commentCount + video.shareCount;
  return video.viewCount > 0 ? (totalEngagement / video.viewCount) * 100 : 0;
}

for (const video of data) {
  const rate = calculateEngagementRate(video);
  console.log(`${video.id}: ${rate.toFixed(2)}% engagement`);
}

Getting Single Video Details

When you have a specific video URL or ID, use the video endpoint to get its full metadata.

Request

curl -X GET "https://api.eternalsocial.dev/v1/tiktok/video/7300000000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY"

You can pass either a numeric video ID or a full TikTok URL — the API handles both:

// Both work:
const byId = await fetch(
  "https://api.eternalsocial.dev/v1/tiktok/video/7300000000000000000",
  { headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const byUrl = await fetch(
  `https://api.eternalsocial.dev/v1/tiktok/video/${encodeURIComponent(
    "https://www.tiktok.com/@creator/video/7300000000000000000"
  )}`,
  { headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

Response Fields

The video detail response includes everything from the posts endpoint, plus:

  • videoUrl — Direct URL to the video file
  • coverUrl — Thumbnail image URL
  • duration — Video length in seconds
  • musicAuthor — Original music creator
  • isAd — Whether the video is a paid promotion
  • effectStickers — AR effects used in the video

Fetching Video Comments

Comments reveal what audiences actually think. The comments endpoint returns comment text, author info, like counts, reply counts, and timestamps.

Request

curl -X GET "https://api.eternalsocial.dev/v1/tiktok/comments/7300000000000000000?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

TypeScript Example

const videoId = "7300000000000000000";

const response = await fetch(
  `https://api.eternalsocial.dev/v1/tiktok/comments/${videoId}?limit=20`,
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);

const { data } = await response.json();

for (const comment of data) {
  console.log(`@${comment.username}: ${comment.text}`);
  console.log(`Likes: ${comment.likes} | Replies: ${comment.replyCount}`);
  console.log(`Posted: ${comment.timestamp}`);
  console.log("---");
}

Comments are paginated the same way as posts — use pagination.nextCursor to fetch more.

Detecting Trending Content

One powerful use of TikTok data is identifying content that's performing above a creator's average. Here's a pattern for finding outlier videos:

async function findTrendingVideos(username: string, apiKey: string) {
  const response = await fetch(
    `https://api.eternalsocial.dev/v1/tiktok/posts/${username}?limit=50`,
    {
      headers: { Authorization: `Bearer ${apiKey}` },
    }
  );

  const { data: videos } = await response.json();

  // Calculate average views
  const avgViews =
    videos.reduce(
      (sum: number, v: { viewCount: number }) => sum + v.viewCount,
      0
    ) / videos.length;

  // Find videos with 3x+ the average views
  const trending = videos.filter(
    (v: { viewCount: number }) => v.viewCount > avgViews * 3
  );

  console.log(`Average views: ${Math.round(avgViews).toLocaleString()}`);
  console.log(`Trending videos (3x+ avg): ${trending.length}`);

  for (const video of trending) {
    console.log(`- ${video.id}: ${video.viewCount.toLocaleString()} views`);
    console.log(`  "${video.description?.substring(0, 60)}..."`);
  }

  return trending;
}

This pattern works for any metric — likes, comments, shares, or engagement rate.

Rate Limits

The EternalSocial API uses per-minute rate limiting:

| Plan | Requests/min | Concurrent | | ---------- | ------------ | ---------- | | Free Trial | 30 | 2 | | Starter | 120 | 5 | | Growth | 300 | 10 | | Enterprise | Custom | Custom |

When rate limited, you'll receive a 429 response with a Retry-After header:

async function fetchWithRetry(url: string, apiKey: string): Promise<unknown> {
  for (let attempt = 0; attempt < 3; attempt++) {
    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (response.status === 429) {
      const retryAfter = Number(response.headers.get("Retry-After")) || 10;
      await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    if (!response.ok) throw new Error(`API error: ${response.status}`);
    return response.json();
  }
  throw new Error("Max retries exceeded");
}

Common Use Cases

Influencer Discovery

Scan creator profiles to find accounts with high engagement rates in specific niches. Filter by follower count, content themes, and posting frequency.

Brand Monitoring

Track mentions and hashtag usage to measure campaign performance. Pull comments to gauge audience sentiment around your brand.

Content Strategy Research

Analyze which video formats, lengths, music tracks, and hashtags drive the most engagement for competitors in your space.

Market Research

Collect aggregated data on trending topics, emerging creators, and audience behavior patterns to inform product and marketing decisions.

API Reference

For the complete list of TikTok endpoints, parameters, and response schemas, see the API documentation.

Key TikTok endpoints:

  • GET /tiktok/profile/{username} — Profile data and stats
  • GET /tiktok/posts/{username} — Video posts with metrics
  • GET /tiktok/video/{id} — Single video details
  • GET /tiktok/comments/{videoId} — Video comments

Get Started

Stop fighting TikTok's anti-scraping defenses. EternalSocial gives you reliable, structured TikTok data through a clean API.

Sign up for a free trial to get your API key and start extracting TikTok data today. The free tier includes 1,000 requests per month — enough to build and validate your integration.

Check the API documentation for full endpoint reference, or reach out to support@eternalsocial.dev if you need help.