SocialCrawl

Creator engagement scoring

Compare a creator's engagement rate across TikTok, Instagram, and YouTube on one ranked table. Same formula, same clamp, 3 credits per creator.

You will build a creator-vetting table for an influencer-marketing team: one creator's TikTok, Instagram, and YouTube performance side by side, ranked, on numbers that are actually comparable.

Cost per run: 3 credits per creator (3 platforms x 1 credit). Vetting a 100-creator shortlist costs 300 credits.

How do you compare engagement rates across platforms?

Fetch the creator's profile from each platform's profile endpoint and read computed.engagement_rate. When an endpoint supports engagement_rate and the required source inputs are present, SocialCrawl applies the canonical formula and clamps the result into [0, 1], so populated values are directly comparable across platforms.

Raw engagement numbers do not compare on their own. A TikTok like is not an Instagram like is not a YouTube comment, follower counts inflate differently, and every analytics vendor defines "engagement rate" its own way. This recipe is the payoff for the canonical schema: a populated TikTok value of 0.082 means the same thing as a populated Instagram value of 0.082.

What you need

Three standard-tier profile endpoints (1 credit each), each carrying the same computed field:

EndpointReturnsCost
GET /v1/tiktok/profileTikTok profile with computed.engagement_rate1cr
GET /v1/instagram/profileInstagram profile with computed.engagement_rate1cr
GET /v1/youtube/channelYouTube channel with computed.engagement_rate1cr

The code

TypeScript
// recipe-engagement-table.ts
// Compares one creator's engagement across TikTok, Instagram, and YouTube.
// Run with: SOCIALCRAWL_KEY=sc_... npx tsx recipe-engagement-table.ts

const KEY = process.env.SOCIALCRAWL_KEY;
if (!KEY) throw new Error("Set SOCIALCRAWL_KEY");

const BASE = "https://www.socialcrawl.dev/v1";
const handle = "mrbeast";

type Profile = {
  success: boolean;
  platform: string;
  data?: {
    author: { username: string | null; followers: number | null };
    computed: {
      engagement_rate: number | null;
      estimated_reach: number | null;
      language: string | null;
      content_category: string | null;
    };
  };
};

async function get(
  path: string,
  params: Record<string, string>,
): Promise<Profile> {
  const url = new URL(`${BASE}/${path}`);
  for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
  const res = await fetch(url, { headers: { "x-api-key": KEY! } });
  return (await res.json()) as Profile;
}

const [tiktok, instagram, youtube] = await Promise.all([
  get("tiktok/profile", { handle }),
  get("instagram/profile", { handle }),
  get("youtube/channel", { handle }),
]);

const rows = [tiktok, instagram, youtube]
  .filter((p) => p.success && p.data)
  .map((p) => ({
    platform: p.platform,
    followers: p.data!.author.followers,
    engagement_rate: p.data!.computed.engagement_rate,
    estimated_reach: p.data!.computed.estimated_reach,
  }))
  .sort((a, b) => (b.engagement_rate ?? 0) - (a.engagement_rate ?? 0));

console.table(rows);

What you get back

JSON
// console.table output:
// ┌─────────┬───────────┬───────────┬─────────────────┬──────────────────┐
// │ (index) │ platform  │ followers │ engagement_rate │ estimated_reach  │
// ├─────────┼───────────┼───────────┼─────────────────┼──────────────────┤
// │    0    │ "tiktok"  │ 95000000  │       1         │     9500000      │ // <-- clamped, see warnings
// │    1    │ "youtube" │ 351000000 │     0.0842      │     2957420      │
// │    2    │ "instagram"│ 64200000 │     0.0413      │      265146      │
// └─────────┴───────────┴───────────┴─────────────────┴──────────────────┘

A clamped 1 is a signal, not a score: data._warnings on that response says which input made the raw ratio impossible. Treat clamped rows as "cannot compare", not as "best creator".

What to change

  • handle: any creator on those three platforms. Try charlidamelio, khaby.lame, or mkbhd.
  • Handles per platform: real creators rarely use one handle everywhere. Pass a per-platform map instead of a single string.
  • Score a shortlist: wrap the whole block in a loop over an array of creators and sort the flattened rows. Budget 3 credits per creator.
  • Weight the rank: engagement_rate alone favours small accounts. Blend it with followers or estimated_reach for the tradeoff your team actually makes.

On this page