# TikTok Anonymous For You Feed Snapshot Scraper (`vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-scraper`) Actor

Capture a snapshot of posts currently surfacing on TikTok's anonymous For You feed, with engagement stats, author, music, and hashtag details for each video or slideshow.

- **URL**: https://apify.com/vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-scraper.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TikTok Anonymous For You Feed Snapshot Scraper

TikTok's For You feed is a moving recommendation stream. This actor captures an anonymous snapshot of the posts surfacing on it — no account, cookies, or login — and returns the ranking, engagement counts, creator details, music, video metadata, subtitles, tagged places, and category labels for each post.

### What this actor does

- Collects posts from TikTok's anonymous For You feed, starting with the warm page payload and extending the snapshot across fresh anonymous sessions.
- Deduplicates by post ID and stops when the requested count is reached or the rotating feed stops producing new posts.
- Labels each post with its snapshot `rank`, `collectedAt`, and a derived `engagementRate`.
- Supports a best-effort `region` market hint, plus client-side filters for minimum plays, recency, and ads.
- Omits fields a post does not carry instead of writing nulls or placeholders.
- Falls back to a headless browser only when the lightweight collection path returns nothing.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `maxItems` | integer | `30` | Maximum posts to collect (0–300). `0` returns no rows. |
| `region` | select | `AUTO` | `AUTO` follows the connection region. A market code (40 supported markets) asks TikTok for that market and uses a matching exit when available; TikTok may still override the hint. |
| `minPlayCount` | integer | `0` | Drop posts below this play count. `0` disables the filter. |
| `postedWithinDays` | integer | `0` | Keep only posts created in the last N days (0–365). `0` disables the filter. |
| `excludeAds` | boolean | `false` | Remove posts TikTok marks as advertisements. |

#### Example: quick US snapshot

```json
{
  "maxItems": 20,
  "region": "US"
}
```

#### Example: recent high-reach posts, no ads

```json
{
  "maxItems": 50,
  "region": "GB",
  "minPlayCount": 100000,
  "postedWithinDays": 7,
  "excludeAds": true
}
```

#### Example: daily trend check

```json
{
  "maxItems": 40,
  "region": "AUTO",
  "postedWithinDays": 1
}
```

Saved tasks that still send the old `regionObservation` key keep working: when `region` is absent, a supported `regionObservation` value is used as the market hint. Other values are kept only as the informational `observedRegion` label.

### Output per post

| Field | Description |
|---|---|
| `rank` | 1-based position in this snapshot after filters. |
| `postId` | TikTok's unique post ID. |
| `postUrl` | Direct URL to the post. |
| `postType` | `"video"` or `"slideshow"`. |
| `caption` | Caption text, including hashtags and mentions as typed. |
| `feedType` | Always `"foryou"` for this actor. |
| `observedRegion` | Requested market label, or `AUTO` when following the connection region. |
| `isPersonalized` | Always `false` — the feed is anonymous. |
| `createTime` | Unix timestamp when the post was created. |
| `createdAt` | Creation time as an ISO 8601 UTC string. |
| `collectedAt` | Collection time as an ISO 8601 UTC string. |
| `locationCreated` | Country code where the post was created, when the source provides it. |
| `playCount` / `likeCount` / `commentCount` / `shareCount` / `collectCount` / `repostCount` | Engagement counters, preferring TikTok's exact string counters. |
| `engagementRate` | `(likes + comments + shares) / plays`, rounded to four decimals. |
| `textLanguage` | Language code detected for the caption. |
| `textTranslatable` | Whether TikTok offers a caption translation. |
| `stitchEnabled` / `duetEnabled` / `shareEnabled` | Whether each interaction type is enabled. |
| `isAd` / `adAuthorization` | Ad-related flags. |
| `isAigc` / `aigcLabelType` | AI-generated-content labels when TikTok provides them. |
| `categoryType` | TikTok's numeric content category. |
| `diversificationId` / `diversificationLabels` | Feed diversification metadata when present. |
| `author` | Object: `id`, `secUid`, `username`, `displayName`, `bio`, `verified`, `privateAccount`, `roomId`, `avatarUrl`, `followerCount`, `followingCount`, `heartCount`, `videoCount`. |
| `music` | Object: `id`, `title`, `authorName`, `original`, `duration`, `album`, `playUrl`, `coverUrl`. |
| `video` | Object: `width`, `height`, `duration`, `ratio`, `definition`, `codecType`, `format`, `size`, `quality`, `playUrl`, `cover`, `originCover`, `dynamicCover`, `subtitles[]` (`languageCode`, `languageName`, `format`, `url`, `expiresAt`). |
| `poi` | Tagged place when present: `id`, `name`, `address`, `category`, `city`, `cityCode`, `countryCode`, `province`, `latitude`, `longitude`. |
| `itemControl` | Interaction permissions: `canComment`, `canRepost`, `canShare`, `canMusicRedirect`, `canCreatorRedirect`. |
| `hashtags` | Array of `{id, name, isCommerce}` objects. |
| `mentions` | Array of `{username, start, end, awemeId}` objects. |
| `images` | Slideshow image URLs for photo posts. |
| `mediaUrlExpiresAt` | ISO 8601 UTC time when signed media URLs expire. |

