Competitor profile tracking

Look up the same competitor on TikTok, Instagram, YouTube, and X — one envelope, per-platform lookupStatus, credit callouts

Track competitor accounts across networks with one API key. Each platform is an independent lookup: a missing YouTube channel does not fail Instagram. Same handle is not the same person — treat each row as a candidate until you link them.

You'll need an API key and the TypeScript SDK. Agents can explore with MCP nl_ask_post, then pin profile tools like tiktok_profile_get.

Credit budget

What this costs

Profile lookups are typically 1 credit each when the request completes — including not_found and private. Four platforms × one competitor = ~4 credits per snapshot. Re-poll on your cadence; failed infrastructure (lookup_failed, 503) is not charged.

Check GET /v1/balance before batching a large roster.

Routes

PlatformRouteSDK
TikTokGET /v1/tiktok/profiles/{handle}client.tiktok.getProfile({ handle })
InstagramGET /v1/instagram/profiles/{handle}client.instagram.getProfile({ handle })
YouTubeGET /v1/youtube/channelclient.youtube.getChannel({ handle })
X/TwitterGET /v1/twitter/profiles/{handle}client.twitter.getProfile({ handle })

Optional: Facebook profile (URL or page id), LinkedIn company, Threads profile.

Fan-out example

import { SocialFetchClient } from "@socialfetch/sdk";

const client = new SocialFetchClient({
  apiKey: process.env.SOCIALFETCH_API_KEY!,
});

type PlatformRow = {
  platform: string;
  handle: string;
  lookupStatus: string | undefined;
  followers: number | null;
  requestId: string;
  creditsCharged: number;
};

async function trackCompetitor(handle: string): Promise<PlatformRow[]> {
  const [tiktok, instagram, youtube, twitter] = await Promise.all([
    client.tiktok.getProfile({ handle }),
    client.instagram.getProfile({ handle }),
    client.youtube.getChannel({ handle }),
    client.twitter.getProfile({ handle }),
  ]);

  const rows: PlatformRow[] = [];

  for (const [platform, result] of [
    ["tiktok", tiktok],
    ["instagram", instagram],
    ["youtube", youtube],
    ["twitter", twitter],
  ] as const) {
    if (!result.ok) {
      console.error(platform, result.error.code, result.error.requestId);
      continue;
    }

    const data = result.value.data as {
      lookupStatus?: string;
      metrics?: { followers?: number; subscribers?: number };
    };

    rows.push({
      platform,
      handle,
      lookupStatus: data.lookupStatus,
      followers: data.metrics?.followers ?? data.metrics?.subscribers ?? null,
      requestId: result.value.meta.requestId,
      creditsCharged: result.value.meta.creditsCharged,
    });
  }

  return rows;
}

Always branch on data.lookupStatus when the route exposes it. HTTP 200 alone is not "found."

What to store

Persist capturedAt, per-platform lookupStatus, follower/subscriber metrics, and meta.requestId. Diff follower counts across snapshots in your warehouse — the API does not compute deltas.

For identity linking when handles diverge (bio URLs, display-name checks): Cross-platform creator profiles.

On this page