{
  "openapi": "3.0.1",
  "info": {
    "title": "Funda Properties Scraper",
    "description": "Scrapes Dutch property listings from Funda: asking price, price per m², living area, rooms, build year, energy label, VvE contribution, address with postcode and neighbourhood, photos and the full Dutch feature table. For sale and for rent.",
    "version": "0.1",
    "x-build-id": "7yR8RQmDPt1oVPQGn"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapyx~funda-properties-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapyx-funda-properties-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/scrapyx~funda-properties-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapyx-funda-properties-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/scrapyx~funda-properties-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapyx-funda-properties-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",
        "required": [
          "locations"
        ],
        "properties": {
          "channel": {
            "title": "Channel",
            "enum": [
              "buy",
              "rent"
            ],
            "type": "string",
            "description": "Properties for sale (koop) or to rent (huur). Rent rows carry a monthly price condition that sale rows do not - comparing a rent amount to a sale amount without reading it compares a month of rent to a purchase price.",
            "default": "buy"
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "Where to search. Accepts a plain place name (Amsterdam, Den Haag, Noord-Holland), a Funda area slug (provincie-noord-holland, regio-groot-amsterdam, amsterdam/uilenburg, 1011lm), or a Funda search URL. Names are normalised and then verified against Funda's own resolution, and an area that does not resolve produces an ERROR row rather than a search - because Funda answers a MISSING area by returning every listing in the Netherlands. Note Funda's slug is not always the obvious one: 's-Hertogenbosch is 'den-bosch'.",
            "default": [
              "amsterdam"
            ],
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevancy",
              "newest",
              "oldest",
              "priceAsc",
              "priceDesc",
              "floorAreaDesc",
              "plotAreaDesc"
            ],
            "type": "string",
            "description": "Result ordering. Only orderings verified to actually change the result order are offered: Funda silently ignores an unknown sort and falls back to relevancy with a normal-looking page, and two plausible values ('smallest floor area first', 'smallest plot first') do exactly that.",
            "default": "relevancy"
          },
          "availability": {
            "title": "Availability",
            "type": "array",
            "description": "Which market states to include. LEAVING THIS EMPTY IS NOT 'everything': Funda's default shows only what is on the market now. For Amsterdam that is 6,194 listings, while a further 13,698 sold or rented ones sit behind this filter. Select all three to measure the whole market including sold stock. Every summary row reports the availability facet counts so you can see what was excluded.",
            "items": {
              "type": "string",
              "enum": [
                "available",
                "negotiations",
                "unavailable"
              ],
              "enumTitles": [
                "Available",
                "Under negotiation",
                "Sold / rented"
              ]
            },
            "default": []
          },
          "minPrice": {
            "title": "Min price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Lower price bound. For rent this is per month. Verified to genuinely narrow results (Amsterdam 6,194 -> 3,849 at 500,000)."
          },
          "maxPrice": {
            "title": "Max price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Upper price bound. For rent this is per month."
          },
          "objectTypes": {
            "title": "Property types",
            "type": "array",
            "description": "Optional filter. Verified: Amsterdam has 5,282 apartments against 775 houses. An unrecognised value is refused up front, because Funda answers one with an empty result set rather than an error - which would read as 'nothing matched'.",
            "items": {
              "type": "string",
              "enum": [
                "house",
                "apartment",
                "parking",
                "land",
                "berth",
                "pitch",
                "storage",
                "storage_space",
                "substructure"
              ],
              "enumTitles": [
                "House",
                "Apartment",
                "Parking",
                "Land",
                "Berth",
                "Pitch",
                "Storage",
                "Storage space",
                "Substructure"
              ]
            },
            "default": []
          },
          "constructionTypes": {
            "title": "Construction",
            "type": "array",
            "description": "Resale or new-build. Note new-build searches surface project rows, which stand for a whole development rather than one home - those carry a price RANGE and are flagged with isProject.",
            "items": {
              "type": "string",
              "enum": [
                "resale",
                "newly_built"
              ],
              "enumTitles": [
                "Existing / resale",
                "Newly built"
              ]
            },
            "default": []
          },
          "energyLabels": {
            "title": "Energy labels",
            "type": "array",
            "description": "Dutch energy labels. 'unknown' is a real value upstream and covers 927 of Amsterdam's listings, so it is offered rather than hidden.",
            "items": {
              "type": "string",
              "enum": [
                "A+++",
                "A++",
                "A+",
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "unknown"
              ]
            },
            "default": []
          },
          "exteriorSpaceTypes": {
            "title": "Outdoor space",
            "type": "array",
            "description": "Balcony, garden or terrace.",
            "items": {
              "type": "string",
              "enum": [
                "balcony",
                "garden",
                "terrace"
              ],
              "enumTitles": [
                "Balcony",
                "Garden",
                "Terrace"
              ]
            },
            "default": []
          },
          "listingTypes": {
            "title": "Listing kind",
            "type": "array",
            "description": "Individual homes or new-build project entries. A project row represents many units at once: its price and floor area are ranges, and its room counts are null. Leave empty for both.",
            "items": {
              "type": "string",
              "enum": [
                "single",
                "group"
              ],
              "enumTitles": [
                "Individual homes",
                "New-build projects"
              ]
            },
            "default": []
          },
          "minFloorArea": {
            "title": "Min floor area (m2)",
            "minimum": 0,
            "type": "integer",
            "description": "Lower bound on living area. Verified: 100 m2 narrows Amsterdam to 1,895."
          },
          "minRooms": {
            "title": "Min rooms",
            "minimum": 0,
            "type": "integer",
            "description": "Lower bound on total rooms. Project rows carry no room count and drop out when this is set."
          },
          "minBedrooms": {
            "title": "Min bedrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Lower bound on bedrooms."
          },
          "publicationDate": {
            "title": "Listed within",
            "enum": [
              "",
              "1",
              "3",
              "5",
              "10",
              "30"
            ],
            "type": "string",
            "description": "Only listings published in the last N days. Funda accepts its own windows only - any other number is silently ignored and returns the unfiltered set.",
            "default": ""
          },
          "fetchDetails": {
            "title": "Fetch each listing's detail page",
            "type": "boolean",
            "description": "Adds one request PER LISTING to pull what the search results cannot carry: the full Dutch description, the nine-group feature table (asking price per m2, VvE contribution, build year, insulation, cadastral parcels, VvE checklist), the brochure link - and the GEO COORDINATES, which search results do not contain at all. Off by default because it is roughly 15x the requests: a search page returns 15 listings, a detail page returns one. A detail page that fails does not lose the row; the search data stays and detailError says what happened.",
            "default": false
          },
          "maxPages": {
            "title": "Max pages per location",
            "minimum": 1,
            "maximum": 666,
            "type": "integer",
            "description": "Pages to fetch per location; each page is 15 listings. Capped at 666 because Funda's result window is 10,000 - past it Funda re-serves its final page forever with a normal 200 rather than ending, so the run stops on the computed last page instead of waiting for an empty one.",
            "default": 5
          },
          "maxItems": {
            "title": "Max listings",
            "minimum": 1,
            "type": "integer",
            "description": "Optional cap on total listing rows across the run, shared across every location. Counted after de-duplication."
          },
          "maxConcurrency": {
            "title": "Max concurrent requests",
            "minimum": 1,
            "maximum": 8,
            "type": "integer",
            "description": "How many requests may be in flight at once. Only matters when several locations are listed; paging within one is sequential.",
            "default": 2
          },
          "minRequestInterval": {
            "title": "Minimum interval between requests (seconds)",
            "minimum": 0.1,
            "maximum": 15,
            "type": "number",
            "description": "The honest speed control: the shortest gap between two request starts. Search pages are about 400 KB each.",
            "default": 1
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy on the shared datacenter pool. This is the default because it is included in your plan at no extra cost and this target works through it. If you start seeing blocks, challenges or empty results, switch the group here to Residential -- it uses real consumer IPs and gets through more, but Apify bills residential traffic per gigabyte, so leave it off unless you need it.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}