TikTok API endpoint
Returns one page of the videos posted at a place, keyed by the `poi_id` that the place search endpoint returns. The upstream is `/tiktok/poi/video/list/v1`: `aweme_list` holds the app's full video objects (id, description, author, statistics, media URLs, music, anchors, ...) and `item_count` is this page's size. Page with `cursor`: the returned `cursor` is a reusable next-page token (measured page 1 `cursor: 20` with `has_more: 1`, page 2 `cursor: 40`), never with arithmetic on `count`. `count` is a page-size hint, not a strict size: 1/2/5 returned exactly that many items on the first page, a later page returned 8 for count=5, and 10/20/50 were all server-capped at 17. Measured 2026-10-21 with the pure-Go (device-free) signer: 11 videos (940-944 KB) on one place, 17 videos (1.4 MB) on another. The route exposes no sort control: `sort_type` and `order` were measured and did not change the page or its order. The upstream throttles bursts, so paced clients are expected. The route is not signature-gated, so it does not need the device-backed signer.
/tiktok/mobile/place/videosOne page of the videos posted at a place, keyed by the poi_id the place search endpoint returns. The upstream
is GET /tiktok/poi/video/list/v1, captured from the running 47.4.3 app on the place detail screen and reproduced
end-to-end against the live gateway. Each aweme_list entry is the app's full video object (id, description,
author, statistics, media URLs, music, anchors, ...), so this is the paged complement to the fixed
top-videos/posts strips the place detail page embeds.
Page with cursor, not with count. The response's cursor is a reusable next-page token: it was measured
returning a fresh page every time (cursor: 20 -> page 2 with cursor: 40, has_more: 1; a live cursor: 5
page returned 8 new videos with cursor: 15). count is a page-size hint, not a strict size: 1/2/5 returned
exactly that many items on the first page, a later page returned 8 for count=5, and 10/20/50 were all
server-capped at 17 items. Stop when has_more is false.
No sort control. sort_type and order were measured and did not change the page or its order, so no sort
parameter is exposed. Order is the upstream's own ranking.
Device-free. The pure-Go placeholder signer returned the same pages, so a deployment needs
TIKTOK_MOBILE_PARAMS but not the device-backed signer (TIKTOK_MOBILE_SIGNER_URL). It answers on the core
aggr16-normal.tiktokv.us / api16-normal-useast5.tiktokv.us pair.
Query parameters:
poi_id: required. The numeric place id from /api/v1/tiktok/mobile/search/place.count: optional. Page-size hint, 1–50 accepted; omitted means the app default. See the paging note above.cursor: optional. The cursor from the previous response; 0/omitted is the first page.Errors:
poi_id is missing, non-numeric, or does not resolve (upstream business status 3009009
"poi not exist"), or count/cursor are out of range.Measured 2026-10-21 (placeholder/device-free signer, core pair):
| call | result |
|---|---|
poi_id=42203861086875992 | 11 videos (940–944 KB), cursor: 13, has_more: 0 |
poi_id=21568226355448582, count=10 | 17 videos (1.4 MB), cursor: 20, has_more: 1 |
same place, count=5 then cursor=5 | page 1: 5 videos cursor: 5; page 2: 8 new videos cursor: 15, has_more: 1 |
same place, count=10 / 20 / 50 | all returned the 17-item page (server cap) |
same place, count=1 / 2 / 5 | 1 / 2 / 5 items exactly (first page) |
sort_type=1, sort_type=2, order=1 | same page and order as the default call |
poi_id=1 | upstream status 3009009 "poi not exist" → 400 |
| shipped-service canary | items=5 cursor=5 has_more=true, 1.06 s |
Example request:
GET /api/v1/tiktok/mobile/place/videos?poi_id=21568226355448582&count=5
Example response (truncated):
{
"code": 200,
"msg": "OK",
"data": {
"poi_id": "21568226355448582",
"aweme_list": [
{
"aweme_id": "7381867551816469803",
"desc": "lychee green tea @Nam Coffee 👌🏼",
"author": {"unique_id": "amanda.bynes_"},
"statistics": {"digg_count": 15068, "comment_count": 42, "play_count": 2668020, "share_count": 1569}
}
],
"item_count": 5,
"cursor": 5,
"has_more": true,
"host": "aggr16-normal.tiktokv.us",
"fetched_at": "2026-10-21T16:30:12Z"
}
}
Notes for callers:
item_count is this page's length; the place's own video_count field (see
place info) is the app's counter and does not match the list — one measured place
reported video_count: 0 with 17 videos available.poi_info appears on some pages only, so it is optional in the response.| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| x-api-key (header) | string | Yes | API key required | ||
| poi_id | string | Yes | Place id from the place search endpoint | 42203861086875992 | |
| count | integer | No | Page-size hint: 1-50 measured, server caps larger pages (default is the app default) | 10 | |
| cursor | integer | No | Next-page token from the previous response (0 = first page) | 0 |
curl -X GET "https://api.crawlora.net/api/v1/tiktok/mobile/place/videos?poi_id=42203861086875992&count=10" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"poi_id": "21568226355448582",
"aweme_list": [
{
"aweme_id": "7381867551816469803",
"desc": "lychee green tea @Nam Coffee 👌🏼",
"author": {
"unique_id": "amanda.bynes_"
},
"statistics": {
"digg_count": 15068,
"comment_count": 42,
"play_count": 2668020,
"share_count": 1569
}
}
],
"item_count": 5,
"cursor": 5,
"has_more": true,
"host": "aggr16-normal.tiktokv.us",
"fetched_at": "2026-10-21T16:30:12Z"
}
}Request schema
No body schema
Response schema
#/definitions/tiktokmobile.placeVideosResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| aweme_list | array | No | ||||
| cursor | integer | No | 20 | |||
| fetched_at | string | No | ||||
| has_more | boolean | No | true | |||
| host | string | No | aggr16-normal.tiktokv.us | |||
| item_count | integer | No | 17 | |||
| poi_id | string | No | 21568226355448582 | |||
| poi_info | unknown | No |
| Status | Description | Schema |
|---|---|---|
| 400 | Invalid input, or the place id does not exist | #/definitions/app.Response |
| 429 | Rate limit exceeded | #/definitions/app.Response |
| 500 | Internal server error | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/tiktok/mobile/place/videos?poi_id=42203861086875992&count=10" \
-H "x-api-key: $CRAWLORA_API_KEY"