{
  "openapi": "3.0.1",
  "info": {
    "title": "Twitch Scraper — Channels, Streams, Clips & VODs",
    "description": "Scrapes public Twitch data with no login or API key: channel profiles and follower counts, live stream status and viewers, top categories, clips, past broadcasts and search. Anonymous access is capped at 30 rows per query by Twitch, and every run reports it.",
    "version": "0.1",
    "x-build-id": "PfxlZLmoDiW115aKL"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapyx~twitch-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapyx-twitch-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/scrapyx~twitch-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapyx-twitch-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/scrapyx~twitch-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapyx-twitch-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": {
          "mode": {
            "title": "What to scrape",
            "enum": [
              "channel",
              "streams",
              "games",
              "clips",
              "videos",
              "search"
            ],
            "type": "string",
            "description": "Decides what your `queries` mean and which rows you get.\n\n• **Channel** — channel names → profile, follower count, live status, social links\n• **Live streams** — top live streams globally, or within a category if you name one\n• **Top categories** — the most-watched games/categories right now\n• **Clips** — channel names → their top clips\n• **Videos (VODs)** — channel names → past broadcasts, highlights or uploads\n• **Search** — search terms → matching channels and categories",
            "default": "channel"
          },
          "queries": {
            "title": "Channels / categories / search terms",
            "type": "array",
            "description": "One entry per thing to scrape. Meaning depends on the mode:\n\n• **Channel / Clips / Videos** — a channel name (`shroud`) or a `twitch.tv/<channel>` URL\n• **Live streams** — a category name exactly as Twitch spells it (`Just Chatting`, `Grand Theft Auto V`), or a `twitch.tv/directory/category/...` URL. **Leave empty for the global top streams.**\n• **Top categories** — leave empty; this mode takes no input\n• **Search** — any search term",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max results per query",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Rows per query. **Twitch's hard ceiling for anonymous access is 30** — it refuses every pagination cursor, so no tool can exceed this per single query. To collect more, add more entries to `queries`, or (in Clips mode) select several time periods. Every run reports this in its summary row.",
            "default": 30
          },
          "clipPeriods": {
            "title": "Clip time periods",
            "type": "array",
            "description": "Clips mode only. Each period costs one request and returns up to 30 clips — and periods genuinely overlap very little, so selecting several is the way to get past 30. Measured on one channel: last week (25) + last month (30) gave 54 unique clips.",
            "items": {
              "type": "string",
              "enum": [
                "LAST_DAY",
                "LAST_WEEK",
                "LAST_MONTH",
                "ALL_TIME"
              ],
              "enumTitles": [
                "Last 24 hours",
                "Last week",
                "Last month",
                "All time"
              ]
            },
            "default": [
              "LAST_WEEK"
            ]
          },
          "clipSort": {
            "title": "Clip sort",
            "enum": [
              "VIEWS_DESC",
              "TRENDING",
              "CREATED_AT_DESC"
            ],
            "type": "string",
            "description": "Clips mode only. `Most viewed` is the dependable option. `Trending` is accepted by Twitch but often returns nothing even on channels with plenty of clips, and `Newest first` currently answers a server error upstream — both are offered for completeness and both are reported honestly in the run summary if they come back empty.",
            "default": "VIEWS_DESC"
          },
          "broadcastType": {
            "title": "Video type",
            "enum": [
              "ARCHIVE",
              "HIGHLIGHT",
              "UPLOAD",
              "PAST_PREMIERE"
            ],
            "type": "string",
            "description": "Videos mode only. Note that Twitch auto-deletes past broadcasts after 7–60 days depending on the channel's status, so an empty `Past broadcasts` result is normal rather than an error.",
            "default": "ARCHIVE"
          },
          "videoSort": {
            "title": "Video sort",
            "enum": [
              "TIME",
              "VIEWS"
            ],
            "type": "string",
            "description": "Videos mode only: newest first, or most viewed first.",
            "default": "TIME"
          },
          "streamSort": {
            "title": "Stream sort",
            "enum": [
              "VIEWER_COUNT",
              "RECENT",
              "RELEVANCE"
            ],
            "type": "string",
            "description": "Live streams mode only. Twitch applies its own recommendation weighting on top of this, so the returned order is close to — but not strictly — the sort you pick.",
            "default": "VIEWER_COUNT"
          },
          "languages": {
            "title": "Stream languages",
            "type": "array",
            "description": "Live streams mode only. Restrict to streams broadcast in these languages. Leave empty for all languages. Another useful way to widen coverage past the 30-row ceiling: the same category in three languages is three separate result sets.",
            "items": {
              "type": "string",
              "enum": [
                "EN",
                "ES",
                "PT",
                "DE",
                "FR",
                "IT",
                "RU",
                "JA",
                "KO",
                "ZH",
                "TR",
                "PL",
                "NL",
                "AR",
                "TH",
                "CS",
                "SV",
                "DA",
                "FI",
                "NO",
                "HU",
                "ID"
              ]
            },
            "default": []
          },
          "maxConcurrency": {
            "title": "Max concurrent requests",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "Upper bound on requests in flight at once. Keep it modest — Twitch throttles a hot IP by answering individual queries with a server error rather than a clean rate-limit status.",
            "default": 4
          },
          "minRequestInterval": {
            "title": "Minimum seconds between request starts",
            "minimum": 0,
            "maximum": 30,
            "type": "number",
            "description": "The honest speed control — it paces request starts without tying up a worker. Raise it if the log shows repeated server-error retries.",
            "default": 0.3
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "**Required in practice.** Twitch gates this API by exit-IP reputation: a residential IP works, a datacenter IP is refused with `failed integrity check` on every request (verified on real cloud runs — a self-minted integrity token does not help). Use Apify Proxy with the RESIDENTIAL group. Without it, every row will be an `integrity_refused` error explaining this.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}