> **For coding agents and LLMs:** This is one page from the Social Fetch docs (markdown export). For curated orientation and workflow guidance, start with [`/llms.txt`](https://www.socialfetch.dev/llms.txt); for agent onboarding and crawl rules, use [`/agents.txt`](https://www.socialfetch.dev/agents.txt); for the full endpoint list with links to pages like this one, use [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt); for one platform's parameters and curls, use [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt); use [`/llms.json`](https://www.socialfetch.dev/llms.json) when you need structured JSON for tool registration.

## This page

- **On-site (HTML):** [https://www.socialfetch.dev/docs/recipes/creator-engagement-scoring](https://www.socialfetch.dev/docs/recipes/creator-engagement-scoring)
- **Markdown (.mdx) URL:** [https://www.socialfetch.dev/docs/recipes/creator-engagement-scoring.mdx](https://www.socialfetch.dev/docs/recipes/creator-engagement-scoring.mdx)

## API base URL and authentication

- **API origin (from OpenAPI `servers`):** `https://api.socialfetch.dev`
- **Authentication:** send `x-api-key: sfk_...` on `/v1/**` routes unless the operation is explicitly anonymous (check OpenAPI `security`, the [API reference hub](https://www.socialfetch.dev/docs/api.mdx), [`/llms.txt`](https://www.socialfetch.dev/llms.txt), or [`/llms.json`](https://www.socialfetch.dev/llms.json) for each route).
- **OpenAPI JSON:** [https://www.socialfetch.dev/openapi.json](https://www.socialfetch.dev/openapi.json)

## Recommended docs entrypoints (this site)

- [Documentation overview](https://www.socialfetch.dev/docs.mdx) — top-level orientation (markdown).
- [Quickstart](https://www.socialfetch.dev/docs/quickstart.mdx) — authenticate with `x-api-key`, validate auth with `whoami`, and understand the JSON envelope.
- [SDK](https://www.socialfetch.dev/docs/sdk.mdx) — official TypeScript SDK guide, including `SocialFetchClient`, `Result`, and `unwrap()`.
- [SDK reference](https://www.socialfetch.dev/docs/sdk-reference.mdx) — exhaustive SDK method inventory and route mapping for agents, tooling, and power users.
- [Choose the right endpoint](https://www.socialfetch.dev/docs/choose-endpoint.mdx) — task-oriented route selection for smoke tests, profiles, list endpoints, and single-item lookups.
- [Capability matrix](https://www.socialfetch.dev/docs/capability-matrix.mdx) — fast comparison of identifiers, pagination, outcomes, media download, and SDK coverage.
- [Recipes](https://www.socialfetch.dev/docs/recipes.mdx) — copyable workflows (brand monitoring, transcripts, Ad Library, creator scoring, Reddit research) with credit callouts and SDK examples.
- [Integrations](https://www.socialfetch.dev/docs/integrations.mdx) — MCP for AI clients, n8n verified node, Apify Store Actors, SDK, and REST API connection paths.
- [MCP product page](https://www.socialfetch.dev/mcp) — hosted MCP overview, OAuth, Skills install.
- [MCP integration](https://www.socialfetch.dev/docs/integrations/mcp.mdx) — hosted `/mcp` server, OAuth, Cursor/VS Code/Claude install snippets, 137 endpoint tools, plus docs_search/docs_read for implementation help.
- [n8n integration](https://www.socialfetch.dev/docs/integrations/n8n.mdx) — install `n8n-nodes-socialfetch`, credentials, and workflow examples.
- [Apify integration](https://www.socialfetch.dev/docs/integrations/apify.mdx) — Store Actors under @social-fetch, PPE billing, dataset export, and quick start.
- [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt) — every documented operation with a direct link to that route's agent-readable markdown page (prefer this over parsing OpenAPI).
- [`/llms-{platform}.txt`](https://www.socialfetch.dev/llms-tiktok.txt) — per-platform endpoint files generated from OpenAPI (parameters, credits, curls).
- [`/agents.txt`](https://www.socialfetch.dev/agents.txt) — agent crawl/onboarding file with capabilities, auth rules, and allowlist.
- [`/llms.json`](https://www.socialfetch.dev/llms.json) — structured machine-readable operation inventory with parameter names, pagination, outcomes, credits, and SDK mapping.
- [API reference hub](https://www.socialfetch.dev/docs/api.mdx) — human-friendly index of operations with links into generated pages.
- [Errors](https://www.socialfetch.dev/docs/errors.mdx) — shared error envelope and HTTP status guidance.
- [Credits](https://www.socialfetch.dev/docs/credits.mdx) — metering, `402`, and planning batch jobs.
- Outcome semantics such as `found`, `not_found`, and `private` are documented in [Errors](https://www.socialfetch.dev/docs/errors.mdx) and on operation pages when present in the OpenAPI contract.

## Markdown docs convention

- Every docs page has a markdown twin: append **`.mdx`** to the docs pathname (for example `/docs/quickstart` → `/docs/quickstart.mdx`).
- Agents that send `Accept: text/markdown` on `/docs/**` HTML URLs may receive markdown directly (same URL, `Vary: Accept`).

---
# Creator engagement scoring (https://www.socialfetch.dev/docs/recipes/creator-engagement-scoring)

Social Fetch returns per-item metrics (views, likes, comments, followers). It does not ship a black-box "engagement score." Pull a profile, pull recent content, score in your warehouse with a formula you can explain to a client.

**You'll need** an [API key](https://app.socialfetch.dev/api-keys) and the [TypeScript SDK](/docs/sdk). Start from [Competitor profile tracking](/docs/recipes/competitor-profile-tracking) if you do not have handles yet.

Credit budget

  Profile get is typically **1 credit**. TikTok / Instagram / YouTube content pages are typically **1 credit** each. Twitter profile tweets are **2 credits** per page. Two content pages after a profile ≈ **3 credits** per creator on TikTok (1 + 1 + 1). Budget before scoring a large roster.

Suggested pipeline

1. Resolve the profile (`lookupStatus` must be `found`).
2. Fetch one or two pages of recent posts/videos.
3. Compute median views (or likes) in your code.
4. Optionally normalize by follower count for cross-creator ranking.

| Platform                          | Profile                                                    | Recent content                                                                                                                                |
| --------------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| [TikTok](/platforms/tiktok)       | [`getProfile`](/docs/api/v1/tiktok/profiles/handle/get)    | [`getProfileVideos`](/docs/api/v1/tiktok/profiles/handle/videos/get)                                                                          |
| [Instagram](/platforms/instagram) | [`getProfile`](/docs/api/v1/instagram/profiles/handle/get) | [`getProfilePosts`](/docs/api/v1/instagram/profiles/handle/posts/get) / [`getProfileReels`](/docs/api/v1/instagram/profiles/handle/reels/get) |
| [YouTube](/platforms/youtube)     | [`getChannel`](/docs/api/v1/youtube/channel/get)           | [`getChannelVideos`](/docs/api/v1/youtube/channels/videos/get)                                                                                |
| [X/Twitter](/platforms/twitter)   | [`getProfile`](/docs/api/v1/twitter/profiles/handle/get)   | [`getProfileTweets`](/docs/api/v1/twitter/profiles/handle/tweets/get) (2 credits/page)                                                        |

Call the profile route before trusting an empty video/post list — some list routes omit `private` / `not_found` the way profile routes do. See the [capability matrix](/docs/capability-matrix).

TikTok example

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

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

function median(nums: number[]): number {
  if (nums.length === 0) return 0;
  const sorted = [...nums].sort((a, b) => a - b);
  return sorted[Math.floor(sorted.length / 2)] ?? 0;
}

async function scoreTikTokCreator(handle: string) {
  const profile = await client.tiktok.getProfile({ handle });
  if (!profile.ok) {
    return { ok: false as const, error: profile.error };
  }

  if (profile.value.data.lookupStatus !== "found") {
    return {
      ok: true as const,
      handle,
      lookupStatus: profile.value.data.lookupStatus,
      score: null,
    };
  }

  const followers = profile.value.data.metrics?.followers ?? 0;
  const videos = await client.tiktok.getProfileVideos({
    handle,
    sortBy: "latest",
  });

  if (!videos.ok) {
    return { ok: false as const, error: videos.error };
  }

  const views = (videos.value.data.videos ?? [])
    .map((v) => v.metrics?.views ?? 0)
    .filter((n) => n > 0);

  const medianViews = median(views);
  const engagementRate =
    followers > 0 ? medianViews / followers : null;

  return {
    ok: true as const,
    handle,
    lookupStatus: "found" as const,
    followers,
    sampleSize: views.length,
    medianViews,
    engagementRate,
    creditsCharged:
      profile.value.meta.creditsCharged + videos.value.meta.creditsCharged,
    requestIds: [
      profile.value.meta.requestId,
      videos.value.meta.requestId,
    ],
  };
}
```

Pick your own formula. Median views beats average when one viral clip skews the feed. Document the rule in code — clients will ask.

Discovery seed

When the roster is empty, seed with [`GET /v1/tiktok/users/search`](/docs/api/v1/tiktok/users/search/get) (`client.tiktok.searchUsers`) or [Instagram profile search](/docs/api/v1/instagram/search/profiles/get), then run the scoring pass.

Longer identity + engagement walkthrough: [Cross-platform creator profiles](/guides/cross-platform-creator-profiles).

Related

* [Credits](/docs/credits) · [SDK](/docs/sdk) · [MCP](/docs/integrations/mcp) · [Capability matrix](/docs/capability-matrix)