# LoopNet Cap Rate Lens — NOI, Yield & Cash Flow (`sian.agency/commercial-investor-lens`) Actor

LoopNet cap rate calculator for commercial investors. Pulls asking price, NOI and listed cap rate, then prints yield, DSCR and cash-on-cash under your down payment, rate and expense assumptions. Local ZHVI and the live 30-year conforming rate sit next to the math so nothing is a black box.

- **URL**: https://apify.com/sian.agency/commercial-investor-lens.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Agents, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $28.00 / 1,000 analyzed 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## LoopNet Cap Rate Lens — NOI, Yield & Cash Flow

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Sibling 1](https://img.shields.io/badge/Store-LoopNet%20Property%20Scraper-1AE392)](https://apify.com/sian.agency/loopnet-property-scraper?fpr=sian) [![Sibling 2](https://img.shields.io/badge/Store-Zillow%20Market%20Data-1F4E79)](https://apify.com/sian.agency/zillow-market-analytics-scraper?fpr=sian) [![Sibling 3](https://img.shields.io/badge/Store-Zillow%20Property%20Detail-1F4E79)](https://apify.com/sian.agency/zillow-property-detail-scraper?fpr=sian)

#### Printed cap-rate math for one LoopNet listing

##### Built for commercial buyers who refuse a black-box score

### What is the LoopNet Cap Rate Lens — and when should you use it?

The **LoopNet Cap Rate Lens** turns a LoopNet for-sale listing into a row you can defend in a memo. It reads asking price, listed NOI and listed cap rate. Then it prints yield, DSCR and cash-on-cash under the down payment and rate you set.

**Use it when you need:** cap rate, NOI, gross yield, cash-on-cash, DSCR, and the exact inputs behind each number.

**Use something else when:** you want a raw LoopNet search feed, broker phones or traffic counts. Use [LoopNet Property Scraper](https://apify.com/sian.agency/loopnet-property-scraper?fpr=sian) for inventory, not underwriting.

### Use with AI agents

Already connected to the [Apify MCP server](https://apify.com/mcp)? Ask for this Actor by name: sian.agency/commercial-investor-lens

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want a printed cap-rate report for a US commercial listing using the Apify Actor `sian.agency/commercial-investor-lens`.

Use it when I need: asking price, listed NOI, cap rate, gross yield, cash-on-cash and DSCR.

Don't use it when: I only want a LoopNet search feed — use LoopNet Property Scraper instead.

How to call it: paste a LoopNet listing URL. Optionally set downPaymentPct, rateOverride and expenseRatio.

Start with this input:
{
  "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
  "downPaymentPct": 25,
  "expenseRatio": 0.35
}

Ask me for the listing URL and my down payment, then run the Actor and summarise cap rate, cash flow and cash-on-cash as a table.
```

**Things you can ask your agent for:**

- Underwrite this Dallas NNN listing at 25% down and today's 30-year rate
- Compare two LoopNet URLs on cash-on-cash under the same assumptions
- Show the formula block so I can paste it into an IC memo

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/commercial-investor-lens.md](https://apify.com/sian.agency/commercial-investor-lens.md).

***

### Overview

Paste a LoopNet URL. Get the same spreadsheet a buyer would build by hand.

**Why teams use it:**

- ✅ **Listed NOI first**: if the listing prints NOI, that number is the NOI. We do not overwrite it.
- ⚡ **One run, three cases**: base, conservative and aggressive sit on the same row.
- 🎯 **Cap rate you can audit**: NOI / price, with both inputs on the row.
- 💰 **Pay per listing**: you are charged for analyzed listings, not for empty errors.
- 💎 **Rate source named**: override, live 30-year conforming, or the documented fallback.
- ✨ **Residential context, labeled**: city ZHVI sits next to the CRE math and is never treated as an appraisal.

***

### Features

- 📊 **Cap rate calculator**: NOI divided by asking price. The formula is on the row.
- 📒 **NOI source tag**: `listing_noi` or `implied_from_listed_cap_rate`.
- 📈 **Gross yield**: listed NOI grossed up by your expense ratio.
- 💸 **Cash-on-cash**: annual cash flow / down payment.
- 🏦 **DSCR**: NOI / annual debt service.
- 🏠 **Market tape**: typical home value and days-to-pending for the listing city.
- 📋 **Copy-ready formula block**: in the HTML report, ready for a memo.
- 🚀 **Bulk URLs**: unique LoopNet links, same assumptions on every row.

***

### Quick Start

Open the actor. Keep the sample Dallas URL. Hit Start. Open the dataset and the HTML report.

```bash
curl -X POST https://api.apify.com/v2/acts/sian.agency~commercial-investor-lens/runs?token=[YOUR_TOKEN] \
-d '{"loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/"}'
```

***

### Getting Started (3 Simple Steps)

#### Step 1: Paste a LoopNet listing

Copy a for-sale URL from LoopNet.

#### Step 2: Set the capital stack

Down payment, optional rate override, expense ratio.

#### Step 3: Run and open the report

The hero shows cap rate, price and yield. The formula block names every input.

**That's it. In about a minute you'll have:**

- Cap rate checked against listed NOI
- Cash-on-cash and DSCR under your loan
- A copy-ready arithmetic block

***

### Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| loopnetUrl | string | No | LoopNet listing URL |
| listingId | string | No | Numeric LoopNet id |
| address | string | No | Used only when no URL is set |
| bulkUrls | array | No | Extra listing URLs |
| downPaymentPct | integer | No | Default 25 |
| rateOverride | number | No | Annual percent. Empty = live 30-year |
| expenseRatio | number | No | Default 0.35 |
| loanYears | integer | No | Default 30 |
| includeMarketContext | boolean | No | Default true |

**Example:**

```json
{
  "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
  "downPaymentPct": 25,
  "expenseRatio": 0.35
}
```

***

### Output

Results land in the dataset. The HTML report is saved as `report.html`.

| Field | Type | Description |
|-------|------|-------------|
| capRatePct | number | NOI / asking price |
| askingPrice | number | Parsed sale price |
| grossYieldPct | number | EGI / asking price |
| annualCashFlow | number | NOI minus debt service |
| cashOnCashPct | number | Cash flow / down payment |
| dscr | number | NOI / debt service |
| listedNOI | number | NOI printed on the listing |
| mortgageRatePct | number | Rate actually used |
| noiSource | string | Where NOI came from |
| listingUrl | string | Source listing |

**Example:**

```json
{
  "listingUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
  "askingPrice": 4400000,
  "listedNOI": 330000,
  "capRatePct": 7.5,
  "grossYieldPct": 11.5385,
  "cashOnCashPct": 6.6505,
  "dscr": 1.2848,
  "mortgageRatePct": 6.75,
  "mortgageRateSource": "live_30yr_conforming",
  "status": "success"
}
```

***

### Use Cases & Examples

#### 1. Underwrite one NNN listing

**A buyer checks whether the printed 7.5% cap is real.**

**Input:** the Dallas drug-store URL, 25% down.
**Output:** NOI $330,000, cap 7.50%, cash-on-cash and DSCR.
**Use:** paste the formula block into the IC memo.

#### 2. Stress the rate

**A CI wants to see +1% on the mortgage.**

**Input:** same URL, leave rate empty, read the conservative case.
**Output:** base vs conservative cash flow on one row.
**Use:** decide if the deal still clears the fund hurdle.

#### 3. Rank a buy-box

**An analyst drops five LoopNet URLs.**

**Input:** bulkUrls plus one expense ratio.
**Output:** one row per listing, same assumptions.
**Use:** sort on cap rate and DSCR in a sheet.

#### 4. Explain the math to a partner

**A broker has to show work, not a score.**

**Input:** one URL.
**Output:** named formulas and every input.
**Use:** forward the HTML report.

#### 5. City tape next to the deal

**A fund wants ZHVI context beside the CRE numbers.**

**Input:** includeMarketContext true.
**Output:** typical home value and days-to-pending for the city.
**Use:** flag a listing whose price is detached from local housing.

***

### Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/commercial-investor-lens').call({
  loopnetUrl: 'https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/commercial-investor-lens').call(
    run_input={'loopnetUrl': 'https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/'}
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~commercial-investor-lens/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/"}'
```

#### Automation workflows

1. **Trigger**: schedule or webhook
2. **HTTP Request**: call the actor
3. **Process**: read JSON rows
4. **Action**: write to a sheet or notify

***

### Performance & Pricing

#### FREE Tier

- **1 listing** per run, full math, same report
- No credit card
- Fine for a first deal

#### PAID Tier

- **Unlimited** listings per run
- Same formulas, no extra delay
- Pay per analyzed listing. Failed lookups are not charged

View current pricing on the [Store page](https://apify.com/sian.agency/commercial-investor-lens?fpr=sian).

***

### Frequently Asked Questions

**Q: How many listings can I process?**
A: FREE: 1 per run. PAID: no per-run cap.

**Q: Does it work on for-lease listings?**
A: Cap-rate math needs a sale price and NOI or a listed cap. Lease-only rows come back with those fields empty.

**Q: What output formats are available?**
A: JSON, CSV, Excel from the dataset, plus the HTML report.

**Q: Where does the mortgage rate come from?**
A: Your override, else the live 30-year conforming snapshot, else 6.75% labeled as a fallback.

**Q: Is this an appraisal?**
A: No. It reprints listing math and your assumptions. It does not value the building.

**Q: How long does a run take?**
A: Usually under a minute for one URL.

***

### Troubleshooting

**Cap rate is empty**

- The listing has no sale price and no listed cap. Try a for-sale URL.

**Address search missed the building**

- Paste the LoopNet URL instead of the street.

**Rate looks stale**

- Set `rateOverride` to the quote your lender gave you.

***

### Is it legal to scrape data?

Our actors do not extract private user data such as email addresses or gender. They only extract what the listing already shows in public. You should still treat results as potentially containing personal data under GDPR and similar laws.

You can also read Apify's post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Trademark Disclaimer

LoopNet is a trademark of CoStar Group, Inc. Zillow is a trademark of Zillow, Inc. This actor is not affiliated with, endorsed by, or sponsored by CoStar or Zillow. All marks belong to their owners.

***

### Support

- Questions: open an issue on the actor or write <apify@sian-agency.online>
- More tools: [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian)

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Changelog

This Actor's version history is a separate document: https://apify.com/sian.agency/commercial-investor-lens/changelog.md

# Actor input Schema

## `loopnetUrl` (type: `string`):

🔗 **ONE LISTING:** Paste a LoopNet for-sale URL. The actor reads asking price, listed NOI and listed cap rate, then prints yield and cash-on-cash.

**How to get it:** open the listing on LoopNet → copy the address bar.

**Supported:** https://www.loopnet.com/Listing/…/12345678/

**TIP:** Use bulk URLs for more than one deal.

## `listingId` (type: `string`):

🆔 **OPTIONAL:** Numeric LoopNet id if you already have it from a search feed. The URL field is enough for most runs.

## `address` (type: `string`):

📍 **OPTIONAL:** US street or city used only when no URL or id is set. The actor searches for-sale listings and takes the first match.

## `bulkUrls` (type: `array`):

🚀 **BULK:** One URL per row. FREE runs keep the first listing. PAID runs keep every unique URL.

Use Bulk edit to paste a list. Duplicates are dropped before any lookup.

## `downPaymentPct` (type: `integer`):

💵 Equity you bring. 25 means 25% down. Used for loan size, cash-on-cash and DSCR.

## `rateOverride` (type: `number`):

📈 Annual rate, for example 6.75. Leave empty to use today's 30-year conforming rate. The source is written on the row.

## `expenseRatio` (type: `number`):

🧾 Share of effective gross income spent on opex, as a decimal. 0.35 means 35%. Used only to gross listed NOI up to a yield. Listed NOI is never overwritten.

## `loanYears` (type: `integer`):

📅 Amortization used for debt service. Default 30.

## `includeMarketContext` (type: `boolean`):

✅ Pulls the listing city's typical home value and today's 30-year conforming rate. Residential ZHVI is context, not a CRE appraisal.

## Actor input object example

```json
{
  "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
  "address": "11403 E Northwest Hwy, Dallas, TX",
  "downPaymentPct": 25,
  "expenseRatio": 0.35,
  "loanYears": 30,
  "includeMarketContext": true
}
```

# Actor output Schema

## `investorReports` (type: `string`):

One row per listing with inputs, cap rate, yield, cash-on-cash and scenarios

## `scrapingSummary` (type: `string`):

HTML report with hero stats, formula block and scenario table

# 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 = {
    "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
    "downPaymentPct": 25,
    "expenseRatio": 0.35,
    "loanYears": 30,
    "includeMarketContext": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/commercial-investor-lens").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 = {
    "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
    "downPaymentPct": 25,
    "expenseRatio": 0.35,
    "loanYears": 30,
    "includeMarketContext": True,
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/commercial-investor-lens").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 '{
  "loopnetUrl": "https://www.loopnet.com/Listing/11403-E-Northwest-Hwy-Dallas-TX/41581120/",
  "downPaymentPct": 25,
  "expenseRatio": 0.35,
  "loanYears": 30,
  "includeMarketContext": true
}' |
apify call sian.agency/commercial-investor-lens --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/commercial-investor-lens"
        }
    }
}
```

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/YVejmSGlvsUW1MZeo/builds/N9IvY59CCqmFCOrBA/openapi.json
