{
  "openapi": "3.0.1",
  "info": {
    "title": "Tiktok Shop Product Scraper",
    "description": "Extract TikTok Shop products, prices, discounts, sold counts, ratings, variants, seller info, shipping, and review signals from product URLs, keywords, categories, and seller pages.",
    "version": "2.0",
    "x-build-id": "RXfzFN3Yd2rfRmgaC"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/coregent~tiktok-shop-product-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-coregent-tiktok-shop-product-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/coregent~tiktok-shop-product-scraper/runs": {
      "post": {
        "operationId": "runs-sync-coregent-tiktok-shop-product-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/coregent~tiktok-shop-product-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-coregent-tiktok-shop-product-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",
        "properties": {
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Search TikTok Shop by keyword. Returns products with price, discount, rating, sold count, and seller. Example: wireless earbuds, portable blender",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "productUrls": {
            "title": "Product URLs or IDs",
            "type": "array",
            "description": "TikTok Shop products to scrape. Accepts either a product URL or a bare product ID.\n\nExamples:\nhttps://shop.tiktok.com/view/product/1730985432198765432\nhttps://shop.tiktok.com/us/pdp/product-slug/1730985432198765432\n1730985432198765432\n\nProducts here are always fully enriched with variants, stock, and shipping. TikTok video URLs are not product pages and are skipped.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "sellerUrls": {
            "title": "Seller / Store URLs or IDs",
            "type": "array",
            "description": "TikTok Shop sellers to scrape all products from. Accepts either a store URL or a bare seller ID.\n\nExamples:\nhttps://shop.tiktok.com/us/store/example-store/7495288463171029168\n7495288463171029168\n\nTip: the sellerId of any product in your results can be pasted straight back in here.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "categories": {
            "title": "Categories",
            "type": "array",
            "description": "TikTok Shop category names to browse. Example: Electronics, Home & Kitchen. Names are resolved against TikTok's live category list.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "countries": {
            "title": "Market",
            "type": "array",
            "description": "TikTok Shop markets to scrape. Six are supported: the US and five Southeast Asian markets, each verified across keyword search, category browse, seller catalogues, product detail and reviews (2026-08-23). Prices come back in each market's own currency — see the note on Minimum/Maximum Price before combining markets with a price filter. GB, AU, JP, ID, DE, BR and others still return nothing and are deliberately absent rather than offered as options that silently produce no rows.",
            "items": {
              "type": "string",
              "enum": [
                "US",
                "MY",
                "TH",
                "VN",
                "PH",
                "SG"
              ],
              "enumTitles": [
                "United States (USD)",
                "Malaysia (MYR)",
                "Thailand (THB)",
                "Vietnam (VND)",
                "Philippines (PHP)",
                "Singapore (SGD)"
              ]
            },
            "default": [
              "US"
            ]
          },
          "maxResultsPerQuery": {
            "title": "Max Results Per Query",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Maximum products per keyword, category, or seller — PER COUNTRY. A run with 3 keywords x 2 countries at 50 can therefore return up to 300 products. Use 'Max Results Total' to cap the whole run.",
            "default": 50
          },
          "maxResultsTotal": {
            "title": "Max Results Total",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on products for the entire run, across all keywords, sellers, categories, and countries. 0 = no cap.",
            "default": 0
          },
          "minPrice": {
            "title": "Minimum Price",
            "type": "number",
            "description": "Only keep products at or above this sale price, in each market's own currency. The number carries no currency, so across markets it is applied as-is to every one of them: 50 means 50 USD in the US and 50 THB in Thailand. Filtering a multi-market run on price is rarely what you want — run one market at a time when price matters."
          },
          "maxPrice": {
            "title": "Maximum Price",
            "type": "number",
            "description": "Only keep products at or below this sale price, in each market's own currency — the same caveat as Minimum Price. A VND ceiling applied to a USD market, or the reverse, silently keeps everything or nothing."
          },
          "minRating": {
            "title": "Minimum Rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Only keep products rated at or above this value (0-5)."
          },
          "minSoldCount": {
            "title": "Minimum Sold Count",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep products with at least this many units sold."
          },
          "deduplicateProducts": {
            "title": "Deduplicate Products",
            "type": "boolean",
            "description": "Remove duplicate products found through more than one discovery route. Duplicates are removed before they are charged.",
            "default": true
          },
          "includeSummary": {
            "title": "Include Summary",
            "type": "boolean",
            "description": "Append a run-level summary record with aggregated statistics (average price, top sellers, bucket counts). Never charged.",
            "default": true
          },
          "includeProductDetails": {
            "title": "Include Variants, Stock, Shipping & Seller Profile",
            "type": "boolean",
            "description": "Fetch the full product detail for every product:\n• Variants & stock — variantCount, variantOptions, variantSummary, availableQuantity, inStock\n• Shipping — shippingFee, shippingType, estimatedDelivery, shipsFrom\n• Seller profile — sellerRating, sellerFollowerCount, sellerProductCount (these feed the seller trust score)\n• Also — full product description, complete image gallery, price range across variants\n\nCOSTS EXTRA: one additional API call per product, billed as one 'product-detail-result' event per product. Off by default because discovery alone returns ~30 products per request. Always on for Product URL mode — that IS the request.\n\nTip: filters run BEFORE this call, so a product excluded by minRating or minSoldCount is never enriched and never charged.\n\nNOTE: this option requires a paid Apify plan. On the Free plan it is skipped and you are not charged for it — discovery results are returned in full, and Product URL mode still returns fully detailed products.",
            "default": false
          },
          "includeReviews": {
            "title": "Include Reviews",
            "type": "boolean",
            "description": "Fetch real customer reviews per product: text, rating, verified-purchase flag, whether the review was incentivized, and the full star breakdown (5★→1★). BEST-EFFORT: TikTok throttles its review endpoints, so reviews are not available for every product on every run. We retry, then fall back to a second review endpoint; when both still fail, the record says so and you are NOT charged. The star breakdown comes only from the primary endpoint, so ratingDistribution can be absent on a run served by the fallback. Every row carries reviewsAccessible and reviewsUnavailableReason ('throttled' = TikTok refused the endpoint, 'none' = the product genuinely has no reviews, 'unreadable_response' = the endpoint answered with something we could not read, 'paid_plan_only' = skipped on the Free plan), so an empty reviews column is never ambiguous. Rating and review COUNT are always available without this option.\n\nNOTE: this option requires a paid Apify plan. On the Free plan it is skipped and you are not charged for it.",
            "default": false
          },
          "maxReviews": {
            "title": "Max Reviews Per Product",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "How many reviews to fetch per product when 'Include Reviews' is on. Billed per review record — 20 reviews across 50 products is 1,000 review events. TikTok returns reviews in pages of 20, so 20 (the default) fetches a full page with nothing wasted; 21 costs a whole extra page for one more review.",
            "default": 20
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}