{
  "openapi": "3.0.1",
  "info": {
    "title": "99.co Singapore Property Listings Scraper",
    "description": "Scrape Singapore property from 99.co — HDB, condo, landed and commercial, for sale or rent. Price, PSF, floor area, beds, baths, tenure, TOP year, coordinates, nearest MRT, photos and agent phone/WhatsApp. Breaks past 99.co's 10,000-result cap to reach all 48,000+ listings. No proxy needed.",
    "version": "1.0",
    "x-build-id": "kytbUkJENQcDQVAhh"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/incognito_mode~99co-property-listings-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-incognito_mode-99co-property-listings-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/incognito_mode~99co-property-listings-scraper/runs": {
      "post": {
        "operationId": "runs-sync-incognito_mode-99co-property-listings-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/incognito_mode~99co-property-listings-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-incognito_mode-99co-property-listings-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": {
          "listingType": {
            "title": "For sale or for rent",
            "enum": [
              "sale",
              "rent"
            ],
            "type": "string",
            "description": "Which side of the market to scrape. 99.co carries about 48,000 sale listings and 22,500 rental listings.",
            "default": "sale"
          },
          "propertyType": {
            "title": "Property type",
            "enum": [
              "all",
              "condo",
              "hdb",
              "landed"
            ],
            "type": "string",
            "description": "Condo covers ECs and apartments; HDB covers all flat sizes; landed covers bungalows, semi-detached and terraces. For offices, retail and industrial use the Property segment field below instead — 99.co does not accept commercial as a property type.",
            "default": "all"
          },
          "districts": {
            "title": "Postal districts",
            "uniqueItems": true,
            "type": "array",
            "description": "Singapore postal districts to search. Leave empty for the whole island — coverage is complete either way, because the search is split by district automatically when it has to be.",
            "items": {
              "type": "string",
              "enum": [
                "D01",
                "D02",
                "D03",
                "D04",
                "D05",
                "D06",
                "D07",
                "D08",
                "D09",
                "D10",
                "D11",
                "D12",
                "D13",
                "D14",
                "D15",
                "D16",
                "D17",
                "D18",
                "D19",
                "D20",
                "D21",
                "D22",
                "D23",
                "D24",
                "D25",
                "D26",
                "D27",
                "D28"
              ],
              "enumTitles": [
                "D01 — Raffles Place, Marina",
                "D02 — Anson, Tanjong Pagar",
                "D03 — Queenstown, Tiong Bahru",
                "D04 — Telok Blangah, Sentosa",
                "D05 — Pasir Panjang, Clementi",
                "D06 — High Street, Beach Road",
                "D07 — Middle Road, Golden Mile",
                "D08 — Little India, Farrer Park",
                "D09 — Orchard, River Valley",
                "D10 — Bukit Timah, Holland, Tanglin",
                "D11 — Novena, Thomson",
                "D12 — Balestier, Toa Payoh",
                "D13 — Macpherson, Potong Pasir",
                "D14 — Geylang, Eunos, Paya Lebar",
                "D15 — Katong, Joo Chiat",
                "D16 — Bedok, Upper East Coast",
                "D17 — Loyang, Changi",
                "D18 — Tampines, Pasir Ris",
                "D19 — Hougang, Punggol, Sengkang",
                "D20 — Bishan, Ang Mo Kio",
                "D21 — Upper Bukit Timah, Ulu Pandan",
                "D22 — Jurong, Boon Lay, Tuas",
                "D23 — Bukit Panjang, Choa Chu Kang",
                "D24 — Lim Chu Kang, Tengah",
                "D25 — Kranji, Woodlands",
                "D26 — Upper Thomson, Springleaf",
                "D27 — Yishun, Sembawang",
                "D28 — Seletar, Yio Chu Kang"
              ]
            },
            "default": []
          },
          "searchUrl": {
            "title": "…or paste a 99.co search URL",
            "type": "string",
            "description": "Paste a search URL from 99.co and its filters are read out of it (listing type, property type, districts, price, bedrooms, bathrooms, tenure, furnishing). Anything you also set explicitly above wins over the URL."
          },
          "maxItems": {
            "title": "Maximum listings",
            "minimum": 1,
            "type": "integer",
            "description": "How many listings to return. This is what you are billed for, one charge per listing. There is no unlimited setting — asking for the whole 48,000-listing sale market takes far longer than one run's time budget, so raise maxRunSecs alongside this for large pulls.",
            "default": 100
          },
          "minPrice": {
            "title": "Minimum price (SGD)",
            "minimum": 0,
            "type": "integer",
            "description": "Total price for sale listings, monthly rent for rentals."
          },
          "maxPrice": {
            "title": "Maximum price (SGD)",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on the same figure — total price for sale, monthly rent for rentals."
          },
          "bedrooms": {
            "title": "Bedrooms",
            "uniqueItems": true,
            "type": "array",
            "description": "Match any of the selected bedroom counts.",
            "items": {
              "type": "string",
              "enum": [
                "0",
                "1",
                "2",
                "3",
                "4",
                "5",
                "6",
                "7"
              ],
              "enumTitles": [
                "Studio",
                "1 bedroom",
                "2 bedrooms",
                "3 bedrooms",
                "4 bedrooms",
                "5 bedrooms",
                "6 bedrooms",
                "7+ bedrooms"
              ]
            },
            "default": []
          },
          "bathrooms": {
            "title": "Bathrooms (minimum)",
            "minimum": 0,
            "type": "integer",
            "description": "Only listings with at least this many bathrooms."
          },
          "tenure": {
            "title": "Tenure",
            "uniqueItems": true,
            "type": "array",
            "description": "Freehold, 999-year or 99-year leasehold.",
            "items": {
              "type": "string",
              "enum": [
                "freehold",
                "999",
                "99"
              ],
              "enumTitles": [
                "Freehold",
                "999-year leasehold",
                "99-year leasehold"
              ]
            },
            "default": []
          },
          "furnishing": {
            "title": "Furnishing",
            "uniqueItems": true,
            "type": "array",
            "description": "Most useful on rentals, where two thirds of listings state it.",
            "items": {
              "type": "string",
              "enum": [
                "fully",
                "partial",
                "unfurnished"
              ],
              "enumTitles": [
                "Fully furnished",
                "Partially furnished",
                "Unfurnished"
              ]
            },
            "default": []
          },
          "propertySegment": {
            "title": "Property segment",
            "enum": [
              "any",
              "residential",
              "commercial"
            ],
            "type": "string",
            "description": "Leave as Any for both. Commercial is how you reach offices, retail, industrial and warehouse listings (about 4,900 of them).",
            "default": "any"
          },
          "rentalType": {
            "title": "Whole units or rooms (rentals only)",
            "enum": [
              "any",
              "whole_unit",
              "room"
            ],
            "type": "string",
            "description": "99.co's rental feed mixes whole units with room rentals — renting a single bedroom in a shared flat — and rooms are 46% of it (10,364 of 22,570). Averaging the two together makes rent and PSF figures meaningless, so pick one unless you want both.",
            "default": "any"
          },
          "minFloorAreaSqft": {
            "title": "Minimum floor area (sqft)",
            "minimum": 0,
            "type": "integer",
            "description": "Applied after fetching, since 99.co offers no floor-area parameter. Listings that do not state an area are kept, not dropped."
          },
          "maxFloorAreaSqft": {
            "title": "Maximum floor area (sqft)",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on floor area, also applied here rather than by 99.co."
          },
          "newLaunchOnly": {
            "title": "New launches only",
            "type": "boolean",
            "description": "Restrict to new-launch projects (about 3,000 listings).",
            "default": false
          },
          "includeAgentContacts": {
            "title": "Include agent contact details",
            "type": "boolean",
            "description": "Adds the listing agent's name, phone and WhatsApp number in full international format, plus 99.co's own pre-filled enquiry message. These are the business contact details the agent publishes on the listing. Note that agency name and CEA licence number are not available from 99.co's API and are never returned.",
            "default": true
          },
          "includePhotoGallery": {
            "title": "Include the full photo gallery",
            "type": "boolean",
            "description": "Adds every photo URL with its caption and room category. Off by default because it can triple the size of a row; the main photo is always included.",
            "default": false
          },
          "completeCoverage": {
            "title": "Break past 99.co's 10,000-result limit",
            "type": "boolean",
            "description": "99.co refuses to serve more than 10,000 results for any single search, so a plain scraper can only ever reach 10,000 of the 48,000 sale listings. Leave this on and the search is split by postal district automatically once you ask for more than the limit allows, which reaches all of them. It costs nothing on smaller runs — no split happens unless it is needed.",
            "default": true
          },
          "maxRunSecs": {
            "title": "Time budget (seconds)",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "The run stops cleanly and keeps everything collected so far once this is reached. Raise it for large pulls; the default is tuned so a default run finishes well inside Apify's five-minute automated test.",
            "default": 210
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Not needed. 99.co is reached directly — Cloudflare here is a TLS gate that this Actor clears without a proxy, unlike competing scrapers that bill you for residential traffic. A proxy is used automatically only if a request is genuinely blocked.",
            "default": {
              "useApifyProxy": 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}