{
  "openapi": "3.0.1",
  "info": {
    "title": "LIHKG Scraper – Keyword Search, Replies & HK Social Listening",
    "description": "Scrape LIHKG, Hong Kong's biggest forum: site-wide keyword search, board thread listings, full posts and replies with reactions and timestamps. Schedule daily runs for brand keyword monitoring — only threads with new activity. No API or login. Export JSON/CSV/Excel for HK social listening.",
    "version": "1.0",
    "x-build-id": "73KHQHGq527x5GWaI"
  },
  "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 are all fetched by default; set maxReplies to cap replies per thread, by floor). Search mode: max results per keyword. Maximum 2000.",
            "default": 50
          },
          "maxReplies": {
            "title": "🧵 Max replies per thread (optional)",
            "minimum": 1,
            "type": "integer",
            "description": "Thread mode only. Maximum number of replies to collect per thread. Every reply is billed as one review-item and a long thread can have thousands of replies, so set this to cap your cost per thread. Takes the first N reply floors of each thread (by floor number; deleted floors can make it slightly fewer than N). Leave empty for no limit (default: the whole thread). Unrelated to Max items, which limits the number of threads."
          },
          "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."
          },
          "aiLabels": {
            "title": "🤖 AI sentiment labels (+$0.002 per row)",
            "type": "boolean",
            "description": "When on, every row gets extra AI-judged fields: whether it concerns your tracked topic (ai_relevance), a sentiment score and negative/neutral/positive label (ai_sentiment, ai_sentiment_label), the intent (ai_intent: complaint / praise / question / other) and a confidence score for each. Each successfully labelled row is billed $0.002 (the ai-label event); rows whose labelling fails are not billed. Text is sent to TypeSafe (US) for processing. Free plan: the first 20 rows per run are labelled. Off by default.",
            "default": false
          },
          "aiTopic": {
            "title": "🎯 Brand or topic to track (for relevance)",
            "type": "string",
            "description": "Optional. The AI judges whether each post is about this brand or topic (ai_relevance). When empty: search mode uses the row's search keyword; category-listing and thread modes skip the relevance question and ai_relevance is null, while the other labels are still produced. Only used when AI sentiment labels are on."
          },
          "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}