{
  "openapi": "3.0.1",
  "info": {
    "title": "28Hse Scraper – Hong Kong Property Listings, FSBO & Details",
    "description": "Scrape 28Hse, a Hong Kong property portal, without an API or login: sale and rental listings plus full property details — price, saleable area, unit price, layout, district and estate, with agent vs owner (FSBO) marker. Unique owner asking-price data for HK property valuation. Export JSON/CSV/Excel.",
    "version": "1.0",
    "x-build-id": "uaTQporAkj5gP1Q6n"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/claude_code_reviewer~28hse-scraper-en/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-claude_code_reviewer-28hse-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~28hse-scraper-en/runs": {
      "post": {
        "operationId": "runs-sync-claude_code_reviewer-28hse-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~28hse-scraper-en/run-sync": {
      "post": {
        "operationId": "run-sync-claude_code_reviewer-28hse-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "🎯 Mode",
            "enum": [
              "listing",
              "detail",
              "transactions"
            ],
            "type": "string",
            "description": "What do you want to scrape? Pick a mode and fill in the matching fields below.",
            "default": "listing"
          },
          "dealType": {
            "title": "🏷️ Buy / Rent",
            "enum": [
              "buy",
              "rent"
            ],
            "type": "string",
            "description": "Used by listing mode (also needed in detail mode when using propertyIds instead of propertyUrls, to build the URL).",
            "default": "buy"
          },
          "propertyType": {
            "title": "🏢 Property type",
            "enum": [
              "apartment",
              "village",
              "house",
              "carpark",
              "shop",
              "office",
              "land"
            ],
            "type": "string",
            "description": "Used by listing mode (also needed in detail mode when using propertyIds instead of propertyUrls, to build the URL). Only \"Apartment\" has been fully tested (GREEN); other types use the same URL pattern but haven't each been individually verified.",
            "default": "apartment"
          },
          "listingUrls": {
            "title": "📋 Listing page URLs (optional, overrides the two fields above)",
            "maxItems": 20,
            "uniqueItems": true,
            "type": "array",
            "description": "Directly specify 28Hse listing page URLs, e.g. https://www.28hse.com/buy/apartment or https://www.28hse.com/rent/village. Multiple URLs are allowed, each paginated and counted independently. Leave empty to auto-build the URL from \"Buy / Rent\" + \"Property type\" above.",
            "items": {
              "type": "string"
            }
          },
          "propertyIds": {
            "title": "🏠 Property IDs",
            "maxItems": 500,
            "uniqueItems": true,
            "type": "array",
            "description": "28Hse property IDs (the numeric part of property-{id} in the URL), e.g. 3948689. When used in detail mode, also set \"Buy / Rent\" and \"Property type\" so the correct URL can be built.",
            "items": {
              "type": "string"
            }
          },
          "propertyUrls": {
            "title": "🏠 Property URLs",
            "maxItems": 500,
            "uniqueItems": true,
            "type": "array",
            "description": "Full 28Hse property URLs, e.g. https://www.28hse.com/buy/apartment/property-3948689. This is the safest way to use detail mode (deal type / property type are already in the URL, unaffected by the fields above).",
            "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 property IDs or property URLs depending on the current mode, and merged into the matching field above at runtime. Fastest way is to copy a whole column from Google Sheets / Excel."
          },
          "ownerOnly": {
            "title": "🔑 FSBO only (owner-listed properties)",
            "type": "boolean",
            "description": "Listing mode only: only keep listings the page marks as owner-listed / FSBO, filtering out agent listings. FSBO listings are usually rare within a single category — if 5 consecutive pages return no matching listings, the run stops early (see Notes, to avoid burning cost for nothing).",
            "default": false
          },
          "maxItems": {
            "title": "📊 Max items",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Listing mode: max items per listing source. Detail mode: max property IDs/URLs to scrape. Maximum 500.",
            "default": 50
          },
          "dateFrom": {
            "title": "📅 Only listings posted after this time (optional, listing mode)",
            "type": "string",
            "description": "Based on the listing's \"posted at\" time (28Hse listings default to newest-first). 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. Not applicable to detail mode (a single property has no pages to stop early 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 egress IPs with every other run on the platform, making it easy to get rate-limited or blocked. Pages aren't tiny (0.3–1.3MB), but datacenter bandwidth cost is still negligible. Turn it off only for your own proxy or local testing.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}