### Use cases

- **Trend researchers** tracking which formats, sounds, and creators the recommendation engine is surfacing.
- **Brand and sponsorship teams** spotting promoted posts and ad labels in an organic feed.
- **Competitive intelligence** comparing creator reach and engagement across markets.
- **Academic researchers** building anonymous feed snapshots for content-distribution studies.
- **Media and dashboard teams** feeding live trend monitoring with ranked post data.

### FAQ

**Q: Do I need a TikTok account or cookies?**\
A: No. The actor works as an anonymous visitor. It accepts no credentials, session IDs, API keys, or proxy configuration.

**Q: Can I choose a specific country's feed?**\
A: `region` is a best-effort hint. TikTok decides the feed from the connection location, so a selected market may be partially or fully overridden. The actor reports the requested label in `observedRegion` and never fabricates a detected country.

**Q: How many posts can I get in one run?**\
A: You can request up to 300. The anonymous feed rotates and has no resumable cursor; one fresh session usually yields around 20–25 unique posts, so deeper requests rotate sessions. If the source exhausts first, the run reports the honest delivered count.

**Q: Why did I get fewer posts than `maxItems`?**\
A: Either TikTok stopped serving new posts, the run reached its bounded session search cap, or the active filters removed them. The status message states which case applies and how many posts were filtered out.

**Q: Will two runs return the same posts?**\
A: Not necessarily. Each run negotiates fresh anonymous sessions, so the snapshot changes over time.

**Q: Are media links permanent?**\
A: No. Video, cover, and subtitle URLs are signed and expire, usually within about two days. `mediaUrlExpiresAt` records the expiry where it can be parsed; use `postUrl` as the stable reference.

**Q: Why are some fields missing on some posts?**\
A: TikTok only includes fields such as `poi`, `locationCreated`, subtitles, or music album for some posts. Empty values are omitted rather than written as null.

**Q: Does this return personalized recommendations?**\
A: No. The feed is an anonymous, non-personalized observation and every row carries `isPersonalized: false`.

### Notes and limits

- The snapshot is a point-in-time observation, not a replayable list. Posts may repeat across sessions and are deduplicated by ID.
- A deep request is bounded by a session search cap. If the cap is reached first, the status message says so instead of claiming the source is exhausted.
- `locationCreated` is supplied mainly by the initial page payload and is absent for most API-served posts.
- Region selection can consume Apify Proxy traffic when a matching datacenter exit is available; `AUTO` uses the connection directly.
- Signed media URLs should be refreshed by re-running the actor when they expire.

# Actor input Schema

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

Maximum number of For You posts to collect. Set to 0 to return no items.

## `region` (type: `string`):

Market hint for the feed. AUTO follows the connection region. A selected market asks TikTok for that market and uses a matching datacenter exit when one is available; TikTok may still override the hint.

## `minPlayCount` (type: `integer`):

Drop posts with fewer plays than this value. 0 disables the filter.

## `postedWithinDays` (type: `integer`):

Only keep posts created in the last N days. 0 disables the filter.

## `excludeAds` (type: `boolean`):

Drop posts that TikTok marks as advertisements.

## Actor input object example

```json
{
  "maxItems": 3,
  "region": "AUTO",
  "minPlayCount": 0,
  "postedWithinDays": 0,
  "excludeAds": false
}
```

# Actor output Schema

## `data` (type: `string`):

Dataset containing TikTok For You feed post records. Each row includes rank, postId, postUrl, caption, feedType, observedRegion, isPersonalized, engagement counts and rate, collectedAt, author, music, video, subtitles, POI, hashtags, and category labels.

# 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 = {
    "maxItems": 3,
    "region": "AUTO",
    "minPlayCount": 0,
    "postedWithinDays": 0,
    "excludeAds": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-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 = {
    "maxItems": 3,
    "region": "AUTO",
    "minPlayCount": 0,
    "postedWithinDays": 0,
    "excludeAds": False,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "maxItems": 3,
  "region": "AUTO",
  "minPlayCount": 0,
  "postedWithinDays": 0,
  "excludeAds": false
}' |
apify call vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/tiktok-anonymous-for-you-feed-snapshot-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/P50cIhupfxfmYN9hW/builds/IewtZ1qwYr8qhwUl2/openapi.json
