From d397964e6524d9ee9ae2e35278f4b1c3bab4464d Mon Sep 17 00:00:00 2001 From: sk Date: Wed, 13 May 2026 17:48:12 +0800 Subject: [PATCH 1/3] feat(tiktok): add search_products and product_reviews commands Adds CLI support for tiktok.search_products and tiktok.product_reviews capabilities. Updates schema fixtures, projection rules (compact table output for both), root_sources command registration, and SKILL.md documentation. Region support for shop_product_info is widened to the full TikHub list (US/GB/SG/MY/PH/TH/VN/ID). --- internal/command/root_sources.go | 8 +- internal/command/root_sources_test.go | 64 +++++++++++++++ internal/command/schema_test_helper.go | 5 ++ internal/output/projection_rules.go | 40 ++++++++++ internal/output/projection_test.go | 2 + skills/apimux-tiktok/SKILL.md | 105 ++++++++++++++++++++++++- 6 files changed, 218 insertions(+), 6 deletions(-) diff --git a/internal/command/root_sources.go b/internal/command/root_sources.go index ffc115a..06a7528 100644 --- a/internal/command/root_sources.go +++ b/internal/command/root_sources.go @@ -169,14 +169,16 @@ func (r *Root) newTiktokCommand(runCtx *runContext) *cobra.Command { return newStaticSourceCommand( "tiktok", "TikTok video, comment, and shop data", - "TikTok video, comment, and shop data.\n\nUse this command to search TikTok videos, inspect video details, list comments, and query TikTok Shop products and product details.", - " apimux tiktok search_videos --keyword laptop\n apimux tiktok get_video_detail --share-url https://www.tiktok.com/t/ZTFNEj8Hk/\n apimux tiktok shop_products --seller-id 123456", - "search_videos, get_video_detail, list_comments, shop_products, shop_product_info", + "TikTok video, comment, and shop data.\n\nUse this command to search TikTok videos, inspect video details, list comments, search TikTok Shop products, query seller products and product details, and browse product reviews.", + " apimux tiktok search_videos --keyword laptop\n apimux tiktok get_video_detail --share-url https://www.tiktok.com/t/ZTFNEj8Hk/\n apimux tiktok shop_products --seller-id 123456\n apimux tiktok search_products --keyword labubu --region US\n apimux tiktok product_reviews --product-id 1729556436942358002 --region US", + "search_videos, get_video_detail, list_comments, shop_products, shop_product_info, search_products, product_reviews", newSchemaBoundCapabilityCommand(runCtx, "tiktok.search_videos", "search_videos", "Search TikTok videos", "tiktok search_videos"), newSchemaBoundCapabilityCommand(runCtx, "tiktok.get_video_detail", "get_video_detail", "Fetch one TikTok video detail", "tiktok get_video_detail"), newSchemaBoundCapabilityCommand(runCtx, "tiktok.list_comments", "list_comments", "List TikTok video comments", "tiktok list_comments"), newSchemaBoundCapabilityCommand(runCtx, "tiktok.shop_products", "shop_products", "List TikTok Shop seller products", "tiktok shop_products"), newSchemaBoundCapabilityCommand(runCtx, "tiktok.shop_product_info", "shop_product_info", "Fetch one TikTok Shop product detail", "tiktok shop_product_info"), + newSchemaBoundCapabilityCommand(runCtx, "tiktok.search_products", "search_products", "Search TikTok Shop products", "tiktok search_products"), + newSchemaBoundCapabilityCommand(runCtx, "tiktok.product_reviews", "product_reviews", "List TikTok Shop product reviews", "tiktok product_reviews"), ) } diff --git a/internal/command/root_sources_test.go b/internal/command/root_sources_test.go index d6a718a..880b95e 100644 --- a/internal/command/root_sources_test.go +++ b/internal/command/root_sources_test.go @@ -597,6 +597,70 @@ func TestTikTokGetVideoDetailCallsService(t *testing.T) { } } +func TestTikTokSearchProductsCallsService(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if maybeServeSchema(w, r) { + return + } + if r.URL.Path != "/v1/capabilities/tiktok.search_products" { + t.Fatalf("unexpected path: %s", r.URL.Path) + } + _, _ = w.Write([]byte(`{"ok":true,"data":[{"product_id":"p-1","product_name":"Labubu Plush","product_sold_count":10,"format_available_price":"$9.99","format_origin_price":"$12.99","discount":"20% off","rating":4.6,"review_count":42}],"meta":{"capability":"tiktok.search_products","cursor":"next-page","has_more":true}}`)) + })) + defer server.Close() + + var stdout bytes.Buffer + var stderr bytes.Buffer + + root := NewRoot(&stdout, &stderr) + exitCode, err := root.Execute(context.Background(), []string{ + "--base-url", server.URL, + "tiktok", "search_products", + "--keyword", "labubu", + "--region", "US", + }) + if err != nil { + t.Fatalf("execute root: %v", err) + } + if exitCode != 0 { + t.Fatalf("expected exit code 0, got %d, stderr=%s", exitCode, stderr.String()) + } + assertCompactTableOutputContains(t, stdout.String(), `"columns":["product_id","product_name","product_sold_count","format_available_price","format_origin_price","discount","rating","review_count"]`, `"p-1"`) +} + +func TestTikTokProductReviewsCallsService(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if maybeServeSchema(w, r) { + return + } + if r.URL.Path != "/v1/capabilities/tiktok.product_reviews" { + t.Fatalf("unexpected path: %s", r.URL.Path) + } + _, _ = w.Write([]byte(`{"ok":true,"data":[{"review_id":"r-1","rating":5,"verified_purchase":true,"like_count":3,"create_time":"2023-11-14T22:13:20Z","content":"Great!"}],"meta":{"capability":"tiktok.product_reviews","has_more":true,"total":120}}`)) + })) + defer server.Close() + + var stdout bytes.Buffer + var stderr bytes.Buffer + + root := NewRoot(&stdout, &stderr) + exitCode, err := root.Execute(context.Background(), []string{ + "--base-url", server.URL, + "tiktok", "product_reviews", + "--product-id", "prod-1", + "--sort", "latest", + "--media-filter", "media", + "--star", "5", + }) + if err != nil { + t.Fatalf("execute root: %v", err) + } + if exitCode != 0 { + t.Fatalf("expected exit code 0, got %d, stderr=%s", exitCode, stderr.String()) + } + assertCompactTableOutputContains(t, stdout.String(), `"columns":["review_id","rating","verified_purchase","like_count","create_time","content"]`, `"r-1"`) +} + func TestMetaAdsSearchCallsService(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if maybeServeSchema(w, r) { diff --git a/internal/command/schema_test_helper.go b/internal/command/schema_test_helper.go index a598da3..26de1bd 100644 --- a/internal/command/schema_test_helper.go +++ b/internal/command/schema_test_helper.go @@ -87,6 +87,11 @@ func testSchemas() map[string]schema.CapabilitySchema { "amazon.get_category_trend": amazonSchema("amazon.get_category_trend", []schema.CapabilityParam{{Name: "node_id", Type: "string", Required: true, FlagName: "node-id"}, {Name: "market", Type: "string"}, {Name: "trend_types", Type: "array", Required: true, ItemsType: "string", Encoding: "csv", FlagName: "trend-types"}}), "tiktok.search_videos": {Name: "tiktok.search_videos", Parameters: []schema.CapabilityParam{{Name: "keyword", Type: "string", Required: true}, {Name: "region", Type: "string"}, {Name: "sort_by", Type: "string", Enum: []string{"relevance", "likes", "date"}, FlagName: "sort-by"}, {Name: "publish_time", Type: "string", Enum: []string{"all", "1d", "1w", "1m", "3m", "6m"}, FlagName: "publish-time"}, {Name: "cursor", Type: "integer"}, {Name: "count", Type: "integer"}}}, "tiktok.get_video_detail": {Name: "tiktok.get_video_detail", Parameters: []schema.CapabilityParam{{Name: "share_url", Type: "string", FlagName: "share-url"}, {Name: "aweme_id", Type: "string", FlagName: "aweme-id"}, {Name: "region", Type: "string"}}}, + "tiktok.list_comments": {Name: "tiktok.list_comments", Parameters: []schema.CapabilityParam{{Name: "video_id", Type: "string", Required: true, FlagName: "video-id"}, {Name: "cursor", Type: "integer"}, {Name: "count", Type: "integer"}}}, + "tiktok.shop_products": {Name: "tiktok.shop_products", Parameters: []schema.CapabilityParam{{Name: "seller_id", Type: "string", Required: true, FlagName: "seller-id"}, {Name: "region", Type: "string"}, {Name: "sort", Type: "string", Enum: []string{"sale", "rec"}}, {Name: "top_n", Type: "integer", FlagName: "top-n"}}}, + "tiktok.shop_product_info": {Name: "tiktok.shop_product_info", Parameters: []schema.CapabilityParam{{Name: "product_id", Type: "string", Required: true, FlagName: "product-id"}, {Name: "region", Type: "string"}}}, + "tiktok.search_products": {Name: "tiktok.search_products", Parameters: []schema.CapabilityParam{{Name: "keyword", Type: "string", Required: true}, {Name: "region", Type: "string", Enum: []string{"US", "GB", "SG", "MY", "PH", "TH", "VN", "ID"}}, {Name: "cursor", Type: "string"}, {Name: "offset", Type: "integer"}, {Name: "count", Type: "integer"}}}, + "tiktok.product_reviews": {Name: "tiktok.product_reviews", Parameters: []schema.CapabilityParam{{Name: "product_id", Type: "string", Required: true, FlagName: "product-id"}, {Name: "region", Type: "string", Enum: []string{"US", "GB", "SG", "MY", "PH", "TH", "VN", "ID"}}, {Name: "page", Type: "integer"}, {Name: "sort", Type: "string", Enum: []string{"default", "latest"}}, {Name: "media_filter", Type: "string", Enum: []string{"all", "media", "verified"}, FlagName: "media-filter"}, {Name: "star", Type: "string", Enum: []string{"all", "1", "2", "3", "4", "5"}}, {Name: "count", Type: "integer"}}}, "meta_ads.search_ads": {Name: "meta_ads.search_ads", Parameters: []schema.CapabilityParam{{Name: "q", Type: "string", Required: true}, {Name: "country", Type: "string"}, {Name: "ad_type", Type: "string", Enum: []string{"all", "political_and_issue_ads", "housing_ads", "employment_ads", "credit_ads"}, FlagName: "ad-type"}, {Name: "active_status", Type: "string", Enum: []string{"active", "inactive", "all"}, FlagName: "active-status"}, {Name: "media_type", Type: "string", Enum: []string{"all", "video", "image", "meme", "image_and_meme", "none"}, FlagName: "media-type"}, {Name: "platforms", Type: "string"}, {Name: "start_date", Type: "string", FlagName: "start-date"}, {Name: "end_date", Type: "string", FlagName: "end-date"}, {Name: "next_page_token", Type: "string", FlagName: "next-page-token"}}}, "meta_ads.get_ad_detail": {Name: "meta_ads.get_ad_detail", Parameters: []schema.CapabilityParam{{Name: "ad_id", Type: "string", Required: true, FlagName: "ad-id"}}}, "douyin.search_videos": {Name: "douyin.search_videos", Parameters: []schema.CapabilityParam{{Name: "keyword", Type: "string", Required: true}, {Name: "sort_type", Type: "string", Enum: []string{"comprehensive", "likes", "latest"}, FlagName: "sort-type"}, {Name: "publish_time", Type: "string", Enum: []string{"all", "1d", "1w", "6m"}, FlagName: "publish-time"}, {Name: "filter_duration", Type: "string", Enum: []string{"all", "under_1m", "1m_5m", "over_5m"}, FlagName: "filter-duration"}, {Name: "content_type", Type: "string", Enum: []string{"all", "video", "image", "article"}, FlagName: "content-type"}, {Name: "cursor", Type: "integer"}}}, diff --git a/internal/output/projection_rules.go b/internal/output/projection_rules.go index a26b8ab..510cc9e 100644 --- a/internal/output/projection_rules.go +++ b/internal/output/projection_rules.go @@ -733,6 +733,46 @@ var projectionRules = map[string]projectionRule{ }, }, }, + "tiktok.search_products": { + Compact: projectionSpec{ + Tables: []tableRule{ + { + From: "$root", + To: "$root", + Limit: 10, + Columns: []fieldRule{ + {From: "product_id", To: "product_id"}, + {From: "product_name", To: "product_name"}, + {From: "product_sold_count", To: "product_sold_count"}, + {From: "format_available_price", To: "format_available_price"}, + {From: "format_origin_price", To: "format_origin_price"}, + {From: "discount", To: "discount"}, + {From: "rating", To: "rating"}, + {From: "review_count", To: "review_count"}, + }, + }, + }, + }, + }, + "tiktok.product_reviews": { + Compact: projectionSpec{ + Tables: []tableRule{ + { + From: "$root", + To: "$root", + Limit: 10, + Columns: []fieldRule{ + {From: "review_id", To: "review_id"}, + {From: "rating", To: "rating"}, + {From: "verified_purchase", To: "verified_purchase"}, + {From: "like_count", To: "like_count"}, + {From: "create_time", To: "create_time"}, + {From: "content", To: "content"}, + }, + }, + }, + }, + }, "xiaohongshu.get_note_comments": { Compact: projectionSpec{ Tables: []tableRule{ diff --git a/internal/output/projection_test.go b/internal/output/projection_test.go index 50da2e7..06c92f8 100644 --- a/internal/output/projection_test.go +++ b/internal/output/projection_test.go @@ -821,6 +821,8 @@ func TestProjectionRulesCoverAllAgentTestCapabilities(t *testing.T) { "reddit.get_post_comments", "tiktok.shop_products", "tiktok.shop_product_info", + "tiktok.search_products", + "tiktok.product_reviews", "xiaohongshu.get_note_comments", "douyin.get_comment_replies", } diff --git a/skills/apimux-tiktok/SKILL.md b/skills/apimux-tiktok/SKILL.md index ab3e50b..e955c2e 100644 --- a/skills/apimux-tiktok/SKILL.md +++ b/skills/apimux-tiktok/SKILL.md @@ -22,6 +22,8 @@ Search TikTok content and inspect TikTok Shop product data. Use this for content - **Analyze comments under a video** → `list_comments` - **List products from a TikTok Shop seller** → `shop_products` - **Inspect one TikTok Shop product** → `shop_product_info` +- **Search TikTok Shop products by keyword** → `search_products` +- **Browse TikTok Shop product reviews** → `product_reviews` - **Validate a market across sources** → use `search_videos` for content demand, then [`amazon.search_products`](../apimux-amazon/SKILL.md) for supply-side checks ## Available capabilities @@ -33,6 +35,8 @@ Search TikTok content and inspect TikTok Shop product data. Use this for content | `list_comments` | List video comments | Audience feedback and comment insights | | `shop_products` | List seller products | Seller and product-selection analysis | | `shop_product_info` | Get product details | Product research and cross-platform comparison | +| `search_products` | Search shop products by keyword | Keyword-level shop discovery and trend scouting | +| `product_reviews` | List product reviews | Product sentiment, rating distribution, UGC mining | --- @@ -223,12 +227,13 @@ Get details for one TikTok Shop product. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `product_id` | string | Yes | Product ID | -| `region` | string | No | Only `US` is supported; default `US` | +| `region` | string | No | `US`, `GB`, `SG`, `MY`, `PH`, `TH`, `VN`, or `ID`; default `US` | ### CLI usage ```bash apimux tiktok shop_product_info --product-id "1729384756" +apimux tiktok shop_product_info --product-id "1729384756" --region "GB" ``` ### Response fields @@ -252,12 +257,106 @@ apimux tiktok shop_product_info --product-id "1729384756" ### Notes - `product_id` is required. -- `region` currently supports only `US`. +- `region` defaults to `US` and accepts the 8 supported markets listed above. - Missing products return `product_not_found`. --- +## tiktok.search_products + +Search TikTok Shop products by keyword. + +### Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `keyword` | string | Yes | Search keyword | +| `region` | string | No | `US`, `GB`, `SG`, `MY`, `PH`, `TH`, `VN`, or `ID`; default `US` | +| `cursor` | string | No | Pagination token from previous `meta.cursor` | +| `offset` | integer | No | Result offset, `>= 0`; default `0` | +| `count` | integer | No | Number of products, `1..200`; default `20` | + +### CLI usage + +```bash +apimux tiktok search_products --keyword "labubu" +apimux tiktok search_products --keyword "labubu" --region "GB" --count 40 +``` + +### Response fields + +| Field | Type | Description | +|-------|------|-------------| +| `product_id` | string | Product ID | +| `product_name` | string | Product name | +| `product_cover` | string | Product cover image | +| `product_sold_count` | integer | Sold count | +| `format_available_price` | string | Current price text | +| `format_origin_price` | string | Original price text | +| `discount` | string | Discount text | +| `rating` | number | Product rating when available | +| `review_count` | integer | Review count when available | + +### Notes + +- `keyword` is required. +- `region` must be one of the 8 supported markets. +- Pagination state is returned in `meta.cursor` and `meta.has_more`. + +--- + +## tiktok.product_reviews + +List reviews for one TikTok Shop product. + +### Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `product_id` | string | Yes | TikTok Shop product ID | +| `region` | string | No | `US`, `GB`, `SG`, `MY`, `PH`, `TH`, `VN`, or `ID`; default `US` | +| `page` | integer | No | Page number starting at `1`; default `1` | +| `sort` | string | No | `default` or `latest`; default `default` | +| `media_filter` | string | No | `all`, `media`, or `verified`; default `all` | +| `star` | string | No | `all` or `1`..`5`; default `all` | +| `count` | integer | No | Number of reviews, `1..100`; default `20` | + +### CLI usage + +```bash +apimux tiktok product_reviews --product-id "1729556436942358002" +apimux tiktok product_reviews --product-id "1729556436942358002" --sort "latest" --star "5" --media-filter "media" +``` + +### Response fields + +| Field | Type | Description | +|-------|------|-------------| +| `review_id` | string | Review ID | +| `rating` | integer | Star rating, `1..5` | +| `content` | string | Review content | +| `create_time` | string | RFC3339 timestamp when available | +| `verified_purchase` | boolean | Verified purchase indicator | +| `like_count` | integer | Likes on this review | +| `medias` | object[] | Review media entries `{type, url}` | +| `author` | object | `user_id`, `nickname`, `avatar` | +| `seller_reply` | object | Seller reply payload when present | + +### Notes + +- `product_id` is required. +- The underlying provider endpoint is documented for Americas and Europe (e.g. + `US`, `GB`). For Southeast Asia regions (`SG`, `MY`, `PH`, `TH`, `VN`, `ID`) + results may be empty. +- Pagination state is returned in `meta.has_more`, `meta.total`, and + `meta.cursor` (the current page number). +- Review summary is surfaced in `meta.resolved_filters.average_rating` and + `meta.resolved_filters.star_distribution` when present. + +--- + ## General notes - See [`../apimux-shared/SKILL.md`](../apimux-shared/SKILL.md) for response structure and error handling. -- TikTok Shop capabilities currently support only the US market. +- TikTok Shop capabilities support the TikHub region list: `US, GB, SG, MY, PH, TH, VN, ID`. `shop_products` currently remains US-only; the other shop capabilities accept the full list with `US` as the default. + From 0f00f718cf9ac16369b842e170266d07e0cd53df Mon Sep 17 00:00:00 2001 From: sk Date: Wed, 13 May 2026 22:52:40 +0800 Subject: [PATCH 2/3] docs(tiktok): note search product pagination token --- skills/apimux-tiktok/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/apimux-tiktok/SKILL.md b/skills/apimux-tiktok/SKILL.md index e955c2e..c59e087 100644 --- a/skills/apimux-tiktok/SKILL.md +++ b/skills/apimux-tiktok/SKILL.md @@ -301,6 +301,7 @@ apimux tiktok search_products --keyword "labubu" --region "GB" --count 40 - `keyword` is required. - `region` must be one of the 8 supported markets. +- First-page requests send an empty `page_token` upstream; subsequent pages use `meta.cursor`. - Pagination state is returned in `meta.cursor` and `meta.has_more`. --- @@ -359,4 +360,3 @@ apimux tiktok product_reviews --product-id "1729556436942358002" --sort "latest" - See [`../apimux-shared/SKILL.md`](../apimux-shared/SKILL.md) for response structure and error handling. - TikTok Shop capabilities support the TikHub region list: `US, GB, SG, MY, PH, TH, VN, ID`. `shop_products` currently remains US-only; the other shop capabilities accept the full list with `US` as the default. - From af590830b6789c0c8223250e45b80e5cc5e03f06 Mon Sep 17 00:00:00 2001 From: sk Date: Thu, 14 May 2026 11:21:08 +0800 Subject: [PATCH 3/3] docs(tiktok): document shop search and reviews workflows --- skills/apimux-tiktok/SKILL.md | 40 +++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/skills/apimux-tiktok/SKILL.md b/skills/apimux-tiktok/SKILL.md index c59e087..51afe50 100644 --- a/skills/apimux-tiktok/SKILL.md +++ b/skills/apimux-tiktok/SKILL.md @@ -1,7 +1,7 @@ --- name: apimux-tiktok version: 1.0.0 -description: "TikTok content and TikTok Shop data. Search videos, analyze comments, list shop products, and inspect product details for content research and commerce analysis." +description: "TikTok content and TikHub-backed TikTok Shop data. Search videos, analyze comments, list shop products, search products, browse reviews, and inspect product details for content research and commerce analysis." metadata: source: tiktok requires: @@ -11,7 +11,7 @@ metadata: # TikTok -Search TikTok content and inspect TikTok Shop product data. Use this for content research, creator/product analysis, shopping research, and cross-platform market validation. +Search TikTok content and inspect TikHub-backed TikTok Shop product data. Use this for content research, creator/product analysis, shopping research, and cross-platform market validation. **Before using:** Read [`../apimux-shared/SKILL.md`](../apimux-shared/SKILL.md) for response structure, error handling, pagination metadata, and CLI conventions. @@ -22,8 +22,8 @@ Search TikTok content and inspect TikTok Shop product data. Use this for content - **Analyze comments under a video** → `list_comments` - **List products from a TikTok Shop seller** → `shop_products` - **Inspect one TikTok Shop product** → `shop_product_info` -- **Search TikTok Shop products by keyword** → `search_products` -- **Browse TikTok Shop product reviews** → `product_reviews` +- **Search TikHub TikTok Shop products by keyword** → `search_products` +- **Browse TikHub TikTok Shop product reviews** → `product_reviews` - **Validate a market across sources** → use `search_videos` for content demand, then [`amazon.search_products`](../apimux-amazon/SKILL.md) for supply-side checks ## Available capabilities @@ -38,6 +38,13 @@ Search TikTok content and inspect TikTok Shop product data. Use this for content | `search_products` | Search shop products by keyword | Keyword-level shop discovery and trend scouting | | `product_reviews` | List product reviews | Product sentiment, rating distribution, UGC mining | +## Common workflows + +- Unknown product ID: use `search_products` first, pick a `product_id`, then call `shop_product_info` or `product_reviews`. +- Product validation: use `search_products` to compare visible demand signals such as sold count, price, rating, and review count; use `product_reviews` to inspect buyer language and objections. +- Review mining: use `product_reviews --sort latest` for fresh buyer feedback, `--star 1` or `--star 2` for pain points, and `--media-filter media` when the user asks for visual proof or UGC examples. +- Cross-market checks: pass `--region` explicitly when comparing markets. Supported TikHub shop regions are `US`, `GB`, `SG`, `MY`, `PH`, `TH`, `VN`, and `ID`; `shop_products` remains seller-listing only and US-only. + --- ## tiktok.search_videos @@ -264,7 +271,9 @@ apimux tiktok shop_product_info --product-id "1729384756" --region "GB" ## tiktok.search_products -Search TikTok Shop products by keyword. +Search TikHub TikTok Shop products by keyword. + +Use this when the user has a product category, trend term, brand, or item name but does not yet have a TikTok Shop `product_id`. This is the entry point for discovering products before fetching detail or reviews. ### Parameters @@ -281,6 +290,7 @@ Search TikTok Shop products by keyword. ```bash apimux tiktok search_products --keyword "labubu" apimux tiktok search_products --keyword "labubu" --region "GB" --count 40 +apimux tiktok search_products --keyword "wireless microphone" --region "US" --cursor "NEXT_CURSOR" ``` ### Response fields @@ -297,18 +307,27 @@ apimux tiktok search_products --keyword "labubu" --region "GB" --count 40 | `rating` | number | Product rating when available | | `review_count` | integer | Review count when available | +### Compact output + +Default compact output is columnar and keeps the first 10 rows with: + +`product_id`, `product_name`, `product_sold_count`, `format_available_price`, `format_origin_price`, `discount`, `rating`, `review_count`. + ### Notes - `keyword` is required. - `region` must be one of the 8 supported markets. - First-page requests send an empty `page_token` upstream; subsequent pages use `meta.cursor`. - Pagination state is returned in `meta.cursor` and `meta.has_more`. +- Use `cursor` for token-based pagination when `meta.cursor` is present. Use `offset` only when the caller explicitly wants offset-based paging. --- ## tiktok.product_reviews -List reviews for one TikTok Shop product. +List TikHub reviews for one TikTok Shop product. + +Use this after obtaining a `product_id` from `search_products`, `shop_products`, or `shop_product_info`. This is the best command for sentiment analysis, purchase objections, quality issues, and customer wording. ### Parameters @@ -327,6 +346,7 @@ List reviews for one TikTok Shop product. ```bash apimux tiktok product_reviews --product-id "1729556436942358002" apimux tiktok product_reviews --product-id "1729556436942358002" --sort "latest" --star "5" --media-filter "media" +apimux tiktok product_reviews --product-id "1729556436942358002" --region "GB" --page 2 --count 50 ``` ### Response fields @@ -343,9 +363,17 @@ apimux tiktok product_reviews --product-id "1729556436942358002" --sort "latest" | `author` | object | `user_id`, `nickname`, `avatar` | | `seller_reply` | object | Seller reply payload when present | +### Compact output + +Default compact output is columnar and keeps the first 10 rows with: + +`review_id`, `rating`, `verified_purchase`, `like_count`, `create_time`, `content`. + ### Notes - `product_id` is required. +- Use `star` to isolate sentiment: `1` and `2` for problems, `4` and `5` for positive language, `all` for the default mix. +- Use `media_filter=media` when the user needs reviews with images or videos; use `media_filter=verified` when the user asks for verified purchases. - The underlying provider endpoint is documented for Americas and Europe (e.g. `US`, `GB`). For Southeast Asia regions (`SG`, `MY`, `PH`, `TH`, `VN`, `ID`) results may be empty.