{
  "openapi": "3.0.1",
  "info": {
    "title": "PropertyGuru Property Scraper",
    "description": "Scrape PropertyGuru listings across Singapore, Malaysia and Thailand: asking price, PSF, beds, baths, floor area, tenure, district, nearest MRT, agent name, licence and phone. Sale and rent. Export JSON, CSV or Excel.",
    "version": "1.0",
    "x-build-id": "tIkS99mzHq1myS1ov"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/sian.agency~propertyguru-property-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-sian.agency-propertyguru-property-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/sian.agency~propertyguru-property-scraper/runs": {
      "post": {
        "operationId": "runs-sync-sian.agency-propertyguru-property-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/sian.agency~propertyguru-property-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-sian.agency-propertyguru-property-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": {
          "operation": {
            "title": "🎯 What do you want to scrape?",
            "enum": [
              "search",
              "detail"
            ],
            "type": "string",
            "description": "Pick one operation per run. Search returns twenty properties per page and is where the value is; Detail opens a single listing for its description, coordinates, facilities and the agent's phone number, and is priced as an add-on.",
            "default": "search"
          },
          "market": {
            "title": "🌏 Market",
            "enum": [
              "sg",
              "my",
              "th"
            ],
            "type": "string",
            "description": "Which PropertyGuru site to search. All three run on one codebase, so every filter and every output column behaves the same way in each. Prices stay in the local currency: SGD in Singapore, MYR in Malaysia, THB in Thailand. Ignored when you paste your own search URLs, since the URL already names the site.",
            "default": "sg"
          },
          "listingType": {
            "title": "🏷️ Sale or rent",
            "enum": [
              "sale",
              "rent"
            ],
            "type": "string",
            "description": "Sale is the larger side in Singapore (56,000 live ads against 22,000 rentals). Rental prices come back per month.",
            "default": "sale"
          },
          "propertyGroup": {
            "title": "🏠 Property type",
            "enum": [
              "",
              "N",
              "H",
              "L"
            ],
            "type": "string",
            "description": "Narrow to one slice of the market. Measured on Singapore for sale: any type 56,381 ads, condo and apartment 33,226, HDB 14,123, landed 9,046. HDB only exists in Singapore, so it returns nothing on the Malaysian or Thai sites.",
            "default": ""
          },
          "bedrooms": {
            "title": "🛏️ Bedrooms",
            "enum": [
              "",
              "studio",
              "1",
              "2",
              "3",
              "4",
              "5"
            ],
            "type": "string",
            "description": "An exact bedroom count, not a minimum. PropertyGuru only honours this as a path filter, so the actor writes it into the search path rather than the query string, where the site would drop it silently.",
            "default": ""
          },
          "minPrice": {
            "title": "💵 Minimum price",
            "minimum": 0,
            "type": "integer",
            "description": "Lowest asking price to include, in the market's own currency and in whole units - 800000 means S$800,000 on a sale search and S$800 per month on a rental one. Leave at 0 for no floor.",
            "default": 0
          },
          "maxPrice": {
            "title": "💰 Maximum price",
            "minimum": 0,
            "type": "integer",
            "description": "Highest asking price to include, same units as the minimum. Leave at 0 for no ceiling. PropertyGuru injects a handful of sponsored ads that sit outside the price you asked for; those are dropped rather than returned and billed.",
            "default": 0
          },
          "minSizeSqft": {
            "title": "📐 Minimum floor area (sqft)",
            "minimum": 0,
            "type": "integer",
            "description": "Smallest floor area to include, in square feet, which is the unit all three sites quote. Leave at 0 for no floor.",
            "default": 0
          },
          "maxResults": {
            "title": "🔢 Max properties",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Stop after this many properties. Each page returns twenty, so the run stops at the first page that crosses your limit.",
            "default": 60
          },
          "searchUrls": {
            "title": "🔗 Search URLs",
            "type": "array",
            "description": "Paste search URLs straight from PropertyGuru and they are used exactly as given, overriding every filter above. Anything the site can show, this can read: https://www.propertyguru.com.sg/property-for-sale/with-3-bedrooms?minPrice=800000, https://www.propertyguru.com.my/property-for-rent, https://www.ddproperty.com/en/property-for-sale. Build the search you want on the site, copy the address bar, paste it here.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "listingUrls": {
            "title": "📄 Property URLs",
            "type": "array",
            "description": "Used by the Property Detail operation: PropertyGuru listing URLs to open, e.g. https://www.propertyguru.com.sg/listing/for-sale-the-florence-residences-500176941. Filling this switches the run to Detail.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "includeDetails": {
            "title": "📞 Add descriptions, GPS & agent phone numbers",
            "type": "boolean",
            "description": "Open every property's own page to add the full description, GPS coordinates, postcode, developer, tenure, furnishing, floor level, the complete photo set, the building's facilities and the agent's phone number. Costs one extra request per property and bills the Property Detail event on top of the search row, so a 100-property run bills 100 search rows plus 100 detail rows.",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}