TikTok API endpoint
Returns one place detail page, keyed by the `poi_id` that the place search endpoint returns. The upstream is TikTok's server-driven UI (`/tiktok/poi/slash/v1`) frame stream, assembled here into the component map of the place-detail screen: `food_head_info` (place name, formatted address, category, phone, coordinates, opening hours, rating/score with mention count, price range, tags and photo album), `poi_top_videos` (top videos strip), `poi_limited_post` (posts about the place: full video items plus `aweme_cursor`/`has_more_aweme`), `poi_review` (review preview with `has_more`) and `ai_summary` when the place has one. `nodes` is opaque and complete, `frames` keeps the raw ordered frames, and the typed counters (`top_video_count`, `post_count`, `post_cursor`, `has_more_posts`, `review_count`, `has_more_reviews`) are convenience projections. The measured page-size controls are forwarded with the app's defaults but the server applies its own bounds. The route is not signature-gated, so it does not need the device-backed signer.
/tiktok/mobile/place/detailOne place detail page, keyed by the poi_id the place search endpoint returns. The upstream is TikTok's
server-driven UI (slash) service — GET /tiktok/poi/slash/v1 — captured from the running 47.4.3 app when a
place card in the search screen's Places tab is opened and reproduced end-to-end against the live gateway. This
is the page behind a place card: the header, the top-videos strip, the posts about the place and the review
preview.
Frame stream, assembled for you. The upstream answers the same length-prefixed JSON frame stream the
streaming search route uses (hex byte length, CRLF, JSON payload, CRLF, 0 terminator). This endpoint assembles
all frames: nodes merges every frame's component map (later frames update earlier components), frames keeps
the raw ordered frames, layout merges the frame layouts, and page_id is the SDUI page id.
The node map is the page. The measured component names are:
| node | content |
|---|---|
food_head_info | place header: poi_name, formatted_address, category_name, phone_info, location (lat/lng), store_info (opening hours), recommend_score (score / max_score / mentioned_count / desc), average_price, poi_detail_tags, picture_album (measured 3 photos) |
poi_top_videos | top-videos strip in data.item_list (6–15 items measured per call) |
poi_limited_post | posts about this place in data.item_list (5–9 full video items measured) plus aweme_cursor and has_more_aweme |
poi_review | review preview in data.reviews (0–3 measured) plus has_more |
ai_summary | AI review summary, present on some places only |
Typed counters lift the node data you page or judge a place by: top_video_count, post_count, post_cursor,
has_more_posts, review_count, has_more_reviews.
Device-free. The route is not signature-value gated: the pure-Go placeholder signer returned the same full
page (945,190 B with header, videos, posts and review), so the deployment does not need the device-backed
signer (TIKTOK_MOBILE_SIGNER_URL) for this endpoint. It does need the api32-normal-useast5.tiktokv.us
origin header, which the service sends; without it the gateway answers HTTP 455.
Query parameters:
poi_id: required. The place id from /api/v1/tiktok/mobile/search/place (poi_info rows).review_count: optional. Review-preview size forwarded upstream; default is the app's 20, bounded at 50.review_cursor: optional. Review cursor forwarded upstream; default 0.merged_count: optional. Posts page size forwarded upstream; default is the app's 9, bounded at 50.video_cursor: optional. Top-videos cursor forwarded upstream; default 0.enter_from: optional. Analytics origin forwarded upstream; default search_places (the app's value from the
Places tab).Control caveat. The page-size controls are forwarded but are not a hard cap: merged_count=9 returned 5–9
posts and merged_count=3 returned 6, i.e. the server applies its own bounds. Treat the returned counters as the
truth for what the page holds.
Measured 2026-10-21 (aggr32-normal.tiktokv.us edge / api32-normal-useast5.tiktokv.us origin):
| call | result |
|---|---|
poi_id=42203861086875992 (Nam Coffee, 304 Ord St) | 698,016–968,641 B, 3–4 frames, header score 4.4 / 33 mentions, 6 top videos, 5–9 posts |
poi_id=21568226355448582 (Nam Coffee, 4876 Fountain Ave) | 1,499,621 B, header score 4.5, 15 top videos, 9 posts, 3 reviews, ai_summary, has_more_aweme: 1 |
| pure-Go placeholder signer | 945,190 B of the same real page — device-free |
Example request:
GET /api/v1/tiktok/mobile/place/detail?poi_id=42203861086875992
Example response (truncated):
{
"code": 200,
"msg": "OK",
"data": {
"poi_id": "42203861086875992",
"page_id": "100614404",
"frame_count": 4,
"nodes": {
"food_head_info": {
"data": {
"poi_name": "Nam Coffee",
"formatted_address": "304 Ord St, Los Angeles, CA 90012, USA",
"category_name": "Coffee Shop",
"recommend_score": {"score": "4.4", "max_score": "5.0", "mentioned_count": "33", "desc": "Good choice"},
"store_info": {"OpeningHoursForPoiDetail": "Opens 8:00 AM"},
"location": {"lat": "34.060090", "lng": "-118.239007"}
}
},
"poi_top_videos": {"data": {"item_list": [{"item_type": 1, "aweme_topic_tag_en": "Iced Vietnamese Coffee"}]}},
"poi_limited_post": {"data": {"item_list": [], "aweme_cursor": 9, "has_more_aweme": 1}},
"poi_review": {"data": {"reviews": [], "has_more": 0}}
},
"top_video_count": 6,
"post_count": 9,
"post_cursor": 9,
"has_more_posts": true,
"review_count": 3,
"has_more_reviews": false,
"host": "aggr32-normal.tiktokv.us"
}
}
| 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 | |
| review_count | integer | No | Review preview size forwarded upstream (default 20, bounded at 50) | 20 | |
| review_cursor | integer | No | Review cursor forwarded upstream (default 0) | 0 | |
| merged_count | integer | No | Posts page size forwarded upstream (default 9, bounded at 50) | 9 | |
| video_cursor | integer | No | Top-videos cursor forwarded upstream (default 0) | 0 | |
| enter_from | string | No | Forwarded analytics origin (default search_places) | search_places |
curl -X GET "https://api.crawlora.net/api/v1/tiktok/mobile/place/detail?poi_id=42203861086875992" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"poi_id": "42203861086875992",
"page_id": "100614404",
"frame_count": 4,
"nodes": {
"food_head_info": {
"data": {
"poi_name": "Nam Coffee",
"formatted_address": "304 Ord St, Los Angeles, CA 90012, USA",
"category_name": "Coffee Shop",
"recommend_score": {
"score": "4.4",
"max_score": "5.0",
"mentioned_count": "33",
"desc": "Good choice"
},
"store_info": {
"OpeningHoursForPoiDetail": "Opens 8:00 AM"
},
"location": {
"lat": "34.060090",
"lng": "-118.239007"
}
}
},
"poi_top_videos": {
"data": {
"item_list": [
{
"item_type": 1,
"aweme_topic_tag_en": "Iced Vietnamese Coffee"
}
]
}
},
"poi_limited_post": {
"data": {
"item_list": [],
"aweme_cursor": 9,
"has_more_aweme": 1
}
},
"poi_review": {
"data": {
"reviews": [],
"has_more": 0
}
}
},
"top_video_count": 6,
"post_count": 9,
"post_cursor": 9,
"has_more_posts": true,
"review_count": 3,
"has_more_reviews": false,
"host": "aggr32-normal.tiktokv.us"
}
}Request schema
No body schema
Response schema
#/definitions/tiktokmobile.placeDetailResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| fetched_at | string | No | ||||
| frame_count | integer | No | 4 | |||
| frames | array | No | ||||
| has_more_posts | boolean | No | true | |||
| has_more_reviews | boolean | No | false | |||
| host | string | No | aggr32-normal.tiktokv.us | |||
| layout | object | No | ||||
| nodes | object | No | ||||
| page_id | string | No | 100614404 | |||
| poi_id | string | No | 42203861086875992 | |||
| post_count | integer | No | 9 | |||
| post_cursor | integer | No | 9 | |||
| review_count | integer | No | 3 | |||
| top_video_count | integer | No | 6 |
| Status | Description | Schema |
|---|---|---|
| 400 | Invalid input | #/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/detail?poi_id=42203861086875992" \
-H "x-api-key: $CRAWLORA_API_KEY"