TikTok
GET /v1/tiktok/audience-demographics

TikTok Audience Demographics API

Audience country + language mix for a TikTok creator — engagement sample, not a follower census.

3 credits per request
TL;DR
Audience country + language mix for a TikTok creator — engagement sample, not a follower census. The TikTok Audience Demographics API (TikTok) is a single authenticated GET request to /v1/tiktok/audience-demographics that responds with clean JSON and costs 3 credits. Pass cache=true for a free 24h cache hit; default is always fresh. Start with 100 free credits — no credit card.

What is the TikTok Audience Demographics API?

Give a profile URL, @handle, or username and get a ranked audience-country breakdown as clean JSON. TikTok does not publish follower geography — we sample people engaging with recent videos. The two signals come from two populations, disclosed in the response: audienceLanguages[] are tallied from top-level commenters (basis.language="commenters"), while audienceLocations[] come from repliers under the most-replied parent comments (basis.region="repliers") — the only public surface that reliably exposes user.region. Each country row carries country name, countryCode, count, and numeric percentage (+ percentageText). Response includes sampleSize, totalCountries, regionSampleParents + regionSampleVideos (how many distinct parent threads / videos the region sample is spread over), and a clustering-aware confidence: the size-based label (low <400, medium 400–999, high ≥1000) is CAPPED when the region sample is concentrated in few threads (<8 parents or <4 videos → low; <20 parents or <8 videos → at most medium), because 400 repliers from 6 threads are not 400 independent observations. Optional other{} only when countriesLimit truncates. timings{path,postsVia,postsMs,postsDeadlineMs,commentsMs,commentsVia,totalMs,videoConcurrency,commentsAttempts,commentsErrors,commentsAttemptsPerVideo} — postsVia names the leg that served the video list (native|apify), commentsVia the comments surface (web+replies), commentsErrors counts blocked comment requests absorbed before clean pages, and commentsAttemptsPerVideo is the per-video attempts distribution (sorted desc). If the posts leg hits its deadline on a real profile you get a degraded 200 (degraded:true, degradedReason:"posts-timeout", 0 credits) — 404 NOT_FOUND is reserved for profiles positively confirmed absent, never for a slow fetch. Choose videos=12|30|60 (credits 3/5/8) for sample depth. Percentages across audienceLocations (+ other) sum to ~100%. This reflects who engages, not a full follower census.

What you get

  • Numeric percentage + percentageText per country
  • totalCountries + other{} only when truncated
  • basis{language:commenters, region:repliers} — the two sampled populations, disclosed
  • regionSampleParents + regionSampleVideos with clustering-aware confidence
  • audienceLanguages[] from top-level commenters
  • videos=12|30|60 with scaled credits (3/5/8)
  • Degraded posts-timeout 200 at 0 credits — 404 only for confirmed-absent profiles

Try it

Open in Playground

Fill in the parameters below and copy a ready-to-run request, or open the live Playground to run it against your account (no API key paste).

Parameters

Sign in to run live
curl "https://api.captapi.com/v1/tiktok/audience-demographics?url=https%3A%2F%2Fwww.tiktok.com%2F%40khaby.lame" \
  -H "Authorization: Bearer capt_live_..."
# or: -H "x-api-key: capt_live_..."

Edit the parameters and the code updates instantly. Switch languages and hit copy.

Example response

{
  "success": true,
  "data": {
    "platform": "tiktok",
    "username": "khaby.lame",
    "url": "https://www.tiktok.com/@khaby.lame",
    "videosSampled": 12,
    "sampleSize": 269,
    "audienceLocations": [
      {
        "country": "Pakistan",
        "countryCode": "PK",
        "count": 70,
        "percentage": 26.02,
        "percentageText": "26.02%"
      },
      {
        "country": "United States",
        "countryCode": "US",
        "count": 33,
        "percentage": 12.27,
        "percentageText": "12.27%"
      }
    ],
    "basis": {
      "language": "commenters",
      "region": "repliers"
    },
    "videosRequested": 12,
    "totalCountries": 23,
    "confidence": "low",
    "other": {
      "count": 129,
      "percentage": 47.96,
      "percentageText": "47.96%"
    },
    "audienceLanguages": [
      {
        "language": "en",
        "count": 142,
        "percentage": 52.79,
        "percentageText": "52.79%"
      },
      {
        "language": "ur",
        "count": 61,
        "percentage": 22.68,
        "percentageText": "22.68%"
      }
    ],
    "languageSampleSize": 269,
    "regionSampleParents": 41,
    "regionSampleVideos": 11
  }
}

Billing metadata is returned in response headers: X-Captapi-Credits (credits charged), X-Captapi-Cache (hit or miss), and X-Captapi-Source. Failed requests (4xx/5xx) are never charged. See the full list of error codes in the error reference.

Response structure

A successful call returns success, cached, creditsUsed, and a data object with the following fields:

