# TikTok Place Posts Scraper (`maximedupre/tiktok-place-posts-scraper`) Actor

Scrape public TikTok place posts from place URLs or IDs. Export captions, creator details, engagement metrics, video links, hashtags, music, and place metadata.

- **URL**: https://apify.com/maximedupre/tiktok-place-posts-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 1,000 place posts

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 place posts scraper for location feeds

TikTok Place Posts Scraper exports public posts from [TikTok](https://www.tiktok.com/) place pages. Paste a TikTok place URL or raw place ID, then get one dataset row per public place-feed post with captions, creator details, engagement metrics, video links, cover images, hashtags, music data, source URLs, place metadata, and scrape timestamps.

Use this TikTok place posts scraper when you need a repeatable export from a specific location or venue feed instead of opening TikTok and copying post data by hand. It is useful for local trend checks, destination research, creator discovery, event monitoring, tourism analysis, venue reporting, and social media research around geo-tagged TikTok content.

For a quick first run, keep the prefilled New York place URL and the default 20-post limit. Once the output shape matches your workflow, add more place URLs or IDs, raise the limits, schedule repeat runs, or call the Actor through the Apify API.

### ✅ What this Actor does

- Accepts TikTok place URLs such as `https://www.tiktok.com/place/New-York-22535796481546927`.
- Accepts raw TikTok place IDs such as `22535796481546927`.
- Saves one dataset row per public post returned from the place feed.
- Adds post URLs, captions, creation timestamps, source position, and TikTok post IDs.
- Adds creator fields such as username, display name, profile URL, avatar, verification status, bio text, and visible profile stats when TikTok exposes them.
- Adds place fields such as place ID, name, address, category, city, country, place URL, and visible video count when available.
- Adds visible engagement metrics such as views, likes, comments, shares, bookmarks, total engagement, and engagement rate.
- Adds video and music metadata such as media URLs, cover URLs, duration, dimensions, sound title, sound author, and original-sound flags when available.
- Can deduplicate repeated TikTok post IDs across multiple place inputs.
- Skips invalid, unavailable, empty, or temporarily inaccessible place targets without saving failure rows.

The Actor focuses on public TikTok place feeds. It does not scrape private posts, comments, followers, profiles, hashtags, search results, TikTok Shop, or arbitrary keyword searches.

### 📊 Data you can export

Each output item represents one public TikTok post found for one place target. Core fields include:

- `inputTarget`, `sourcePlaceId`, `resolvedPlaceId`, and `resolvedPlaceUrl`
- `sourcePosition`, `postId`, `postUrl`, `caption`, `createdAt`, and `createdAtIso`
- `author` with username, display name, profile URL, avatar URL, verification status, signature, and visible stats
- `place` with ID, name, address, category, city, country, URL, and visible video count
- `engagement` with view, like, comment, share, bookmark, total engagement, and engagement rate fields
- `video` with media URLs, cover URLs, duration, dimensions, format, bitrate, and size when available
- `music` with sound ID, title, author, duration, cover URL, play URL, original-sound flag, and copyright flag when available
- `hashtags`, top-level engagement fields, language hints, ad flag, and `scrapedAt`

You can open the dataset in Apify, export it as JSON, CSV, Excel, XML, RSS, or HTML, use the dataset API, schedule runs, or send results to webhooks and integrations.

### 🚀 How to run it

1. Add one or more TikTok place URLs or raw place IDs in **TikTok place URLs or IDs**.
2. Keep **Posts per place** at `20` for a small first run, or raise it for larger exports.
3. Optionally set **Total posts** to cap the whole run across all places.
4. Leave **Deduplicate posts** on unless you want duplicate post IDs preserved across overlapping place inputs.
5. Keep **Include raw TikTok item** off for cleaner exports, or turn it on when you need source-level auditing.
6. Start the Actor and open the dataset.

Good input examples:

```json
{
	"targets": [
		"https://www.tiktok.com/place/New-York-22535796481546927",
		"22535865202704586"
	],
	"maxPostsPerPlace": 20,
	"maxTotalPosts": 40,
	"deduplicatePosts": true,
	"includeRawItem": false
}
````

### 🧾 Output example

```json
{
	"inputIndex": 1,
	"inputTarget": "22535865202704586",
	"sourceTarget": "https://www.tiktok.com/place/Hollywood-22535865202704586",
	"sourcePlaceId": "22535865202704586",
	"resolvedPlaceId": "22535865202704586",
	"resolvedPlaceUrl": "https://www.tiktok.com/place/Hollywood-22535865202704586",
	"sourcePosition": 1,
	"postId": "7631624554200288525",
	"postUrl": "https://www.tiktok.com/@creator/video/7631624554200288525",
	"caption": "Example TikTok place post caption",
	"createdAt": 1780228800,
	"createdAtIso": "2026-05-31T12:00:00.000Z",
	"author": {
		"username": "creator",
		"displayName": "Creator Name",
		"profileUrl": "https://www.tiktok.com/@creator",
		"verified": false
	},
	"place": {
		"id": "22535865202704586",
		"name": "Hollywood",
		"address": "California, United States",
		"url": "https://www.tiktok.com/place/Hollywood-22535865202704586"
	},
	"engagement": {
		"viewCount": 327900000,
		"likeCount": 14000000,
		"commentCount": 120200,
		"shareCount": 1300000,
		"bookmarkCount": 927970,
		"totalEngagement": 16348170,
		"engagementRate": 4.985718
	},
	"video": {
		"durationSeconds": 13,
		"playUrl": "https://...",
		"coverUrl": "https://..."
	},
	"music": {
		"title": "original sound",
		"authorName": "Creator Name"
	},
	"hashtags": ["hollywood", "travel"],
	"scrapedAt": "2026-06-01T00:00:00.000Z"
}
```

Fields can be `null` or empty when TikTok does not expose a value for a specific public post or place.

### 💡 Common use cases

- Monitor TikTok posts tied to a store, hotel, attraction, venue, city, or landmark.
- Find creators posting from a specific place.
- Compare local TikTok engagement around destinations, events, or neighborhoods.
- Build geo-tagged TikTok datasets for social listening, reporting, or content research.
- Export source URLs and post IDs for review, deduping, or follow-up workflows.
- Feed captions, hashtags, creator metadata, and engagement metrics into spreadsheets, dashboards, databases, or AI analysis.

### 💵 Pricing

This Actor uses pay-per-event pricing. One **Place post** event is charged for each public TikTok place post saved to the dataset. Current pricing is `$0.00025` per saved post.

Skipped inputs, invalid place IDs, empty place feeds, and targets that return no usable public posts do not save dataset rows and do not trigger the post event.

### ⚠️ Limits and caveats

- TikTok place feeds can change between runs, so repeated runs may return different posts or ordering.
- The Actor preserves the order returned by TikTok for each place feed.
- Some fields can be missing when TikTok does not expose them publicly.
- Unsupported TikTok URLs are ignored during input normalization.
- Private, removed, region-limited, or temporarily unavailable content is reported in logs rather than saved as placeholder rows.
- The Actor does not require you to provide TikTok cookies, a TikTok login, or a TikTok API key.

### ❓ FAQ

**Can I scrape more than one TikTok place in one run?**\
Yes. Add several place URLs or raw place IDs to `targets`. Use **Total posts** if you want one hard cap across the whole batch.

**Can I use a normal TikTok video URL?**\
No. This Actor is for TikTok place pages and raw place IDs. Use TikTok Video Downloader when you already have specific video URLs.

**Why did my run return zero rows?**\
The place may have no public posts available through TikTok at run time, the place ID may be invalid, or TikTok may not expose that feed publicly from the submitted target.

**Does this Actor download video files?**\
No. It exports TikTok media URLs and metadata. Use TikTok Video Downloader if your workflow needs saved video or audio files.

### 📝 Changelog

- 0.1: Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~tiktok-place-posts-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Other actors

- [TikTok Hashtag Search Scraper ↗](https://apify.com/maximedupre/tiktok-hashtag-search-scraper) - Find hashtag ideas and public hashtag metrics from TikTok keywords or tag URLs.
- [TikTok Keywords Discovery Tool ↗](https://apify.com/maximedupre/tiktok-keywords-discovery-tool) - Export TikTok autocomplete suggestions for content planning and social search research.
- [TikTok Profile Mention Scraper ↗](https://apify.com/maximedupre/tiktok-profile-mention-scraper) - Find public TikTok videos that mention selected profile handles.
- [TikTok Video Downloader ↗](https://apify.com/maximedupre/tiktok-video-downloader) - Download media files from known public TikTok video URLs.
- [TikTok Transcript Scraper ↗](https://apify.com/maximedupre/tiktok-transcript-scraper) - Extract transcripts, captions, subtitles, and video metadata from public TikTok videos.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `targets` (type: `array`):

Add TikTok place URLs such as `https://www.tiktok.com/place/New-York-22535796481546927` or raw place IDs such as `22535796481546927`. Use one item per place; each target is scraped separately.

## `maxPostsPerPlace` (type: `integer`):

Maximum public posts to save from each TikTok place. Keep `20` for a small first export, then raise it after checking the output.

## `maxTotalPosts` (type: `integer`):

Optional cap across all place targets. Leave empty to use the per-place limit for every submitted place.

## `deduplicatePosts` (type: `boolean`):

Skip repeated TikTok post IDs when the same post appears under multiple place inputs.

## `includeRawItem` (type: `boolean`):

Attach the raw TikTok item under `rawItem` for advanced auditing. Keep this off for cleaner tables and smaller exports.

## Actor input object example

```json
{
  "targets": [
    "https://www.tiktok.com/place/New-York-22535796481546927"
  ],
  "maxPostsPerPlace": 20,
  "deduplicatePosts": true,
  "includeRawItem": false
}
```

# Actor output Schema

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

Open the dataset with public TikTok place posts, source links, creator data, engagement metrics, media links, hashtags, music, and place metadata.

# 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 = {
    "targets": [
        "https://www.tiktok.com/place/New-York-22535796481546927"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/tiktok-place-posts-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 = { "targets": ["https://www.tiktok.com/place/New-York-22535796481546927"] }

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-place-posts-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 '{
  "targets": [
    "https://www.tiktok.com/place/New-York-22535796481546927"
  ]
}' |
apify call maximedupre/tiktok-place-posts-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Place Posts Scraper",
        "description": "Scrape public TikTok place posts from place URLs or IDs. Export captions, creator details, engagement metrics, video links, hashtags, music, and place metadata.",
        "version": "0.1",
        "x-build-id": "ixAbTHPmVJX7jnfxb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/maximedupre~tiktok-place-posts-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-maximedupre-tiktok-place-posts-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/maximedupre~tiktok-place-posts-scraper/runs": {
            "post": {
                "operationId": "runs-sync-maximedupre-tiktok-place-posts-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/maximedupre~tiktok-place-posts-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-maximedupre-tiktok-place-posts-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",
                "required": [
                    "targets"
                ],
                "properties": {
                    "targets": {
                        "title": "TikTok place URLs or IDs",
                        "minItems": 1,
                        "maxItems": 500,
                        "type": "array",
                        "description": "Add TikTok place URLs such as `https://www.tiktok.com/place/New-York-22535796481546927` or raw place IDs such as `22535796481546927`. Use one item per place; each target is scraped separately.",
                        "items": {
                            "type": "string",
                            "minLength": 1
                        }
                    },
                    "maxPostsPerPlace": {
                        "title": "Posts per place",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum public posts to save from each TikTok place. Keep `20` for a small first export, then raise it after checking the output.",
                        "default": 20
                    },
                    "maxTotalPosts": {
                        "title": "Total posts",
                        "minimum": 1,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Optional cap across all place targets. Leave empty to use the per-place limit for every submitted place."
                    },
                    "deduplicatePosts": {
                        "title": "Deduplicate posts",
                        "type": "boolean",
                        "description": "Skip repeated TikTok post IDs when the same post appears under multiple place inputs.",
                        "default": true
                    },
                    "includeRawItem": {
                        "title": "Include raw TikTok item",
                        "type": "boolean",
                        "description": "Attach the raw TikTok item under `rawItem` for advanced auditing. Keep this off for cleaner tables and smaller exports.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
