# TikTok Metrics Scraper - Video & Profile Stats (`chronometrica/tiktok-metrics-scraper`) Actor

Scrape public TikTok video and profile metrics from video URLs, share links, profile URLs, and @handles. Collect views, likes, comments, shares, saves, reposts, profile stats, IDs, captions, hashtags, music, timestamps, precision labels, provenance, and clean CSV/API rows.

- **URL**: https://apify.com/chronometrica/tiktok-metrics-scraper.md
- **Developed by:** [Chronometrica](https://apify.com/chronometrica) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 0 monthly users, 66.7% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 tiktok metric rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## TikTok Metrics Scraper

### 📊 What does TikTok Metrics Scraper do?

TikTok Metrics Scraper collects public TikTok video metrics and profile metrics
from TikTok video URLs, share links, profile URLs, and `@handles`.

Use it when you need clean TikTok data for creator research, influencer
reporting, campaign tracking, competitor monitoring, social analytics,
dashboards, warehouse loads, and scheduled metric snapshots.

The Actor returns flat CSV/API-friendly rows with TikTok views, likes, comments,
shares, saves, reposts, profile stats, IDs, captions, hashtags, music,
thumbnails, timestamps, status fields, and metric quality labels.

This Actor does not log in, use cookies, scrape private TikTok content, collect
comment text, or bypass TikTok access controls. It only returns data that is
available from public TikTok surfaces at run time.

With TikTok Metrics Scraper, you can:

- 📈 Track TikTok video performance from known video URLs and share links.
- 👤 Discover recent public videos from TikTok profile URLs and `@handles`.
- 💬 Collect public views, likes, comments, shares, saves, and reposts when
  available.
- 🧑‍🎤 Add public profile metrics such as followers, following, total likes, and
  video counts.
- 🆔 Extract useful IDs such as `profileId` and `postId`.
- 🎵 Save captions, hashtags, music metadata, thumbnails, duration, and created
  dates.
- 🎯 Check metric precision and availability instead of treating every count as
  equally exact.
- 📦 Export results as JSON, JSONL, CSV, Excel, XML, RSS, or HTML.

### 📦 What TikTok metric data can I extract?

Each dataset row represents one TikTok video.

| Data group         | Example fields                                                                               |
| ------------------ | -------------------------------------------------------------------------------------------- |
| 🔗 URL identity    | `inputUrl`, `postUrl`, `profileUrl`                                                          |
| 🆔 TikTok IDs      | `profileId`, `postId`, `postType`                                                            |
| 🧾 Content details | `description`, `publishedAt`, `thumbnailUrl`, `videoDurationSeconds`, hashtags, `musicTitle` |
| 👤 Profile details | `profileHandle`, `profileName`, `profileAvatarUrl`, `profileVerified`                        |
| 📊 Video metrics   | `views`, `likes`, `comments`, `shares`, `saves`, `reposts`                                   |
| 👥 Profile metrics | `profileFollowersCount`, `profileFollowingCount`, `profileLikesCount`, `profileVideosCount`  |
| 🎯 Metric quality  | `postMetricStatus`, `profileMetricStatus`                                                    |
| 🚦 Row status      | `status`, `statusReason`, `scrapedAt`                                                        |

Metric availability depends on what TikTok exposes publicly for each video or
profile. If a public source does not expose a metric, the Actor marks that
metric as unavailable instead of filling it with a fake zero.

### ⚙️ Can I use this Actor through an API?

Yes. You can run TikTok Metrics Scraper manually in Apify Console or use it
through:

- Apify API
- Python SDK
- Node.js SDK
- Webhooks
- Scheduled runs
- Apify integrations

This makes it useful for social media dashboards, influencer lists, competitive
intelligence, creator databases, campaign reporting, data warehouses, and
automated market research workflows.

### 🎯 Why scrape TikTok video and profile metrics?

TikTok public metrics help you understand which creators, videos, sounds,
hashtags, campaigns, and competitors are gaining traction.

| Use case                     | How TikTok metric data helps                                                      |
| ---------------------------- | --------------------------------------------------------------------------------- |
| 📈 Track creator performance | Monitor public engagement across known creator video URLs.                        |
| 🧑‍🎤 Research influencers      | Compare profile audience size, video volume, and recent video performance.        |
| 📣 Measure campaigns         | Collect repeatable snapshots for campaign videos, branded posts, and promotions.  |
| 🕵️ Monitor competitors       | Track public video metrics for competing brands, products, or creators.           |
| 🎵 Analyze content signals   | Keep captions, hashtags, music, thumbnails, duration, and created dates together. |
| 📊 Build reporting workflows | Feed normalized TikTok metrics into dashboards, spreadsheets, and BI tools.       |
| 🔎 Audit metric availability | Separate available, partial, unavailable, and failed rows cleanly.                |

### 💵 How much does scraping TikTok metrics cost?

TikTok Metrics Scraper uses Pay Per Event pricing: **$2.00 per 1,000 TikTok
metric rows** ($0.002 per row), with platform usage included. Higher Apify
subscription tiers may receive lower per-row pricing on the Actor's
**Pricing** tab.

Start with a small batch of 3 to 10 URLs when testing. The run summary and
dataset statuses show which URLs resolved, which returned public metrics, which
returned no public metrics, and whether any URLs failed.

### 🚀 How do I use TikTok Metrics Scraper?

1. Create or log in to your Apify account.
2. Open **TikTok Metrics Scraper**.
3. Choose **Auto-detect URLs and handles**, **Video URLs only**, or **Profile
   discovery only**.
4. Paste TikTok video URLs, share links, profile URLs, `@handles`, or a mix of
   them.
5. Set the maximum number of metric rows to collect.
6. Leave the default settings for your first run.
7. Click **Start**.
8. Open the **Output** tab to inspect the dataset and run summary.
9. Download your data in JSON, JSONL, CSV, Excel, XML, RSS, or HTML.

### ⬇️ Input

The main input is `startUrls`. Paste at least one TikTok video URL, share link,
profile URL, or `@handle`. `https://` is optional for normal TikTok URLs.

For a quick test, run a known public MrBeast TikTok video:

```json
{
    "mode": "auto",
    "startUrls": ["https://www.tiktok.com/@mrbeast/video/7654638524729216287"],
    "maxItems": 25,
    "includeProfileMetrics": true
}
````

In **Auto-detect URLs and handles** mode, you can paste direct video URLs and
profile inputs into the same list. The Actor combines direct videos and
profile-discovered videos, deduplicates them, and applies one shared metric row
cap.

#### 🔗 TikTok URLs and handles

Supported input shapes include:

```text
www.tiktok.com/@creator/video/1234567890123456789
https://www.tiktok.com/@creator/video/1234567890123456789
https://www.tiktok.com/t/ZTxxxxxxxx/
https://vm.tiktok.com/ZMxxxxxxxx/
https://vt.tiktok.com/ZSxxxxxxxx/
https://www.tiktok.com/@creator
@creator
creator
creator.name
```

Best results usually come from direct public video URLs and public profile URLs
that open in a logged-out browser.

#### 👤 Profile discovery

Use profile discovery when you want the Actor to find recent public videos from
a TikTok profile before collecting metrics.

```json
{
    "mode": "profileUrls",
    "startUrls": ["@mrbeast"],
    "maxItems": 25,
    "maxItemsPerProfile": 10,
    "includeProfileMetrics": true
}
```

Use `maxItemsPerProfile` to control how many public video URLs are discovered
from each profile. The shared `maxItems` cap still limits total output rows for
the whole run.

#### 🎛️ Settings

| Option                  | What it does                                                                                   |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| `mode`                  | `auto` to detect mixed inputs, `knownUrls` for video URLs only, or `profileUrls` for profiles. |
| `startUrls`             | TikTok video URLs, share links, profile URLs, `@handles`, or raw handles such as `mrbeast`.    |
| `maxItems`              | Maximum video metric rows to save across the whole run.                                        |
| `maxItemsPerProfile`    | Maximum public video URLs to discover from each profile input.                                 |
| `includeProfileMetrics` | Adds best-effort public follower, following, total likes, and video counts.                    |
| `maxConcurrency`        | Controls how many TikTok URLs are resolved at the same time.                                   |
| `requestTimeoutSecs`    | Maximum wait time for each public TikTok request.                                              |
| `failOnNoMetrics`       | Fails the run if none of the input URLs expose public metrics.                                 |

### ⬆️ Output sample

The results are stored in the default dataset. Each result is one TikTok video
row.

```json
{
    "platform": "tiktok",
    "inputUrl": "www.tiktok.com/@examplecreator/video/7651772538292342046",
    "postUrl": "https://www.tiktok.com/@examplecreator/video/7651772538292342046",
    "postId": "7651772538292342046",
    "postType": "video",
    "description": "Example caption text #marketing #tiktok",
    "publishedAt": "2026-06-22T12:00:00.000Z",
    "thumbnailUrl": "https://p16-sign-va.tiktokcdn.com/example.jpg",
    "videoDurationSeconds": 42,
    "hashtagNames": ["marketing", "tiktok"],
    "musicTitle": "Example sound",
    "musicAuthorName": "Example Artist",
    "profileId": "1234567890123456789",
    "profileHandle": "examplecreator",
    "profileName": "Example Creator",
    "profileUrl": "https://www.tiktok.com/@examplecreator",
    "profileVerified": true,
    "views": 1234567,
    "likes": 23456,
    "comments": 345,
    "shares": 456,
    "saves": 567,
    "reposts": 12,
    "postMetricStatus": [
        {
            "metric": "views",
            "status": "present",
            "precision": "exact"
        }
    ],
    "profileFollowersCount": 1250000,
    "profileFollowingCount": 418,
    "profileLikesCount": 24800000,
    "profileVideosCount": 412,
    "profileMetricStatus": [
        {
            "metric": "profileFollowersCount",
            "status": "present",
            "precision": "exact"
        }
    ],
    "status": "ok",
    "statusReason": null,
    "scrapedAt": "2026-06-22T12:05:00.000Z"
}
```

### 🎯 Metric precision and availability

TikTok public pages can expose full integers, compact display counts, or already
rounded public counts. TikTok Metrics Scraper labels metric precision instead
of pretending all numbers are equally exact.

| Precision         | Meaning                                                                               |
| ----------------- | ------------------------------------------------------------------------------------- |
| `exact`           | TikTok public data exposed a full integer that does not look display-rounded.         |
| `display_rounded` | TikTok public data exposed a compact display value such as `1.2K`, `3.4M`, or `5B`.   |
| `likely_rounded`  | TikTok public data exposed a large bucketed integer that is probably already rounded. |
| `unavailable`     | The public source did not expose that metric.                                         |

`postMetricStatus` and `profileMetricStatus` show metric-by-metric status and
precision. The top-level metric columns hold the counts.

When both a compact display count and a full integer are present, the Actor
prefers the full integer. It does not emit derived engagement-rate columns.
Calculate rates downstream from the returned counts and precision labels if you
need them.

### 🚦 Output statuses

| Status                       | Meaning                                                                        |
| ---------------------------- | ------------------------------------------------------------------------------ |
| `ok`                         | At least one public engagement metric was collected.                           |
| `resolved_no_public_metrics` | The URL resolved, but public sources did not expose engagement counts.         |
| `blocked_or_challenged`      | TikTok returned a challenge, login wall, or access page before metrics loaded. |
| `invalid_url`                | The input is not a valid TikTok URL or `@handle`.                              |
| `unsupported_url`            | The input is a valid TikTok URL, but that TikTok surface is not supported.     |
| `failed`                     | A request, parser, or runtime error happened.                                  |

### 🧭 Practical notes

This Actor collects public TikTok data only. It does not use login, cookies,
private accounts, or private content access.

Profile discovery is best effort. Some profiles expose profile metrics but not
recent public video URLs in the public surfaces available at run time.

TikTok counts change continuously. Treat each run as a point-in-time snapshot.
For monitoring, schedule repeated runs and compare rows by `postId` and
`scrapedAt`.

For large TikTok URL lists, split work into smaller runs. This keeps retries,
timeouts, and result inspection easier to manage.

### ❓ Common questions

#### Can this scrape TikTok saves and reposts?

The dataset includes fields for `saves` and `reposts`. The Actor
collects them when TikTok exposes those metrics in public page data. If TikTok
does not expose them for a specific video, the fields are marked unavailable
with `postMetricStatus`.

#### Can this scrape TikTok comments?

This Actor collects the public comment count. It does not scrape comment text,
comment authors, or comment threads.

#### Can this scrape TikTok followers?

Yes, when TikTok exposes public profile metrics. The Actor can return follower,
following, total likes, and video counts for the creator profile.

#### Can I use it for TikTok competitor tracking?

Yes. Paste public competitor video URLs, profile URLs, or handles, then schedule
the Actor to collect repeat metric snapshots over time.

#### Can I run it through the Apify API?

Yes. The Actor is designed for both Apify Console runs and API workflows. Use
the flat output rows for dashboards, data warehouses, exports, and monitoring
pipelines.

#### Why are some metrics unavailable?

TikTok does not expose every metric on every public surface. When a metric is
missing, the Actor keeps the row, marks the metric unavailable, and includes
status fields so your pipeline can handle the row cleanly.

# Actor input Schema

## `mode` (type: `string`):

Choose how to use the inputs below. Auto-detect accepts video URLs, profile URLs, and @handles in the same list.

## `startUrls` (type: `array`):

Paste public TikTok video URLs, mobile/share URLs, profile URLs, or @handles. The actor combines direct videos and discovered profile videos, deduplicates them, and applies one shared metric row cap.

## `urls` (type: `array`):

Backward-compatible hidden field for API users that send known TikTok video URLs as urls.

## `profileUrls` (type: `array`):

Backward-compatible hidden field for API users that send TikTok profile URLs or @handles as profileUrls.

## `maxItems` (type: `integer`):

Maximum number of video metric rows to collect across direct video URLs and videos discovered from profiles.

## `maxItemsPerProfile` (type: `integer`):

Maximum number of public video URLs to discover from each TikTok profile URL or @handle. The shared cap still limits total output rows.

## `includeProfileMetrics` (type: `boolean`):

Add best-effort public profile follower, following, total likes, and video counts when TikTok exposes them in public page data.

## `includeAuthorProfileMetrics` (type: `boolean`):

Backward-compatible hidden field for API users that send includeAuthorProfileMetrics.

## `requestTimeoutSecs` (type: `integer`):

Maximum seconds to wait for each public TikTok request.

## `maxConcurrency` (type: `integer`):

Maximum number of TikTok URLs to resolve at the same time.

## `failOnNoMetrics` (type: `boolean`):

Fail the run if none of the input URLs expose public metrics. Individual URLs without metrics still emit rows with structured statuses.

## Actor input object example

```json
{
  "mode": "auto",
  "startUrls": [
    "https://www.tiktok.com/@mrbeast/video/7654638524729216287"
  ],
  "urls": [],
  "profileUrls": [],
  "maxItems": 25,
  "maxItemsPerProfile": 20,
  "includeProfileMetrics": true,
  "requestTimeoutSecs": 20,
  "maxConcurrency": 3,
  "failOnNoMetrics": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `output` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://www.tiktok.com/@mrbeast/video/7654638524729216287"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chronometrica/tiktok-metrics-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": ["https://www.tiktok.com/@mrbeast/video/7654638524729216287"] }

# Run the Actor and wait for it to finish
run = client.actor("chronometrica/tiktok-metrics-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.tiktok.com/@mrbeast/video/7654638524729216287"
  ]
}' |
apify call chronometrica/tiktok-metrics-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=chronometrica/tiktok-metrics-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Metrics Scraper - Video & Profile Stats",
        "description": "Scrape public TikTok video and profile metrics from video URLs, share links, profile URLs, and @handles. Collect views, likes, comments, shares, saves, reposts, profile stats, IDs, captions, hashtags, music, timestamps, precision labels, provenance, and clean CSV/API rows.",
        "version": "0.1",
        "x-build-id": "zowXlWpAubFWigtU5"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/chronometrica~tiktok-metrics-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-chronometrica-tiktok-metrics-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/chronometrica~tiktok-metrics-scraper/runs": {
            "post": {
                "operationId": "runs-sync-chronometrica-tiktok-metrics-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/chronometrica~tiktok-metrics-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-chronometrica-tiktok-metrics-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "mode": {
                        "title": "Input handling",
                        "enum": [
                            "auto",
                            "knownUrls",
                            "profileUrls"
                        ],
                        "type": "string",
                        "description": "Choose how to use the inputs below. Auto-detect accepts video URLs, profile URLs, and @handles in the same list.",
                        "default": "auto"
                    },
                    "startUrls": {
                        "title": "TikTok URLs or @handles",
                        "minItems": 0,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Paste public TikTok video URLs, mobile/share URLs, profile URLs, or @handles. The actor combines direct videos and discovered profile videos, deduplicates them, and applies one shared metric row cap.",
                        "items": {
                            "type": "string",
                            "pattern": "^\\s*(?:(?:https?:\\/\\/)?(?:(?:www\\.|m\\.|vm\\.|vt\\.)?tiktok\\.com)\\/\\S+|@[A-Za-z0-9._-]+|[A-Za-z0-9._-]+)\\s*$"
                        },
                        "default": [
                            "https://www.tiktok.com/@mrbeast/video/7654638524729216287"
                        ]
                    },
                    "urls": {
                        "title": "Legacy video URLs",
                        "type": "array",
                        "description": "Backward-compatible hidden field for API users that send known TikTok video URLs as urls.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "profileUrls": {
                        "title": "Legacy profile URLs",
                        "type": "array",
                        "description": "Backward-compatible hidden field for API users that send TikTok profile URLs or @handles as profileUrls.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "maxItems": {
                        "title": "Metric rows to collect (shared cap)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of video metric rows to collect across direct video URLs and videos discovered from profiles.",
                        "default": 25
                    },
                    "maxItemsPerProfile": {
                        "title": "Videos to discover per profile",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of public video URLs to discover from each TikTok profile URL or @handle. The shared cap still limits total output rows.",
                        "default": 20
                    },
                    "includeProfileMetrics": {
                        "title": "Add profile metrics",
                        "type": "boolean",
                        "description": "Add best-effort public profile follower, following, total likes, and video counts when TikTok exposes them in public page data.",
                        "default": true
                    },
                    "includeAuthorProfileMetrics": {
                        "title": "Legacy profile metrics flag",
                        "type": "boolean",
                        "description": "Backward-compatible hidden field for API users that send includeAuthorProfileMetrics."
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout",
                        "minimum": 5,
                        "type": "integer",
                        "description": "Maximum seconds to wait for each public TikTok request.",
                        "default": 20
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of TikTok URLs to resolve at the same time.",
                        "default": 3
                    },
                    "failOnNoMetrics": {
                        "title": "Fail when no metrics are exposed",
                        "type": "boolean",
                        "description": "Fail the run if none of the input URLs expose public metrics. Individual URLs without metrics still emit rows with structured statuses.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
