{
  "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": "2.0",
    "x-build-id": "UJA30Cvr5Rdp8CIaw"
  },
  "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 is read straight from TikTok Shop's own search API as structured data (price, rating, sold count, seller, variants) — no browser, no scrolling, no CAPTCHA — and yields every matching product up to <em>Max Results</em>.</p><p>Examples: <code>wireless earbuds</code>, <code>silk pillowcase</code>, <code>kbeauty serum</code></p><p><strong>Region support:</strong> every supported storefront. The storefront follows your proxy's exit country, so set <em>Region</em> to match it. TikTok's search feed typically ends after 50–200 products per keyword.</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"
            }
          },
          "category_urls": {
            "title": "Category URLs",
            "type": "array",
            "description": "<p>Category browse-page URLs. Each yields every product in that category — pulled straight from TikTok Shop's own product API as structured data (price, rating, sold count, seller, variants), so no scrolling and no page-scraping.</p><p>URL pattern: <code>https://shop.tiktok.com/{region}/c/{slug}/{id}</code> — e.g. <code>https://shop.tiktok.com/us/c/beauty-personal-care/601450</code>. Copy one from the storefront's category menu. The <em>Max Results</em> cap applies per category URL.</p><p>Works in every supported region. Set <em>Region</em> to match the storefront and your proxy's exit country.</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 — United States, United Kingdom, Vietnam, Thailand, Philippines, Malaysia, Singapore, Japan, Mexico or Brazil — 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 or per category URL</strong> (or per <em>Product URL</em>, where it always equals 1). Search and category results are paged from TikTok Shop's product API.</p><p>Default 100. Hard cap 1000 — TikTok's search feed typically ends after 50–200 products per keyword 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
          },
          "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>"
          },
          "proxyProvider": {
            "title": "Proxy provider",
            "enum": [
              "default",
              "dataimpulse",
              "apify",
              "custom",
              "disabled"
            ],
            "type": "string",
            "description": "<b>Default</b> routes the run through DataImpulse residential IPs (falling back to Apify Proxy) and is <b>included in the price of the run</b>. <b>Custom</b> uses the proxy URLs you enter below; <b>Apify Proxy</b> uses the proxy configuration below; <b>No proxy</b> connects directly. Leave this empty to keep the behaviour this actor already had — nothing is imposed on a run that does not choose."
          },
          "proxyUrls": {
            "title": "Custom proxy URLs",
            "type": "array",
            "description": "Only read when <b>Proxy provider</b> is <b>Custom</b>. One gateway URL per entry, e.g. <code>http://user:pass@host:port</code> — works with any provider that issues URLs (BrightData, Oxylabs, SmartProxy, your own). Leave empty for any other Proxy provider.",
            "items": {
              "type": "string"
            }
          },
          "proxy": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "<p>Managed by the actor. Proxy is bundled — the scraper runs on its own residential proxy (DataImpulse, with Apify residential fallback), aligned to the selected <em>Region</em>. No proxy configuration is needed. Advanced users may override via the API with a <code>raw_urls</code> / provider proxy object.</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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}