{
  "openapi": "3.0.1",
  "info": {
    "title": "Batdongsan Scraper - Vietnam Property Data",
    "description": "Scrape Batdongsan.com.vn listings across Vietnam: price in VND and USD, area, price per m², bedrooms, district, agent, verified badge and posted date. Sale and rent. JSON, CSV or Excel.",
    "version": "1.0",
    "x-build-id": "Zgh1k3D7K77gl2vkl"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/sian.agency~batdongsan-property-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-sian.agency-batdongsan-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~batdongsan-property-scraper/runs": {
      "post": {
        "operationId": "runs-sync-sian.agency-batdongsan-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~batdongsan-property-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-sian.agency-batdongsan-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"
            ],
            "type": "string",
            "description": "Property Search sweeps Batdongsan's own results pages and returns about 20 listings per request. Choose for sale or for rent, a property category, one or more provinces, and optionally the site's own price and area bands. You can also paste Batdongsan search URLs directly and they are followed exactly as given.",
            "default": "search"
          },
          "listingType": {
            "title": "🏷️ For sale or for rent",
            "enum": [
              "ban",
              "cho-thue"
            ],
            "type": "string",
            "description": "Which half of the Batdongsan market to read. Rent prices are per month and are returned as a monthly figure with the period named on the row, so sale and rent rows can never be confused after export. The two halves carry different property categories - offices and boarding rooms exist only for rent, land and condotels only for sale - and an unavailable combination is rejected before anything is charged.",
            "default": "ban"
          },
          "propertyType": {
            "title": "🏡 Property category",
            "enum": [
              "all",
              "apartment",
              "mini-apartment",
              "house",
              "street-house",
              "villa",
              "shophouse",
              "land",
              "project-land",
              "warehouse",
              "condotel",
              "farm-resort",
              "office",
              "room",
              "other"
            ],
            "type": "string",
            "description": "Which Batdongsan category to read. Several categories exist on only one side of the market, which the titles say: shophouses, land, project land plots, condotels and farm/resort land are sale-only, while offices and boarding rooms are rent-only. Pick one that does not exist for the chosen listing type and the run stops with the list of categories that do, before anything is charged - it never quietly falls back to all categories and bills you for the wrong rows.",
            "default": "all"
          },
          "provinces": {
            "title": "📍 Provinces and cities",
            "type": "array",
            "description": "Batdongsan's own province slugs, one search per entry. The eleven the site itself features are tp-hcm, ha-noi, da-nang, hai-phong, binh-duong, dong-nai, ba-ria-vung-tau, long-an, khanh-hoa, quang-ninh, hung-yen and quang-nam. Any other slug the site publishes works too - it is put into the URL exactly as typed. Leave the list empty to sweep the whole country. Three provinces return roughly three times the rows, and a slug the site does not publish is reported on its own row as a location that…",
            "default": [
              "tp-hcm"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "🔢 Max listings",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Stop after this many listings across every province in the list. A results page carries 20 listings, so the run finishes the page that crosses your limit and then stops. Free-plan runs are capped lower; the run log and the report both say so when the cap bites.",
            "default": 100
          },
          "priceBand": {
            "title": "💵 Price band",
            "enum": [
              "",
              "gia-thuong-luong",
              "gia-duoi-500-trieu",
              "gia-tu-500-trieu-den-800-trieu",
              "gia-tu-800-trieu-den-1-ty",
              "gia-tu-1-ty-den-2-ty",
              "gia-tu-2-ty-den-3-ty",
              "gia-tu-3-ty-den-5-ty",
              "gia-tu-5-ty-den-7-ty",
              "gia-tu-7-ty-den-10-ty",
              "gia-tu-10-ty-den-20-ty",
              "gia-tu-20-ty-den-30-ty",
              "gia-tu-30-ty-den-40-ty",
              "gia-tu-40-ty-den-60-ty",
              "gia-tren-60-ty"
            ],
            "type": "string",
            "description": "Batdongsan's own price bands, taken from the bands the site publishes on its results pages rather than invented, so the filter is applied by the site itself and the count you see is the count you get. These are sale prices; on the rent side the same bands read as monthly rent. Price and area bands cannot both be applied in one search - if you set both, the price band wins and the run log says so.",
            "default": ""
          },
          "areaBand": {
            "title": "📐 Area band",
            "enum": [
              "",
              "dt-duoi-30m2",
              "dt-tu-30m2-den-50m2",
              "dt-tu-50m2-den-80m2",
              "dt-tu-80m2-den-100m2",
              "dt-tu-100m2-den-150m2",
              "dt-tu-150m2-den-200m2",
              "dt-tu-200m2-den-250m2",
              "dt-tu-250m2-den-300m2",
              "dt-tu-300m2-den-500m2",
              "dt-tren-500m2"
            ],
            "type": "string",
            "description": "Batdongsan's own floor-area bands, again copied from the bands the site publishes. Used only when no price band is set, because the site's URL scheme accepts one band at a time.",
            "default": ""
          },
          "searchUrls": {
            "title": "🔗 Batdongsan search URLs",
            "type": "array",
            "description": "Paste Batdongsan search URLs and they are fetched exactly as written, filters and all - build the search you want on the site, copy the address bar, and every option above is ignored. Useful for the district, street, project and bedroom filters that have no field here. Pagination is still followed, so one URL can return thousands of rows.",
            "default": [],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}