{
  "openapi": "3.0.1",
  "info": {
    "title": "LIHKG Scraper – Hong Kong Forum Threads, Replies & Sentiment",
    "description": "Scrape LIHKG (a major Hong Kong forum) threads and replies for social listening: title, author, reply count, reactions, content and timestamps. No API or login. Export JSON/CSV/Excel. Ideal for HK sentiment analysis and brand monitoring.",
    "version": "1.0",
    "x-build-id": "pwlMvPVFhszzFQVzE"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/claude_code_reviewer~lihkg-scraper-en/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-claude_code_reviewer-lihkg-scraper-en",
        "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/claude_code_reviewer~lihkg-scraper-en/runs": {
      "post": {
        "operationId": "runs-sync-claude_code_reviewer-lihkg-scraper-en",
        "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/claude_code_reviewer~lihkg-scraper-en/run-sync": {
      "post": {
        "operationId": "run-sync-claude_code_reviewer-lihkg-scraper-en",
        "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": "🎯 Mode",
            "enum": [
              "thread-list",
              "thread",
              "search"
            ],
            "type": "string",
            "description": "What do you want to scrape? Pick a mode and fill in the matching fields below.",
            "default": "thread-list"
          },
          "catIds": {
            "title": "📋 Category IDs",
            "maxItems": 50,
            "uniqueItems": true,
            "type": "array",
            "description": "LIHKG category IDs (numeric), e.g. 1 (Chat), 2 (Sports), 5 (Current Affairs). Used by listing mode. Enter all to expand to every one of the 37 postable categories (aggregate boards such as Hot / Latest / Custom are excluded automatically); maxItems is a per-category cap, not a total.",
            "items": {
              "type": "string"
            }
          },
          "threadIds": {
            "title": "💬 Thread IDs",
            "maxItems": 100,
            "uniqueItems": true,
            "type": "array",
            "description": "LIHKG thread IDs (numeric), e.g. 1234567. Used by thread mode.",
            "items": {
              "type": "string"
            }
          },
          "threadUrls": {
            "title": "💬 Thread URLs",
            "maxItems": 100,
            "uniqueItems": true,
            "type": "array",
            "description": "Full LIHKG thread URLs, e.g. https://lihkg.com/thread/1234567/page/1. The thread ID is extracted automatically.",
            "items": {
              "type": "string"
            }
          },
          "bulkInput": {
            "title": "📋 Bulk paste",
            "type": "string",
            "description": "**One item per line** (press Enter for a new line, no quotes or commas). Treated as category IDs in listing mode, thread IDs/URLs in thread mode, or keywords in search mode, and merged into the matching field above at runtime. Fastest way is to copy a whole column from Google Sheets / Excel."
          },
          "maxItems": {
            "title": "📊 Max items",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Listing mode: max threads per category. Thread mode: max threads to scrape (replies per thread are not limited by this). Search mode: max results per keyword. Maximum 2000.",
            "default": 50
          },
          "keywords": {
            "title": "🔍 Keywords",
            "maxItems": 50,
            "uniqueItems": true,
            "type": "array",
            "description": "Search mode: the keywords to search for (brand names, product names, property developers); each keyword runs its own search. Listing mode: only keep threads whose title contains at least one keyword (filter; leave empty for no filtering). Bulk-pasted lines are merged in here in search mode.",
            "items": {
              "type": "string"
            }
          },
          "order": {
            "title": "🔃 Sort order",
            "enum": [
              "desc_reply_time",
              "desc_create_time",
              "score"
            ],
            "type": "string",
            "description": "Search mode only. Latest replies first suits monitoring (with dateFrom it also stops paging early); newest threads first shows freshly opened threads; relevance first suits research.",
            "default": "desc_reply_time"
          },
          "dateFrom": {
            "title": "📅 Only threads active since (optional)",
            "type": "string",
            "description": "Formats: relative 3d (last 3 days), 12h (last 12 hours), 2w (last 2 weeks), or an absolute date MM/DD/YY. Leave empty for no filtering. When set, paging also stops early, which keeps scheduled monitoring cheap."
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy (Apify datacenter proxy on by default)",
            "type": "object",
            "description": "Apify datacenter proxy is on by default. Without a proxy your run shares the platform's egress IPs with every other run, so LIHKG rate-limits you for traffic you never sent (429s, missing reply pages). Responses are small JSON, so proxy bandwidth cost is negligible. Turn it off only for local testing or your own proxyUrls.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}