Top-level fields

  • platformPlatform identifier for this response (matches the endpoint's platform).
  • usernameAccount username / handle.
  • urlCanonical URL of the item.
  • videosSampledHow many of the creator's recent videos were sampled to build the breakdown.
  • sampleSizeTotal number of commenter countries counted across the sampled videos.
  • videosRequestedvideos query parameter used for this call (12, 30, or 60).
  • totalCountriesHow many distinct countries appeared in the commenter sample (before countriesLimit truncation).
  • confidenceSample-strength from sampleSize ("low" <400, "medium" 400–999, "high" ≥1000), capped for clustering: regionSampleParents <8 or regionSampleVideos <4 forces low; <20 parents or <8 videos caps at medium.
  • languageSampleSizeHow many comments contributed a language code to audienceLanguages.
  • regionSampleParentsDistinct parent comment threads the region sample is spread over. Low values mean repliers clustered in few conversations — confidence is capped accordingly.
  • regionSampleVideosDistinct videos that contributed at least one replier to the region sample.

Audience locations

Each item in audienceLocations contains:

  • countryCountry for the request context. On popular-creators top-level: ISO feed market you queried (e.g. US) — not each creator's home country (see region).
  • countryCodeISO-3166 alpha-2 country code (e.g. US, MX).
  • countNumber of items in this bucket (e.g. commenters from this country in the sample).
  • percentageNumeric share of the sample (e.g. 26.02). Never a string — use percentageText for display. Values across audienceLocations (+ other) sum to ~100.
  • percentageTextDisplay form of percentage with a % suffix (e.g. "26.02%"). Prefer percentage for math.

Basis

The basis object contains:

  • languageDetected or requested language code.
  • regionRegion or country code for this result (meaning depends on the endpoint — market vs creator home).

Other

The other object contains:

  • countNumber of items in this bucket (e.g. commenters from this country in the sample).
  • percentageNumeric share of the sample (e.g. 26.02). Never a string — use percentageText for display. Values across audienceLocations (+ other) sum to ~100.
  • percentageTextDisplay form of percentage with a % suffix (e.g. "26.02%"). Prefer percentage for math.

Audience languages

Each item in audienceLanguages contains:

  • languageDetected or requested language code.
  • countNumber of items in this bucket (e.g. commenters from this country in the sample).
  • percentageNumeric share of the sample (e.g. 26.02). Never a string — use percentageText for display. Values across audienceLocations (+ other) sum to ~100.
  • percentageTextDisplay form of percentage with a % suffix (e.g. "26.02%"). Prefer percentage for math.

Parameters

NameTypeRequiredDescription
urlstringYesTikTok profile URL, @handle, or username, e.g. https://tiktok.com/@username. Not a YouTube channel URL. The URL platform must match this endpoint's platform. Do not pass cross-platform URLs, e.g. YouTube to TikTok, Instagram to Facebook, LinkedIn to X/Twitter, or Pinterest to Rumble.
videosintegerNoHow many recent videos to sample comments from: 12 (default, 3 credits), 30 (5 credits), or 60 (8 credits).
countriesLimitintegerNoMax countries in audienceLocations; remainder folds into other{count,percentage}. Omit for the full list (other is omitted when unused).
cachebooleanNoSet true to serve from the 24h response cache (0 credits on hit). Default false — always fetch fresh. Envelope includes cached + cachedAt on hits.

Authentication: send your key as Authorization: Bearer capt_live_.... A typical call costs 3 credits. Pass cache=true for a free 24h cache hit; default is always fresh.

Using an AI agent? This endpoint is the MCP tool tiktok_audience_demographics via @captapi/mcp. Set it up →

How it works

  1. 1. Sign up — get 100 free credits, no card required.
  2. 2. Create a key from your dashboard.
  3. 3. Send one request to /v1/tiktok/audience-demographics and parse the JSON response.

Use cases

Geo Targeting

See which countries commenters engage from before localizing creatives.

Market Sizing

Estimate which markets show up in a creator's engaged audience.

Localization

Pick caption languages and market focus from commenter language mix.

Creator Vetting

Check whether engaged commenters match the campaign's target geos.

Frequently asked questions

What does the TikTok Audience Demographics API do?+

The TikTok Audience Demographics API lets you fetch profile or page details and audience stats from a public TikTok profile or page using one GET request to /v1/tiktok/audience-demographics. It returns clean JSON — no OAuth or infrastructure setup required.

How many credits does the TikTok Audience Demographics API cost?+

Each successful call costs 3 credits. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Hits include cached + cachedAt. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Failed or empty results are never charged.

Do I need a TikTok API key or OAuth?+

No. A single Captapi key works across every platform Captapi supports — YouTube, TikTok, Instagram, Facebook, Twitter/X, Reddit, Threads, Bluesky, Pinterest, LinkedIn, Rumble, Spotify, Kwai, and more. We handle proxies, rate limits, retries, and authentication for you.

Is this follower geography?+

No. TikTok does not publish follower country. We sample people engaging with recent videos and report sampleSize, videosSampled, and confidence. Percentages are numeric. Use videos=12|30|60 for deeper samples (3/5/8 credits). Do not treat this as a full follower census.

Why does basis have two values?+

The two signals come from two populations. audienceLanguages[] are tallied from top-level commenters (basis.language="commenters"); audienceLocations[] come from repliers under the most-replied parent comments (basis.region="repliers") — the only public surface that reliably exposes user.region. Repliers are people in conversation, so treat the country mix as engagement geography, not a census.

What does confidence mean?+

A sample-strength label that starts from sampleSize (low <400, medium 400–999, high ≥1000) and is then CAPPED for clustering: replies concentrate under a few popular parent comments, so when regionSampleParents <8 or regionSampleVideos <4 the label drops to low, and below 20 parents / 8 videos it caps at medium. 400 repliers from 6 threads are not 400 independent observations — check regionSampleParents / regionSampleVideos alongside sampleSize.

Why did I get degraded:true with empty audienceLocations?+

That is a posts-timeout: the video-list fetch hit its deadline (see timings.postsMs vs postsDeadlineMs) on a profile that exists. The call costs 0 credits — retry later or with fewer videos. A 404 NOT_FOUND means the profile was positively confirmed absent, which is a different outcome.

Is the TikTok Audience Demographics API suitable for production use?+

Yes. It is a stable REST endpoint with predictable JSON and automatic retries. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Hits include cached + cachedAt. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Use it for analytics, monitoring, and content automation.

More TikTok APIs

Ready to use the TikTok Audience Demographics API?

Sign up, grab your key, and make your first call in 60 seconds.