# TikTok Location Scraper: what a place is posting

TikTok Location Scraper takes a TikTok location URL and returns the public posts filed under that place, each with its engagement, its creator and its video and audio metadata.

[Run this scraper free](https://apify.com/apidojo/tiktok-location-scraper)

[See the three jobs](#jobs)

apidojo/tiktok-location-scraper

**Locations**

**Posts returned**

Estimated run cost

$0.00

Free Apify plan: 5 runs a month, 10 items a run. No credit card.

**$0.006** per location queried

**~20** posts included in that

**$0.0003** per post after

**99.98%** run success, last 30 days

Read on 27 September 2026.

## Getting the URL right is most of the work

Three inputs, and only one of them takes thought. TikTok has no separate place page to copy a link from. A location is a tag URL with a flag on the end, and that is the form the actor expects.

-   The flag is the whole trick

    `startUrls`

    $0.006per location

    ~20 posts included

    A tag URL carrying ?location=true. That query string is what turns a hashtag page into a place.

    `https://www.tiktok.com/tag/newyork?location=true`

-   `startUrls (bulk)`

    × $0.006one fee each

    20 free per place

    Many places in one run. The listing puts no cap on how many geographic areas a single run may cover.

    `tag/newyork · tag/miami · tag/austin`

-   `maxItems`

    ÷ $0.0003cap the spend

    1,000 ≈ $0.30

    The ceiling on posts for the entire run. The listing frames it directly as a budget control.

    `1000`

Because the free allowance is per location rather than per run, twenty places at twenty posts each costs $0.12 in query fees and nothing in items, which is the cheapest way to watch a lot of ground at once.

**Apify actor:** apidojo/tiktok-location-scraper

**Inputs:** startUrls · maxItems · customMapFunction

**URL form:** tiktok.com/tag/<place>?location=true, a tag URL with the flag set

**Returns:** Post records. No coordinates, no place name, no location id

**Billing:** $0.006 a location including ~20 posts, then $0.0003 each

**Cheapest useful run:** Six tenths of a cent, for one place and its first page

**Login or proxy:** Neither. Public posts only

**Reliability:** 99.98% of 9,131 runs succeeded in the last 30 days

## One city deep, or many cities wide

The interesting decision here is not what to scrape but how to spread the budget: a thousand posts from one place, or the first twenty from fifty places, cost roughly the same and answer completely different questions.

**01 One place, deep $0.006 + $0.0003 past ~20**

**02 Many places, wide One fee and 20 free per place**

**03 A cheap scan $0.006 a place, items free**

### How do you scrape TikTok posts from a location?

Put one location URL in startUrls. The query costs $0.006 and brings roughly twenty posts with it; everything past that is $0.0003. A thousand posts from a single city comes to $0.30.

Input

```
{
  "startUrls": [
    "https://www.tiktok.com/tag/newyork?location=true"
  ],
  "maxItems": 1000
}
```

$0.006 + 980 × $0.0003 \= **$0.30**

What comes back

The **post record**, A full post with its creator attached, and nothing naming the place.

```
{
  "id": "7310663737562631457",
  "title": "#duet with @The Tus House…",
  "views": 2597080,
  "likes": 200239,
  "comments": 894,
  "shares": 493,
  "bookmarks": 5597,
  "hashtags": ["duet", "steak", "egg"],
  "postPage": "https://www.tiktok.com/@gordonramsayofficial/video/7310663737562631457"
}
```

Nothing in the row says where it came from

The output carries no coordinates, no place name and no location id. On a single-location run that costs you nothing, because the answer is the input. It becomes a problem the moment you put a second URL in the list.

### How do you compare several locations at once?

You can list fifty location URLs in one run, but the dataset will not tell you which row came from which place. Run them separately, one location per run, and label the output yourself. The cost is identical either way.

Input

```
{
  "startUrls": [
    "https://www.tiktok.com/tag/miami?location=true"
  ],
  "maxItems": 200
}
```

10 × $0.006 + 1,800 × $0.0003 \= **$0.60**

What comes back

The **creator block**, Follower counts on every row, which is how local creators surface.

```
{
  "channel": {
    "name": "Gordon Ramsay",
    "username": "gordonramsayofficial",
    "url": "https://www.tiktok.com/@gordonramsayofficial",
    "verified": false,
    "followers": 39745807,
    "following": 513,
    "videos": 451
  }
}
```

One location per run is the cheap fix

Since billing is per location either way, splitting a ten-city sweep into ten runs costs exactly what one combined run costs, and each dataset then has an unambiguous place attached to it. Ten cities at 2,000 posts is $0.60 whichever way you slice it.

### What is the cheapest way to monitor a lot of places?

Take only the free page. Each location costs $0.006 and includes about twenty posts, so twenty places scanned at their first page is $0.12 total with no item charges at all, a standing weekly sweep for the price of a coffee a year.

Input

```
{
  "startUrls": [
    "https://www.tiktok.com/tag/austin?location=true"
  ],
  "maxItems": 20
}
```

20 × $0.006 \= **$0.12**

What comes back

The **video and sound**, Duration, resolution and the track, enough to spot a format spreading locally.

```
{
  "video": {
    "width": 648,
    "height": 576,
    "ratio": "540p",
    "duration": 57.399
  },
  "song": {
    "title": "original sound - thetushouse",
    "artist": "The Tus House",
    "duration": 64
  }
}
```

Roughly twenty, not exactly twenty

The listing says "~20 posts" and calls it the first page, so treat the allowance as approximate rather than a contract. Setting maxItems to 20 keeps a scan inside it; setting it to 25 risks a few cents of items across a large sweep.

## What a place-filed post looks like

Four blocks, and the listing documents all thirty-two fields by name. The notable thing is what is not in the list: there is no geographic block, because the geography was the question rather than part of the answer.

-   8

    Post and reach

    The row itself

    -   id, title
    -   views, likes, comments
    -   shares, bookmarks
    -   hashtags
    -   postPage
-   9

    Creator

    channel

    -   name, username, id, url
    -   avatar
    -   verified
    -   followers, following
    -   videos
-   7

    Video file

    video

    -   width, height, ratio
    -   duration
    -   url, direct download
    -   cover, thumbnail
-   0

    Geography

    Not returned

    -   No latitude or longitude
    -   No place name or location id
    -   Provenance is the URL you sent

**id · title:** Post ID and caption text

**views · likes · comments:** Headline engagement counters

**shares · bookmarks:** Saves and shares, the two that predict local spread best

**hashtags:** Array of tags on the post, place tag included where used

**postPage:** Canonical link to the post

**uploadedAt · uploadedAtFormatted:** Unix seconds and the same moment in ISO 8601

**channel.username · name · id:** Who posted it

**channel.followers · following · videos:** Their reach and output, how a local creator is told from a visiting one

**channel.verified:** Verification status on the creator

**video.duration · ratio:** Length in seconds and served resolution

**video.url:** Direct download URL for the file itself

**video.cover · thumbnail:** Still imagery for the post

**song.title · artist · album:** The audio track behind the post

**song.id · duration · cover:** Enough to pivot into the Music Scraper on a sound that is spreading

channel.followers is the field that does the work on a location run. A place’s feed mixes residents with tourists and with national accounts passing through; follower count and video count are the cheapest way to tell which is which.

## Four things to know before the first run

Two come from the listing’s input documentation, one from its pricing section, and one from the shape of the output itself.

-   01

    The URL needs ?location=true on it

    The listing gives the form as tiktok.com/tag/<place\>?location=true. Without the flag it is an ordinary hashtag URL, which is a different query against different content.

-   02

    The free allowance is per location, not per run

    Each location query includes roughly the first page of about twenty posts. Ten locations means ten allowances, which is why a wide sweep is so much cheaper per place than a deep dive.

-   03

    Label your own provenance

    Nothing in a row names the place. Run one location at a time, or tag the dataset on the way out, if you ever intend to compare places against each other.

-   04

    Never filter inside customMapFunction

    The listing is explicit that the map function is for transformation and that filtering with it may result in automatic bans. Use maxItems to control volume instead.

Free accounts run in demo mode: 5 runs a month, 10 items each.

## Six worked examples, checked

These are the listing’s own figures, recomputed from the two charge events. All six reproduce exactly, $0.006 a location with about twenty posts inside it, then $0.0003 for each post beyond.

| Run | Method | Calculation | Cost |
| --- | --- | --- | --- |
| 20 posts | 1 location, the free page | $0.006 | $0.006 |
| 100 posts | 1 location | $0.006 + 80 × $0.0003 | $0.03 |
| 500 posts | 5 locations | 5 × $0.006 + 400 × $0.0003 | $0.15 |
| 1,000 posts | 1 location, deep | $0.006 + 980 × $0.0003 | $0.30 |
| 2,000 posts | 10 locations | 10 × $0.006 + 1,800 × $0.0003 | $0.60 |
| 10,000 posts | 10 locations, deep | 10 × $0.006 + 9,800 × $0.0003 | $3.00 |

Compare the third row against the fourth: five hundred posts spread over five cities cost half what a thousand from one city cost, because four extra allowances came with the four extra queries. Breadth is subsidised here in a way depth is not.

## Who works a map instead of a feed?

The listing points at local creator discovery, regional content leaders and geographic market research. What they have in common is a question about a place that a hashtag cannot answer, because a hashtag is a topic and a location is an address.

-   Local influencer scouting

    One place, deep

    Find creators posting from a city and separate residents from national accounts by follower count and output

    $0.30 per 1,000 posts

-   Regional market research

    Many places, one run each

    Compare what different cities post about, with each dataset labelled by the URL that produced it

    $0.60 across 10 cities

-   Tourism and destination marketing

    A cheap scan, weekly

    Watch the first page of a destination tag on a schedule, paying only the query fee

    $0.12 per 20-place sweep

-   Venue and hospitality

    One place, shallow

    See what is being filmed at a location without commissioning anything, six tenths of a cent a look

    $0.006 per check

-   Trend spotting

    A cheap scan, then pivot

    Catch a sound recurring across a city’s posts, then take song.id into the Music Scraper

    $0.03 per 100-post probe

## Automating a sweep

The actor is apidojo/tiktok-location-scraper. Because the rows arrive without a place on them, the pattern worth writing once is the loop that runs each location on its own and stamps the result.

**Python**

**JavaScript**

**cURL**

```
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
ACTOR = "apidojo/tiktok-location-scraper"

def place_url(slug):
    return f"https://www.tiktok.com/tag/{slug}?location=true"

def sweep(slugs, per_place=20):
    """One run per place: billing is identical and provenance survives."""
    out = []
    for slug in slugs:
        run = client.actor(ACTOR).call(run_input={
            "startUrls": [place_url(slug)],
            "maxItems": per_place,
        })
        for row in client.dataset(run.default_dataset_id).iterate_items():
            out.append({**row, "place": slug})   # the field the actor cannot give you
    return out

rows = sweep(["newyork", "miami", "austin"])

for r in rows:
    print(r["place"], r["channel"]["followers"], r["views"], r["title"][:40])
```

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const placeUrl = (slug) => `https://www.tiktok.com/tag/${slug}?location=true`;

const run = await client.actor('apidojo/tiktok-location-scraper').call({
  startUrls: [placeUrl('newyork')],
  maxItems: 1000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();

// A place's feed mixes locals with national accounts passing through.
const locals = items.filter((p) => p.channel.followers < 100_000);
console.log(locals.length, 'of', items.length, 'from smaller accounts');
```

```
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~tiktok-location-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.tiktok.com/tag/newyork?location=true"],"maxItems":20}'
```

The listing quotes 400–600 posts per second, so a deep single-city run finishes in seconds. Export as JSON, CSV or Excel from the Storage tab, or read it straight off the API.

## TikTok Location Scraper FAQ

### What does a TikTok location URL look like?

It is a tag URL with a flag: https://www.tiktok.com/tag/newyork?location=true. The ?location=true part is what makes TikTok treat the page as a place rather than a hashtag.

### How much does it cost to scrape a TikTok location?

$0.006 for the location query, which includes roughly the first twenty posts, then $0.0003 for each post after that. A thousand posts from one place is $0.30.

### Does the output include coordinates or a place name?

No. The records are ordinary post objects with no geographic fields at all. You know where they came from because of the URL you submitted, so label the data yourself if you are comparing places.

### Can I scrape several locations in one run?

Yes, and the listing puts no cap on how many. But because no row names its place, running one location per run costs exactly the same and keeps the provenance intact.

### What is the cheapest useful run?

Six tenths of a cent. One location query at $0.006 brings about twenty posts with it and no item charges, which makes a wide shallow sweep unusually cheap.

### Is a location the same as a hashtag?

No. The URL is built from a tag path, but the location flag returns posts filed against the place rather than everything using the word as a topic.

### Can I find local creators with it?

That is the common use. Every row carries the creator’s follower count, following count and total videos, which is how residents get separated from national accounts appearing in the same feed.

### How fast is it?

The listing states 400–600 posts per second.

## Where TikTok Location Scraper fits

[Parent scraper TikTok Scraper Six TikTok scrapers, each entered through a different door, a handle, a post, a sound, a place. This is the geographic one, and the only member of the family whose first twenty results are free.](/scrapers/tiktok-scraper/)

Sibling scrapers

-   [TikTok Profile Scraper](/scrapers/tiktok-profile-scraper/)
-   [TikTok Comments Scraper](/scrapers/tiktok-comments-scraper/)
-   [TikTok User Scraper](/scrapers/tiktok-user-scraper/)

Guides

-   Telling locals from tourists in TikTok location data*Coming soon*
-   Running a cheap weekly sweep across 20 cities*Coming soon*
-   Why geotagged posts arrive without a geotag*Coming soon*

## Check one place

Six tenths of a cent, and the first page comes with it.

`startUrls: ["…/tag/newyork?location=true"] · maxItems: 20`

[Run this scraper free](https://apify.com/apidojo/tiktok-location-scraper)

Apidojo is not affiliated with TikTok or ByteDance.

## Guides for this scraper

-   [TikTok scraping guides Pulling posts, comments, sounds and places from TikTok: which door each scraper goes in by, what a run costs, and what the output does not contain.](/blog/tiktok/)
-   [Why geotagged TikTok posts arrive without a geotag TikTok Location Scraper returns posts filed under a place, and not one field in the output names that place. Here is how to keep the provenance.](/blog/tiktok/tiktok-location-provenance/)
