{
  "openapi": "3.0.1",
  "info": {
    "title": "TikTok Posts Scraper",
    "description": "TikTok Posts Scraper extracts public post data including captions, creators, hashtags, views, likes, comments, shares, upload dates, and video URLs. Build structured datasets for content research, trend analysis, influencer discovery, and competitor monitoring.",
    "version": "0.1",
    "x-build-id": "y8EZyOIBC9HZF2Qfz"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scraper-engine~tiktok-posts-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scraper-engine-tiktok-posts-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/scraper-engine~tiktok-posts-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scraper-engine-tiktok-posts-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/scraper-engine~tiktok-posts-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scraper-engine-tiktok-posts-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": {
          "startUrls": {
            "title": "🔗 Start URLs (profile / video / hashtag / search / music)",
            "type": "array",
            "description": "Paste any TikTok URLs and get results immediately — profile, video, hashtag (#tag), search, or music links, mixed freely in one list. Paste directly, upload a file, or link to a hosted .txt file (one URL per line) for bulk input. When this is filled in, 'Scrape Mode' below is ignored.",
            "items": {
              "type": "string"
            }
          },
          "scrapeMode": {
            "title": "🧭 Scrape Mode",
            "enum": [
              "profiles",
              "hashtag",
              "keyword"
            ],
            "type": "string",
            "description": "Used only when 'Start URLs' above is empty. Choose what kind of TikTok data to scrape.",
            "default": "profiles"
          },
          "profiles": {
            "title": "👤 TikTok Profiles",
            "type": "array",
            "description": "Usernames to scrape (without the @). Required when Scrape Mode is 'profiles'.",
            "items": {
              "type": "string"
            }
          },
          "hashtag": {
            "title": "#️⃣ Hashtag",
            "type": "string",
            "description": "One hashtag to scrape posts from (without the #). Required when Scrape Mode is 'hashtag'."
          },
          "keyword": {
            "title": "🔍 Search Keyword",
            "type": "string",
            "description": "Keyword or phrase to search TikTok for. Required when Scrape Mode is 'keyword'."
          },
          "maxResultsPerProfile": {
            "title": "📦 Max Results Per Profile",
            "minimum": 1,
            "maximum": 500000,
            "type": "integer",
            "description": "Maximum number of posts to collect per profile (profiles mode only).",
            "default": 30
          },
          "maxResults": {
            "title": "📦 Max Results",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum total number of posts to collect (hashtag and keyword-search modes only).",
            "default": 50
          },
          "sortBy": {
            "title": "↕️ Sort By",
            "enum": [
              "latest",
              "popular",
              "relevance",
              "most-liked",
              "date-posted"
            ],
            "type": "string",
            "description": "Applied client-side after collection. Profiles mode: 'latest' or 'popular'. Keyword-search mode: 'relevance', 'most-liked', or 'date-posted'. Leave empty to keep TikTok's own order."
          },
          "datePosted": {
            "title": "📅 Date Posted Filter",
            "enum": [
              "yesterday",
              "this-week",
              "this-month",
              "last-3-months",
              "last-6-months",
              "all-time"
            ],
            "type": "string",
            "description": "Only keep posts published within this window (keyword-search mode only)."
          },
          "region": {
            "title": "🌍 Region",
            "minLength": 2,
            "maxLength": 2,
            "type": "string",
            "description": "2-letter country code (e.g. US, GB, FR) — sent as a locale/Accept-Language hint. For a real change of exit IP geography, also pick a country inside 'Proxy configuration' below."
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy Configuration",
            "type": "object",
            "description": "🟢 Default = no proxy (direct connection), which works for most runs. If TikTok starts rejecting requests, the Actor automatically escalates itself: Direct ➜ 🖥️ Datacenter proxy ➜ 🏠 Residential proxy (retried up to 3×), then stays on residential for the rest of the run. Every switch is logged. Override this only to force a specific proxy from the start."
          },
          "maxMountRetries": {
            "title": "🔁 Max Page-Load Retries",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many times to reload a page before treating it as blocked and escalating the proxy. Raise this if runs on a slow connection give up too early.",
            "default": 5
          },
          "maxScrollRetries": {
            "title": "🔁 Max Empty-Scroll Retries",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many consecutive scrolls with no new posts to allow before assuming a target has no more results. Raise this if a run stops short of 'Max Results' on a profile/hashtag/search that clearly has more content.",
            "default": 8
          },
          "maxScanned": {
            "title": "🔎 Max Scanned Rows",
            "minimum": 100,
            "maximum": 200000,
            "type": "integer",
            "description": "Safety cap on how many raw posts a single target may scan through while paginating, even if 'Max Results' hasn't been reached yet (protects against a runaway crawl).",
            "default": 20000
          },
          "concurrency": {
            "title": "⚡ Concurrency",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "How many targets (profiles/hashtags/searches/URLs) to scrape in parallel browser tabs. Keep this low — TikTok's anti-bot risk system is more likely to challenge a run that looks like a burst of parallel traffic.",
            "default": 2
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}