# LoopNet Scraper – CRE Listings, Brokers & Deal Intel (`trakk/loopnet-commercial-real-estate-scraper`) Actor

Collect LoopNet commercial property searches and full listing details with prices, cap rates, building facts, brokers, photos, transit, traffic and change monitoring. Export analysis-ready US CRE data as JSON, CSV or Excel.

- **URL**: https://apify.com/trakk/loopnet-commercial-real-estate-scraper.md
- **Developed by:** [Kelopr\_bk](https://apify.com/trakk) (community)
- **Categories:**
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 commercial property listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## LoopNet Scraper — CRE Listings, Brokers & Deal Intelligence

Collect commercial real estate listings from LoopNet across the United States. Search markets, enrich known properties, export broker and media data, compare deals, and monitor listing changes from one Actor.

**Property listings** · **Prices & cap rates** · **Building facts** · **Broker contacts** · **Photos & tours** · **Deal calculations** · **Change monitoring**

### What can this Actor do?

| Workflow | Use it for | Result |
|---|---|---|
| `SEARCH` | Fast market research | Listing cards with location, asking terms, property type, available space, brokers, photos, and rank |
| `LISTING_DETAILS` | Enrich known URLs or IDs | Full property description, facts, brokers, media, source flags, and deal calculations |
| `SEARCH_FULL` | Build a complete research dataset | Search discovery followed by full details for every selected listing |
| `MONITOR` | Recurring market tracking | New, updated, unchanged, and safely detected removed listings |

### Popular use cases

- Build commercial property datasets by city, state, property type, or deal type.
- Find offices, retail, industrial, land, multifamily, hospitality, and specialty properties.
- Compare asking prices, lease rates, cap rates, NOI, size, and price per square foot.
- Create broker and brokerage lead lists.
- Download property photos, videos, tours, and brochures when available.
- Track price and status changes across scheduled runs.
- Feed CRE data into spreadsheets, dashboards, CRMs, and AI workflows.

### Quick start

#### Search by location

```json
{
  "mode": "SEARCH",
  "locations": ["Los Angeles, CA"],
  "dealType": "FOR_LEASE",
  "propertyType": "OFFICE",
  "maxItems": 25,
  "maxPages": 1
}
```

#### Use a LoopNet search URL

```json
{
  "mode": "SEARCH_FULL",
  "searchUrls": [
    {
      "url": "https://www.loopnet.com/search/office-space/los-angeles-ca/for-lease/"
    }
  ],
  "maxItems": 10,
  "maxPages": 1
}
```

#### Enrich listings by ID

```json
{
  "mode": "LISTING_DETAILS",
  "listingIds": [
    "31948105"
  ],
  "maxItems": 1
}
```

#### Monitor a market

```json
{
  "mode": "MONITOR",
  "locations": ["Austin, TX"],
  "dealType": "FOR_SALE",
  "propertyType": "INDUSTRIAL",
  "maxItems": 100,
  "maxPages": 5,
  "emitUnchanged": false,
  "emitRemoved": true
}
```

### What data will you receive?

#### Listing identity

`listingId`, `requestedListingId`, `listingIdWasResolved`, `propertyId`, `listingKey`, `lrId`, `listingName`, `listingUrl`, `listingType`, `dealType`, `status`, `exposure`, `dateModified`, `scrapedAt`.

`requestedListingId` and `listingIdWasResolved` make redirects explicit when an older listing ID points to a current listing record.

#### Address and coordinates

`streetAddress`, `city`, `state`, `postalCode`, `county`, `country`, `countryCode`, `cityState`, `latitude`, `longitude`, `locationInterpretation`.

#### Pricing and financials

`price`, `priceText`, `priceCurrency`, `pricePerSqFt`, `capRate`, `noi`, `saleType`, `saleCondition`, `availableSpace`, `buildingInfo`.

#### Property facts

`propertyType`, `propertySubtype`, `propertyTypeId`, `buildingClass`, `buildingSize`, `lotSize`, `spaceCount`, `availableSpacesCount`, `yearBuilt`, `stories`, `tenancy`, `zoning`, `parkingRatio`, `frontage`, `buildingFar`, `walkScore`, `factsJson`, `availableSpacesJson`.

#### Marketing information

`description`, `executiveSummary`, `highlights`, `amenities`, `breadcrumbNames`, `linksJson`.

#### Brokers and companies

`brokerCount`, `brokerNames`, `brokerTitles`, `brokerPhones`, `brokerEmails`, `brokerCompanies`, `brokerProfileUrls`, `brokerProfileIds`, `brokerBios`, `brokerAvatars`, `brokerCompanyLogos`, `brokersJson`, `company`, `provider`.

Contact fields are conditional. If LoopNet does not publish a phone, email, biography, or company value for a listing, it remains empty.

#### Photos, tours, and documents

`coverPhotoUrl`, `imageCount`, `imageUrls`, `imageAlts`, `videoCount`, `videoUrls`, `videoThumbnails`, `matterportTourUrls`, `brochureUrls`, `brochureLabels`, `mediaJson`.

#### Location intelligence

Depending on the listing, output can include walk, transit, bike, and drive scores; nearby transit, rail, and airport information; traffic counts; points of interest; and demographic blocks.

Fields include `walkScore`, `transitScore`, `bikeScore`, `driveScore`, score descriptions, `nearestTransitDistance`, `nearestRailDistance`, `nearestAirportDistance`, `trafficCount`, `maxTrafficVolume`, `nearestTrafficDistance`, `transportationJson`, `trafficCountsJson`, `pointsOfInterestJson`, `demographicsJson`, and `dataPointsJson`.

#### Taxes and listing flags

`parcelNumber`, `landAssessment`, `improvementAssessment`, `totalAssessment`, `isActive`, `isAuction`, `isSaleDataLocked`, `listingAcl`, `ldpAcl`, `ldpExposure`, `ldpGroup`, `ldpPropertyType`, `ldpStatus`, `ldpType`, `flagsJson`, `profileStateJson`.

#### Complete source coverage

Keep `includeRawSource: true` to retain conditional source fields in `rawSourceJson` and the dedicated `*Json` columns. This is useful when different property types publish different fact, media, broker, transportation, or financial structures.

### Deal Intelligence

The Actor adds clear calculations when the required values are available:

- `pricePerBuildingSqFtCalculated` — asking price divided by building size;
- `pricePerLotAcreCalculated` — asking price divided by lot acreage;
- `estimatedNoiFromCapRate` — asking price multiplied by the published cap rate;
- `brokerCount`, `imageCount`, `hasVideo`, `hasMatterport`, `hasBrochure`;
- `listingCompletenessPercent`;
- `dataCoverage` and `missingFieldGroups`.

Calculated values are explicitly named and stay empty when their inputs are unavailable.

### Monitoring output

The first matching monitoring run establishes a snapshot and returns records as `NEW`. Later runs can add:

- `changeStatus`: `NEW`, `UPDATED`, `UNCHANGED`, or `REMOVED`;
- `firstSeenAt`, `lastSeenAt`;
- `previousPrice`, `priceChange`, `priceChangePercent`;
- `previousStatus`, `statusChanged`;
- `closeStatus`, `closeDetectedAt`.

Removed records are emitted only after an exhaustive source scan. Page, result, source, or budget limits prevent removal detection for that run, avoiding false alerts.

### Filters

| Input | Purpose |
|---|---|
| `dealType` | For sale, for lease, or auction searches |
| `propertyType` | Office, retail, industrial, land, multifamily, hospitality, healthcare, and more |
| `minPrice`, `maxPrice` | Filter normalized asking prices |
| `minBuildingSize`, `maxBuildingSize` | Filter building square footage |
| `minCapRate`, `maxCapRate` | Filter published cap rates |
| `maxItems` | Total successfully saved unique records |
| `maxPages` | Maximum pages per search source |

Listings missing a value cannot pass a filter that requires that value. Filtered, duplicate, failed, and unchanged monitoring candidates do not consume `maxItems`.

### Output views

Every run provides focused tables:

| View | Designed for |
|---|---|
| **Listings** | Core property research |
| **Financials** | Prices, cap rates, NOI, and deal ratios |
| **Brokers** | Contacts and brokerage research |
| **Media** | Photos, videos, tours, and brochures |
| **Location intelligence** | Coordinates, access, transport, and traffic |
| **Monitoring** | New, changed, unchanged, and removed listings |
| **Run summary** | Saved counts, warnings, and stop reasons |

### Export and integrations

Download data as JSON, JSONL, CSV, Excel, XML, RSS, or HTML Table. Access results through the Apify API or connect the Actor to Google Sheets, Google Drive, Make, Zapier, Slack, Airbyte, webhooks, CRMs, and your own applications.

Save an input as an Apify task to reuse the same market search or monitoring configuration.

### Performance

The tested Search workflow collected **50 unique US listings in 8.9 seconds on 512 MB**, including two result pages and dataset writes. Full-detail speed depends on the number of selected listings and the amount of media and property data available.

### Cost control

For an inexpensive first run:

1. Select `SEARCH`.
2. Use one location or search URL.
3. Set `maxItems` to 5–10.
4. Inspect the fields you need.
5. Use `LISTING_DETAILS` or `SEARCH_FULL` for the selected properties that need enrichment.

Set Maximum charge per run in Apify Console to create a hard budget ceiling.

### Frequently asked questions

#### Can I paste a complete LoopNet search URL?

Yes. Filters included in a LoopNet `/search/` URL are preserved. Location and dropdown filters are used when the Actor builds the search URL for you.

#### Can I combine URLs and listing IDs?

Yes, in `LISTING_DETAILS`. Repeated listing IDs are deduplicated before collection.

#### Why do some listings contain more fields than others?

Land, office, retail, portfolio, auction, lease, and for-sale listings publish different information. Missing values remain empty, while available source blocks can be retained in the JSON columns.

#### Will filtering reduce the requested result allowance?

No. Filtered and duplicate candidates do not consume `maxItems`.

#### Can monitoring report false removals after a short run?

No. Removal detection requires a complete source scan and is disabled for limited or interrupted runs.

#### Are missing broker contacts estimated?

No. Broker contact values are saved only when they are available for the listing.

#### How do I call the Actor from code?

Open the **API** tab for ready-to-copy Python, JavaScript, CLI, HTTP, OpenAPI, and MCP examples.

### Support

When reporting an issue, include the run ID, mode, sanitized input, and one affected LoopNet URL or listing ID. This makes the problem quick to reproduce.

# Actor input Schema

## `mode` (type: `string`):

Choose fast search cards, full details for known listings, search with full enrichment, or recurring change monitoring.

## `searchUrls` (type: `array`):

SEARCH, SEARCH\_FULL, or MONITOR. Paste one or more LoopNet /search/ URLs; their property and deal filters are preserved.

## `locations` (type: `array`):

SEARCH, SEARCH\_FULL, or MONITOR. One US city/state, state, ZIP, or market phrase per entry.

## `listingUrls` (type: `array`):

LISTING\_DETAILS only. Paste direct LoopNet /Listing/ URLs.

## `listingIds` (type: `array`):

LISTING\_DETAILS only. Add 7–10 digit LoopNet listing IDs as strings.

## `dealType` (type: `string`):

Used for location-built searches. Complete LoopNet search URLs preserve their own deal type.

## `propertyType` (type: `string`):

Used for location-built searches. Complete LoopNet search URLs preserve their own property type.

## `minPrice` (type: `number`):

Keep records at or above this normalized asking price; records without a price cannot pass this filter.

## `maxPrice` (type: `number`):

Keep records at or below this normalized asking price; records without a price cannot pass this filter.

## `minBuildingSize` (type: `number`):

Keep records at or above this normalized building square footage.

## `maxBuildingSize` (type: `number`):

Keep records at or below this normalized building square footage.

## `minCapRate` (type: `number`):

Keep records at or above this source-published capitalization rate.

## `maxCapRate` (type: `number`):

Keep records at or below this source-published capitalization rate.

## `maxItems` (type: `integer`):

Total successfully saved unique records per run. Filtered, duplicate, failed, and unchanged monitoring candidates do not consume the allowance.

## `maxPages` (type: `integer`):

Maximum result pages for each search source.

## `maxConcurrency` (type: `integer`):

Maximum number of property detail requests processed concurrently in SEARCH\_FULL, LISTING\_DETAILS, and MONITOR.

## `emitUnchanged` (type: `boolean`):

MONITOR only. Include records whose tracked price and status did not change.

## `emitRemoved` (type: `boolean`):

MONITOR only. Emit removed records only after an exhaustive, uncapped source scan.

## `includeRawSource` (type: `boolean`):

Keep the lossless JSON-LD, source attributes, and listing state used for field provenance.

## `maxRetries` (type: `integer`):

Additional attempts for temporary source, connection, or rate-limit failures.

## `requestTimeoutSec` (type: `integer`):

Maximum seconds allowed for one source request.

## `proxyConfiguration` (type: `object`):

Connection settings used for source requests.

## Actor input object example

```json
{
  "mode": "SEARCH",
  "searchUrls": [
    {
      "url": "https://www.loopnet.com/search/office-space/los-angeles-ca/for-lease/"
    }
  ],
  "locations": [
    "Los Angeles, CA",
    "Austin, TX"
  ],
  "listingUrls": [
    {
      "url": "https://www.loopnet.com/Listing/1435-River-Ave-Camden-NJ/31948105/"
    }
  ],
  "listingIds": [
    "31948105"
  ],
  "dealType": "FOR_SALE",
  "propertyType": "ALL",
  "maxItems": 25,
  "maxPages": 1,
  "maxConcurrency": 8,
  "emitUnchanged": false,
  "emitRemoved": false,
  "includeRawSource": true,
  "maxRetries": 2,
  "requestTimeoutSec": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

No description

## `financials` (type: `string`):

No description

## `brokers` (type: `string`):

No description

## `media` (type: `string`):

No description

## `locationIntel` (type: `string`):

No description

## `monitoring` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `diagnostics` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "SEARCH",
    "searchUrls": [
        {
            "url": "https://www.loopnet.com/search/office-space/los-angeles-ca/for-lease/"
        }
    ],
    "listingUrls": [
        {
            "url": "https://www.loopnet.com/Listing/1435-River-Ave-Camden-NJ/31948105/"
        }
    ],
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("trakk/loopnet-commercial-real-estate-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "SEARCH",
    "searchUrls": [{ "url": "https://www.loopnet.com/search/office-space/los-angeles-ca/for-lease/" }],
    "listingUrls": [{ "url": "https://www.loopnet.com/Listing/1435-River-Ave-Camden-NJ/31948105/" }],
    "maxItems": 25,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("trakk/loopnet-commercial-real-estate-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "SEARCH",
  "searchUrls": [
    {
      "url": "https://www.loopnet.com/search/office-space/los-angeles-ca/for-lease/"
    }
  ],
  "listingUrls": [
    {
      "url": "https://www.loopnet.com/Listing/1435-River-Ave-Camden-NJ/31948105/"
    }
  ],
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call trakk/loopnet-commercial-real-estate-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,trakk/loopnet-commercial-real-estate-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/weWtOkw3u9djymcQr/builds/5SBXIIamDAdtojDdN/openapi.json
