{
  "openapi": "3.0.1",
  "info": {
    "title": "TikTok Shop Scraper — Products & Categories",
    "description": "Scrape TikTok Shop products from any category page or product URL. Auto-solves the slide captcha. Supports 12 storefronts (VN, US, UK, ID, MY, TH, PH, SG, GB, JP, MX, BR) — region follows your proxy's exit IP. Returns title, price, rating, sold count, image, URL.",
    "version": "0.1",
    "x-build-id": "OQY5J3o0r04oqJjU2"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/herus13~tiktok-shop-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-herus13-tiktok-shop-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/herus13~tiktok-shop-scraper/runs": {
      "post": {
        "operationId": "runs-sync-herus13-tiktok-shop-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/herus13~tiktok-shop-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-herus13-tiktok-shop-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": {
          "search_terms": {
            "title": "Search Terms",
            "type": "array",
            "description": "<p>Keywords to search on the TikTok Shop storefront. Each term opens <code>https://shop.tiktok.com/us/s?q={keyword}</code> in an anti-detect browser, scrolls to load matches, and yields every visible product card.</p><p>Examples: <code>wireless earbuds</code>, <code>silk pillowcase</code>, <code>kbeauty serum</code></p><p><strong>Region support:</strong> web keyword search currently works only on <code>US</code>. Other regions either 404 the search URL or redirect to non-shop surfaces — for those, use <em>Product URLs</em> directly. (Browse-by-category is handled by a separate actor.)</p>",
            "items": {
              "type": "string"
            }
          },
          "product_urls": {
            "title": "Product URLs",
            "type": "array",
            "description": "<p>Direct product detail-page (PDP) URLs. Always returns the full detail enrichment (description, image gallery, full breadcrumb).</p><p>URL pattern: <code>https://shop.tiktok.com/{region}/pdp/{product_id}</code></p><p>Use this when you already have product IDs (from a previous run, an affiliate feed, or competitor research).</p>",
            "items": {
              "type": "string"
            }
          },
          "region": {
            "title": "Region",
            "enum": [
              "US",
              "GB",
              "VN",
              "TH",
              "PH",
              "MY",
              "SG",
              "JP",
              "MX",
              "BR"
            ],
            "type": "string",
            "description": "<p>TikTok Shop storefront for the proxy/exit IP. <strong>Must match your residential proxy's exit country</strong> — the actor probes the proxy IP and aligns the browser's locale, timezone, and geolocation automatically, but the proxy still has to land in a supported country. TikTok returns <code>{\"code\":10000}</code> on a mismatch.</p><p>Note: <code>FR</code> has no web Shop (mobile-app only); <code>ID</code> redirects to Tokopedia and is not supported.</p>",
            "default": "US"
          },
          "max_results": {
            "title": "Max Results",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "<p>Cap on products yielded <strong>per search term</strong> (or per <em>Product URL</em>, where it always equals 1). The scraper scrolls the SERP in batches; raising this triggers more scrolls.</p><p>Default 100. Hard cap 1000 — TikTok's SERP typically exhausts at 200–500 cards regardless of how high you set this.</p>",
            "default": 100
          },
          "scrape_product_details": {
            "title": "Scrape Product Details",
            "type": "boolean",
            "description": "<p>For each product yielded by a search term, fetch its full detail page (description, full image gallery, complete category breadcrumb). Adds one browser fetch per product and is billed at the higher PPE rate. Already implied for <em>Product URLs</em>.</p>",
            "default": false
          },
          "max_concurrency": {
            "title": "Max Concurrent Requests",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many product detail fetches run in parallel. Higher is faster but more likely to trigger rate-limiting.",
            "default": 3
          },
          "browser_endpoint": {
            "title": "Remote Browser Endpoint (CDP)",
            "type": "string",
            "description": "<p>Optional WebSocket URL of a remote CDP-compatible browser (Bright Data Scraping Browser, BrowserBase, etc.). Use as a fallback if the bundled Camoufox + captcha solver still gets blocked from the Apify proxy.</p><p>Example (Bright Data): <code>wss://brd-customer-XXX-zone-scraping_browser:PWD@brd.superproxy.io:9222</code></p>"
          },
          "proxy": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "<p><strong>Required.</strong> TikTok Shop blocks unauthenticated traffic from many countries with a login wall. Use Apify residential proxy with <code>US</code> or <code>GB</code> (well-covered) or your own residential proxy (BrightData, Oxylabs, SmartProxy via raw_urls). Apify's <code>VN</code> / SEA pools are best-effort and often route via EU — which fails.</p>"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}