{
  "openapi": "3.0.1",
  "info": {
    "title": "Imovirtual & Storia Property Scraper (Portugal, Romania)",
    "description": "Scrapes property listings from Imovirtual (Portugal) and Storia (Romania), the leading OLX Group real-estate portals in each market. Each row carries price, area, rooms, address, agency contact and photos, with optional full listing details.",
    "version": "0.1",
    "x-build-id": "BBlKVU1U41RsZuMAQ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapyx~imovirtual-storia-properties-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapyx-imovirtual-storia-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~imovirtual-storia-properties-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapyx-imovirtual-storia-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~imovirtual-storia-properties-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapyx-imovirtual-storia-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",
        "properties": {
          "market": {
            "title": "Market",
            "enum": [
              "pt",
              "ro"
            ],
            "type": "string",
            "description": "Which portal to scrape. Both run the same platform, so every option returns the same fields — only the language of the listings differs.",
            "default": "pt"
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "One location **slug** per entry, each producing its own SEARCH_SUMMARY row.\n\nPortugal: `lisboa`, `porto`, `braga`, `faro`, `setubal`, `coimbra`. Romania: `bucuresti`, `cluj`, `timisoara`, `brasov`, `iasi`, `constanta`.\n\nSlugs may be several segments deep for districts and parishes — copy the tail of any search URL on the site itself. **Leave empty to scrape the whole country** (`todo-o-pais` / `toata-romania`).\n\nA location the portal does not recognise is answered with a clean 404 and reported as an ERROR row, so a typo can never silently return the wrong area.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "transaction": {
            "title": "Transaction",
            "type": "string",
            "description": "Portugal: `comprar` (buy) or `arrendar` (rent). Romania: `vanzare` (buy) or `inchiriere` (rent).\n\nLeave empty to use the market's default (buy). Validated before the run — an unrecognised value is refused rather than sent.",
            "default": ""
          },
          "propertyType": {
            "title": "Property type",
            "type": "string",
            "description": "Portugal: `apartamento`, `moradia`, `terreno`, `imoveis-comerciais`, `escritorio`, `armazens`, `garagem`, `quarto`. Romania: `apartament`, `garsoniere`, `casa`, `teren`, `spatiu-comercial`, `birou`, `depozite-hale`, `camera`.\n\nLeave empty for the market's default (apartments).\n\n**This is the one input the portal is dangerous about.** An unrecognised property type is *not* rejected — it returns HTTP 200 with every listing in the country **and silently discards your location too**. Values are therefore checked against the list above before the run, and the resolved URL is re-checked afterwards; if upstream ever widens the search anyway, the run stops and reports `searchApplied: false` instead of returning the wrong rows.",
            "default": ""
          },
          "rooms": {
            "title": "Number of rooms",
            "type": "array",
            "description": "Match any of the selected room counts. Leave empty for any.\n\nVerified real: 3 rooms narrowed Lisbon apartments from 16,418 to 6,036 and Bucharest apartments from 22,750 to 6,986.",
            "items": {
              "type": "string",
              "enum": [
                "ONE",
                "TWO",
                "THREE",
                "FOUR",
                "FIVE",
                "SIX",
                "SEVEN",
                "EIGHT",
                "NINE",
                "TEN",
                "MORE"
              ],
              "enumTitles": [
                "1 room",
                "2 rooms",
                "3 rooms",
                "4 rooms",
                "5 rooms",
                "6 rooms",
                "7 rooms",
                "8 rooms",
                "9 rooms",
                "10 rooms",
                "More than 10"
              ]
            },
            "default": []
          },
          "minPrice": {
            "title": "Minimum price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Verified real: `300000` narrowed Lisbon apartments from 16,418 to 14,205. Leave at 0 to skip.",
            "default": 0
          },
          "maxPrice": {
            "title": "Maximum price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Leave at 0 to skip.",
            "default": 0
          },
          "minArea": {
            "title": "Minimum area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Verified real: `100` narrowed Lisbon apartments from 16,418 to 8,476. Leave at 0 to skip.",
            "default": 0
          },
          "maxArea": {
            "title": "Maximum area (m²)",
            "minimum": 0,
            "type": "integer",
            "description": "Leave at 0 to skip.",
            "default": 0
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "",
              "LATEST",
              "PRICE",
              "AREA",
              "PRICE_PER_METER"
            ],
            "type": "string",
            "description": "Proven by checking that results genuinely reorder, not merely that the request succeeded — an unrecognised sort is silently ignored by this platform.\n\nNote: `Newest first` reorders Portugal but is a no-op on Romania, whose default ordering is already newest-first.",
            "default": ""
          },
          "sortDirection": {
            "title": "Sort direction",
            "enum": [
              "",
              "ASC",
              "DESC"
            ],
            "type": "string",
            "description": "Only meaningful together with a sort field.",
            "default": ""
          },
          "pageSize": {
            "title": "Listings per request",
            "enum": [
              "24",
              "36",
              "48",
              "72"
            ],
            "type": "string",
            "description": "Only these four are honoured. Anything else (100, 200) is silently ignored and falls back to 36, so the list is closed. 72 halves the number of requests versus the default.\n\n(Carried as a string because the platform does not allow a dropdown on an integer field; the value is a plain number of listings either way.)",
            "default": "72"
          },
          "includePropertyDetails": {
            "title": "Fetch full listing details",
            "type": "boolean",
            "description": "Fetch each listing's own page for the ~50 fields the results list does not carry: the full description, characteristics (price per m², build year, energy certificate), the complete feature list, advertiser contact details including phone numbers, breadcrumbs and floor plans.\n\nCosts **one extra request per listing**. De-listed ads return 404 — those rows are still emitted, with `detailFetched: false`.",
            "default": false
          },
          "maxItems": {
            "title": "Max listings per location",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many listings per location. Set to 0 for everything the portal will serve — there is no artificial ceiling here, so a whole-country query can run to hundreds of pages.",
            "default": 100
          },
          "maxConcurrency": {
            "title": "Max concurrent requests",
            "minimum": 1,
            "maximum": 12,
            "type": "integer",
            "description": "Upper bound on requests in flight at once, across all locations and detail fetches.",
            "default": 4
          },
          "minRequestInterval": {
            "title": "Minimum seconds between requests",
            "minimum": 0,
            "maximum": 30,
            "type": "integer",
            "description": "Paces how often requests START, without tying up a concurrency slot. No rate limiting was observed, so this defaults to 0; raise it for long unattended crawls.",
            "default": 0
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Residential by default. No bot challenge appeared on any of the 7 TLS fingerprints tested across both markets, but datacentre egress from a cloud platform is fingerprinted differently from a local test — an earlier actor in this portfolio lost every request that way.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}