{
  "openapi": "3.0.1",
  "info": {
    "title": "LoopNet US + UK + Realla [$1.5💰] Commercial Property Scraper",
    "description": "💰 $1.50 per 1,000 results, scrape commercial property from LoopNet (US) AND LoopNet UK / Realla (UK) in one actor — the only Apify scraper bundling both. Lease & sale listings across all US states + every UK city. Rich rows: address, geo, sqft, asking rent/price, broker, EPC. $1.50/1k.",
    "version": "0.0",
    "x-build-id": "zZEC76HfJpcwNCHMl"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~loopnet-scraper-ppe/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-loopnet-scraper-ppe",
        "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/memo23~loopnet-scraper-ppe/runs": {
      "post": {
        "operationId": "runs-sync-memo23-loopnet-scraper-ppe",
        "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/memo23~loopnet-scraper-ppe/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-loopnet-scraper-ppe",
        "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": {
          "startUrls": {
            "title": "Start URLs (US, UK, Realla — all in one actor)",
            "type": "array",
            "description": "Mix any combination of: (a) US listing URLs (`/search/.../usa/for-sale/`), (b) US Listing detail URLs (`/Listing/{slug}/{id}/`), (c) US property records (`/property/{slug}/{parcel-id}/`), (d) businesses-for-sale, (e) US broker directory pages, (f) **UK listing URLs** (`/search/commercial-property/{city}--united-kingdom/...`), (g) UK detail listing URLs, (h) UK sub-category URLs (office / retail / industrial / land / coworking). `realla.co.uk` and `loopnet.co.uk` paths point at the same CoStar dataset since the 2018 Realla acquisition; use the loopnet.com URLs (where the listing JSON actually lives) for best results.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "addresses": {
            "title": "Addresses to search",
            "type": "array",
            "description": "Addresses to scrape - should be in format 123 Main St, City, State",
            "items": {
              "type": "string"
            }
          },
          "dbState": {
            "title": "State (2-letter code)",
            "type": "string",
            "description": "US state code, e.g. \"CA\", \"TX\", \"NY\". Setting this alone is enough to activate Instant Database mode."
          },
          "dbCity": {
            "title": "City (optional)",
            "type": "string",
            "description": "Narrow to a city (case-insensitive substring). Leave empty to return the whole state."
          },
          "dbCompany": {
            "title": "Company contains (optional)",
            "type": "string",
            "description": "Only return brokers whose company/brokerage name contains this text (case-insensitive), e.g. \"CBRE\" or \"Cushman\"."
          },
          "dbHasPhone": {
            "title": "Only brokers with a phone",
            "type": "boolean",
            "description": "Return only brokers that have a phone number on file.",
            "default": false
          },
          "instantDatabase": {
            "title": "Use Instant Database (no scraping)",
            "type": "boolean",
            "description": "Serve results from the pre-collected broker database instead of live-scraping. Auto-enabled when you set a State above.",
            "default": false
          },
          "searchQuery": {
            "title": "Free-text search query",
            "type": "string",
            "description": "Free-text search, e.g. 'office space Canary Wharf London' or 'retail space Austin Texas'. The actor infers the property type and location, then searches LoopNet. Use this when you don't have a specific LoopNet search URL or address."
          },
          "searchType": {
            "title": "Transaction type (Filter mode)",
            "enum": [
              "for-sale",
              "for-lease",
              "auctions"
            ],
            "type": "string",
            "description": "For-sale vs for-lease when running in Filter mode — i.e. searching by location / property type / free-text query WITHOUT a Start URL. Leave empty when you pass a Start URL: the transaction type is then taken from the URL's /for-lease/ or /for-sale/ segment and this field is ignored."
          },
          "moreResults": {
            "title": "Scrape all possible results (bypass limit of 500 items/listings)",
            "type": "boolean",
            "description": "Enable this option to retrieve the maximum number of results possible. Note that LoopNet limits results to 500 per search.",
            "default": false
          },
          "includeListingDetails": {
            "title": "Include listing details as well",
            "type": "boolean",
            "description": "Set to true if you want to include listing details of each search result. Visits each listing's detail page and adds full description, photos, lease terms, broker contact, EPC rating (UK) and property/parcel records (US). Slower, same pricing. Default false.",
            "default": false
          },
          "includePortfolioProperties": {
            "title": "Include individual properties from portfolio listings",
            "type": "boolean",
            "description": "When a LoopNet listing is a portfolio (multiple properties bundled under one URL), enable this to scrape each individual property as its own dataset record. Each child carries isPortfolioMember, parentPortfolioUrl, and parentPortfolioId.",
            "default": false
          },
          "maxItems": {
            "title": "Max Listings/Items per start URL",
            "type": "integer",
            "description": "Maximum listings or items collected per start URL (each entry in startUrls). With multiple URLs, the run can produce up to this many items per URL (for example, 10 × 3 URLs → up to 30 total). If not defined, all items will be scraped.",
            "default": 10000
          },
          "maxConcurrency": {
            "title": "Max Concurrency",
            "type": "integer",
            "description": "Maximum number of pages that can be processed at the same time. Values below 20 are raised to 20 at runtime.",
            "default": 20
          },
          "minConcurrency": {
            "title": "Min Concurrency",
            "type": "integer",
            "description": "Minimum number of pages that will be processed at the same time.",
            "default": 1
          },
          "maxRequestRetries": {
            "title": "Max Request Retries",
            "type": "integer",
            "description": "Number of times the crawler will retry a failed request before giving up. Default 8 — gives Akamai-blocked sessions enough chances to retire and get a fresh residential IP from the proxy gateway, without burning cost on truly broken requests (100 was the old default and was wasteful).",
            "default": 8
          },
          "PriceMin": {
            "title": "Min Price",
            "type": "integer",
            "description": "Minimum price to scrape."
          },
          "PriceMax": {
            "title": "Max Price",
            "type": "integer",
            "description": "Maximum price to scrape."
          },
          "BuildingSizeRangeMin": {
            "title": "Min Building Size",
            "type": "integer",
            "description": "Minimum building size to scrape."
          },
          "BuildingSizeRangeMax": {
            "title": "Max Building Size",
            "type": "integer",
            "description": "Maximum building size to scrape."
          },
          "PriceRangeRateType": {
            "title": "Price Range Rate Type",
            "enum": [
              "none",
              "Total",
              "BuildingSquareFootage",
              "LotAcreage",
              "Units"
            ],
            "type": "string",
            "description": "Price range rate type to scrape."
          },
          "CondosFilter": {
            "title": "Condos Filter",
            "enum": [
              "0",
              "1",
              "2"
            ],
            "type": "string",
            "description": "Condos filter to scrape.",
            "default": "0"
          },
          "DateIndicator": {
            "title": "Date Entered",
            "enum": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7"
            ],
            "type": "string",
            "description": "Date entered to scrape.",
            "default": "0"
          },
          "listedInLastDays": {
            "title": "Listed in last N days",
            "minimum": 0,
            "type": "integer",
            "description": "Only return listings listed or updated within the last N days (e.g. 2 = last 2 days). 0 or empty = all dates. This is the clear way to filter by recency and takes precedence over the legacy 'Date Entered' (DateIndicator) select. Combine freely with property type, location, and price filters."
          },
          "State": {
            "title": "State",
            "enum": [
              "none",
              "Al",
              "Ak",
              "Az",
              "Ar",
              "Ca",
              "Co",
              "Ct",
              "De",
              "Fl",
              "Ga",
              "Hi",
              "Id",
              "Il",
              "In",
              "Ia",
              "Ks",
              "Ky",
              "La",
              "Me",
              "Md",
              "Ma",
              "Mi",
              "Mn",
              "Ms",
              "Mo",
              "Mt",
              "Ne",
              "Nv",
              "Nh",
              "Nj",
              "Nm",
              "Ny",
              "Nc",
              "Nd",
              "Oh",
              "Ok",
              "Or",
              "Pa",
              "Ri",
              "Sc",
              "Sd",
              "Tn",
              "Tx",
              "Ut",
              "Vt",
              "Va",
              "Wa",
              "Wv",
              "Wi",
              "Wy"
            ],
            "type": "string",
            "description": "Select your state",
            "default": "none"
          },
          "City": {
            "title": "City",
            "type": "string",
            "description": "Enter City to scrape."
          },
          "firebaseAppCheckToken": {
            "title": "Firebase App Check token (advanced)",
            "type": "string",
            "description": "LoopNet's mobile API now requires a Firebase App Check token (X-Firebase-AppCheck). It is issued by the iOS app via Apple App Attest and EXPIRES ~60 minutes after capture, so it must be supplied fresh. Leave blank if your account auto-refreshes it into the shared 'loopnet-appcheck' key-value store. Without a valid token the source API returns 403."
          },
          "maxUnblockerRequests": {
            "title": "Max unblocker requests (cost cap)",
            "minimum": 0,
            "type": "integer",
            "description": "When the mobile API is blocked (no/expired App Check token), the actor falls back to scraping the website via a paid unblocker. This caps how many such requests one run may make, so a token outage can't run up a surprise bill. Default 60."
          },
          "freeBrowserSearch": {
            "title": "Search resilience (internal)",
            "type": "boolean",
            "description": "Internal fallback for the search step; off by default. Not user-configurable.",
            "default": false
          },
          "monitoringMode": {
            "title": "Run in monitoring mode where only newly listings compared to previous runs will be scraped",
            "type": "boolean",
            "description": "Enable this option to retrieve the maximum number of results possible. Note that LoopNet limits results to 500 per search. (Note: this toggle enables monitoring mode — only listings that are new compared to previous runs are scraped and pushed to the dataset. Default false.)",
            "default": false
          },
          "enablePriceMonitoring": {
            "title": "Enable price monitoring",
            "type": "boolean",
            "description": "If checked, it will only scrape newly listings compared to what has been scraped in previous runs. (Note: this toggle enables price monitoring — price changes of listings are tracked against prior runs. Default false.)",
            "default": false
          },
          "transactionTrackingMode": {
            "title": "Track listings that have closed since the last run",
            "type": "boolean",
            "description": "When enabled, the dataset emits ONLY the closed listings (not the full inventory). Each output item includes the original listing details plus closeStatus (removed / pending / under_contract / sold / leased), closeDetectedAt, firstSeenAt, lastSeenAt, and previousPrice. The snapshot is auto-keyed by a hash of the input (search URLs / filters), so the same scheduled input always finds its prior snapshot.",
            "default": false
          },
          "downloadImages": {
            "title": "Download images (Images will be stored inside Key-Value Store)",
            "type": "boolean",
            "description": "Set to true if you want to download images to Apify's Key-Value Store so you can download them to your computer",
            "default": false
          },
          "maxImages": {
            "title": "Max images per listing (Only applicable if 'Download images' is enabled)",
            "type": "integer",
            "description": "Maximum number of images to download per listing.",
            "default": 10
          },
          "storeName": {
            "title": "Name your storage for images where to store them (this is optional)",
            "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
            "type": "string",
            "description": "Rule for naming: it can only contain letters 'a' through 'z', the digits '0' through '9', and the hyphen ('-') but only in the middle of the string (e.g. 'my-value-1')\n Assign a custom name to the Key-Value Store where your scraped listings will be saved. This ensures:\n 1. **Persistent Storage**: Enables long-term retention of listings, beyond default storage limits.\n 3. **Project Management**: Separate datasets by using unique names for different projects or analyses.\n 4. **Data Reuse**: Easily reference and reuse stored data without overwriting.\n (If left blank, the default storage will be used with standard retention limits.)"
          },
          "cookies": {
            "title": "Cookies",
            "type": "array",
            "description": "<p>Cookie used to authorize actor with crexi.com. Install <a rel=\"noopener noreferrer nofollow\" target=\"_blank\" href=\"https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg\" previewlistener=\"true\">EditThisCookie</a> chrome extension. Login to your crexi.com account. Click on the extension and export the crexi.com cookies. Insert the contents here</p><p>(Note: for this actor, export the cookies from loopnet.com — the crexi.com mentions above are a legacy leftover. Optional; most runs need no cookies.)</p>"
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Specifies proxy servers that will be used by the scraper in order to hide its origin.<br><br>For details, see <a href='https://apify.com/apify/web-scraper#proxy-configuration' target='_blank' rel='noopener'>Proxy configuration</a> in README.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}