# ForSaleByOwner.com Scraper — FSBO Listings (`memo23/forsalebyowner-scraper`) Actor

Scrape for-sale-by-owner US homes from ForSaleByOwner.com: address, price, beds/baths, sqft, GPS, photos, owner-financing flag & status. Search by state or city.

- **URL**: https://apify.com/memo23/forsalebyowner-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.90 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## ForSaleByOwner.com Scraper — FSBO Listings

Pull for-sale-by-owner homes from [ForSaleByOwner.com](https://www.forsalebyowner.com). Search by state or city and get one clean row per listing — address, asking price, beds, baths, square footage, GPS coordinates, photos, an owner-financing flag, and status. Owner-posted listings, not agent feeds.

![How the ForSaleByOwner.com Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-forsalebyowner.png)

### Why use this scraper

- **Owner listings.** ForSaleByOwner.com is a for-sale-by-owner marketplace — the inventory agents' feeds skip.
- **Structured rows.** Address (street/city/county/state/zip), price, beds/baths, square footage, year built, coordinates, photos and an owner-financing flag arrive parsed and typed.
- **Owner phone extracted, not just implied.** Sellers frequently paste a phone number in the description; the actor pulls it into an `ownerPhone` field. Competitors on this same feed ship an empty phone column — this one is filled when a number is present.
- **Motivated-seller scoring.** Every row gets a `motivationScore` (0–100) with a `motivationReasons` list, derived from price drops, owner financing, short sale, lease-to-own, days on market and an owner phone in the listing. Filter with `minMotivationScore`, `onlyPriceReduced` or `minDaysOnMarket`.
- **Daily fresh-listing feed.** Monitoring mode returns only listings not seen on earlier runs.
- **Handles the US geo-block for you.** The site is US-only behind a WAF; the actor runs on US residential with automatic IP rotation and retries.

### What it does

You point the actor at states, city slugs, or ForSaleByOwner search URLs; it queries the site's listing API, pages through the full result set, and delivers clean JSON or CSV — one record per listing.

### Supported inputs

- **US states** — one or more two-letter codes (`TX`, `FL`), or leave empty for every state.
- **City location slugs** — `city-state` form, e.g. `houston-texas`, `miami-florida`.
- **ForSaleByOwner search URLs** — e.g. `https://www.forsalebyowner.com/search/list/houston-texas/fsbo-source/for_sale-status`.
- **Source / status** — owner-only (default) or all sources; for-sale, for-rent, sold or pending.

### Use cases

- **Investors & wholesalers** sourcing agent-free, often motivated sellers (owner-financing listings are flagged).
- **Buyer's agents** finding FSBO inventory to represent buyers on.
- **Market analysts** tracking owner-listing supply and pricing by market.
- **Lead tools & CRMs** topping up a territory with fresh FSBO records on a schedule.

### How it works

1. You provide states, city slugs, or search URLs, plus source/status.
2. The actor resolves each location and POSTs to ForSaleByOwner's search API through a US residential IP, retrying on a fresh IP if the WAF blocks one.
3. It pages through the whole result set.
4. Each listing is mapped to a clean row (coordinates, absolute photo URLs, owner-financing flag).
5. With monitoring mode on, listings delivered before are skipped.
6. Results stream to the dataset as JSON, CSV, Excel or API.

### Input configuration

| Field | Type | Description |
|---|---|---|
| `states` | array | Two-letter US state codes. Empty = every state. |
| `locationSlugs` | array | City slugs in `city-state` form. |
| `startUrls` | array | ForSaleByOwner search URLs (override the fields above). |
| `source` | string | `fsbo` (owner only, default) or `all`. |
| `status` | string | `for_sale` (default), `for_rent`, `sold`, `pending`. |
| `monitoringMode` | boolean | Return only listings not seen on previous runs. |
| `maxItems` | integer | Hard cap on delivered listings. |
| `proxy` | object | Defaults to Apify US residential. |

#### Example input

```json
{
  "states": ["TX", "FL"],
  "source": "fsbo",
  "status": "for_sale",
  "maxItems": 1000
}
```

### Output overview

One row per listing. Prices are in US dollars, coordinates are split into `latitude`/`longitude`, photo URLs are absolute, and `ownerFinancing` flags sellers open to financing.

#### Output sample

```json
{
  "listingId": "6aa3350dfc2bee7de504f075",
  "listingUrl": "https://www.forsalebyowner.com/listing/1301-REAR-Bellaire-Street-Amarillo-TX-79106/6aa3350dfc2bee7de504f075",
  "street": "1301 REAR Bellaire Street",
  "city": "Amarillo",
  "county": "Potter",
  "state": "TX",
  "zip": "79106",
  "propertyType": "House",
  "bedrooms": 1,
  "bathrooms": 1,
  "livingAreaSqft": 13047,
  "yearBuilt": 1946,
  "listPrice": 108800,
  "latitude": 35.201901,
  "longitude": -101.8887064,
  "status": "Active",
  "source": "For Sale By Owner",
  "forSaleByOwner": true,
  "ownerFinancing": true,
  "willWorkWithBuyersAgent": "buyer_agent_and_commission",
  "photoCount": 7,
  "listingSource": "ForSaleByOwner.com",
  "scrapedAt": "2026-09-11T15:05:31.551Z"
}
```

### Key output fields

| Field | Description |
|---|---|
| `listingId` | ForSaleByOwner.com internal ID. |
| `listingUrl` | Browsable listing URL. |
| `street`, `city`, `county`, `state`, `zip` | Full property address. |
| `propertyType` | House, Condo, Land, etc. |
| `bedrooms`, `bathrooms`, `livingAreaSqft`, `yearBuilt` | Core property facts. |
| `listPrice` | Asking price in US dollars. |
| `latitude`, `longitude` | Property coordinates. |
| `status`, `source` | Listing status and source. |
| `forSaleByOwner` | True when the source is an owner. |
| `ownerFinancing`, `shortSale`, `leaseToOwn` | Seller-flexibility / distress flags. |
| `ownerPhone`, `ownerPhones`, `ownerEmails` | Owner contact pulled from the description text (present when the owner included it). |
| `daysOnMarket` | Whole days since the listing date. |
| `motivationScore`, `motivationReasons` | Seller-motivation score 0–100 and the signals behind it. |
| `description` | Property description — often contains the owner's phone number. |
| `primaryPhotoUrl`, `photoUrls`, `photoCount` | Listing photos. |

### FAQ

**Is there an owner phone number?**
There is no dedicated structured contact field, but sellers frequently include a phone number in the listing `description`, so many rows carry direct contact.

**Why does it need a US proxy?**
ForSaleByOwner.com serves listings only to US visitors. The actor routes through its own US residential proxy (fresh IP + retry per request) by default, so you don't configure anything. To use your own US residential proxy instead, set the `proxy` input.

**Owner listings only?**
Yes with `source: fsbo` (the default). Set `source: all` to include the agent/MLS listings the site also aggregates.

**Can I get only new listings each day?**
Yes — enable monitoring mode and schedule the actor.

### Support

Found a bug or need an extra field? Open an issue on the actor's Issues tab in Apify Console.

### Additional services

Need bigger US for-sale-by-owner volume? The companion **FSBO.com Scraper** (same owner-listing niche, tens of thousands of listings) pairs well with this one. Ask via the contact on the profile.

### Explore more scrapers

Part of a large real-estate scraping suite covering FSBO.com, Zillow, Redfin, Realtor.com, Trulia, LoopNet, Crexi, Land.com and more.

### 🤖 For AI agents & LLM apps

Inputs and outputs are plain JSON with documented field names, so an LLM agent can ask for "for-sale-by-owner homes in Texas with owner financing" and get structured rows — address, price, beds/baths, coordinates, owner-financing flag and listing URL — no HTML parsing.

### ⚠️ Disclaimer

This scraper collects only publicly available listing information from ForSaleByOwner.com. Use the data in line with ForSaleByOwner.com's terms of service and all applicable laws, including real-estate marketing, data-protection and anti-solicitation rules in your jurisdiction. You are responsible for how you use the output.

### SEO keywords

ForSaleByOwner scraper, ForSaleByOwner.com scraper, for sale by owner listings, FSBO scraper, FSBO leads, owner listings, US real estate scraper, owner financing homes, motivated seller leads, real estate investor leads, off-market properties, property data API, homes for sale by owner, real estate lead generation.

# Actor input Schema

## `states` (type: `array`):

Two-letter US state codes to scrape, one per line — e.g. `FL`, `TX`, `CA`. Leave everything empty to scrape every state.

## `locationSlugs` (type: `array`):

City-level search slugs, one per line — e.g. `houston-texas`, `miami-florida`. Format is `city-state` (lowercase, hyphenated).

## `startUrls` (type: `array`):

Optional. Paste ForSaleByOwner search URLs, one per line — e.g. `https://www.forsalebyowner.com/search/list/houston-texas/fsbo-source/for_sale-status`. When set, these take precedence over the fields above.

## `source` (type: `string`):

`fsbo` returns for-sale-by-owner listings only (default). `all` also includes agent/MLS-sourced listings the site aggregates.

## `status` (type: `string`):

Which listing status to return.

## `propertyTypes` (type: `array`):

Restrict to these property types, one per line (e.g. `House`, `Condo`, `Townhouse`, `Multi-Family`, `Land`). Empty = all.

## `minBeds` (type: `integer`):

Only listings with at least this many bedrooms.

## `maxBeds` (type: `integer`):

Only listings with at most this many bedrooms.

## `minBaths` (type: `integer`):

Only listings with at least this many bathrooms.

## `maxBaths` (type: `integer`):

Only listings with at most this many bathrooms.

## `minPrice` (type: `integer`):

Only listings priced at or above this amount.

## `maxPrice` (type: `integer`):

Only listings priced at or below this amount.

## `onlyPriceReduced` (type: `boolean`):

Return only listings flagged as price-reduced — a common motivated-seller signal.

## `minDaysOnMarket` (type: `integer`):

Only listings that have been on the market at least this many days (staleness / motivation signal).

## `minMotivationScore` (type: `integer`):

Only listings whose computed seller-motivation score is at least this. The score rewards price drops, owner financing, short sale, lease-to-own, days on market and an owner phone in the listing.

## `monitoringMode` (type: `boolean`):

Remember the listing IDs delivered on previous runs (per user) and return only listings not seen before. Ideal for a daily fresh-FSBO feed.

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

Hard cap on the number of listings delivered across all searches.

## `proxy` (type: `object`):

Optional. ForSaleByOwner.com requires a US residential exit; the actor uses its own US residential proxy by default. Set this only to route through your own US residential proxy instead.

## Actor input object example

```json
{
  "states": [
    "TX",
    "FL"
  ],
  "source": "fsbo",
  "status": "for_sale",
  "onlyPriceReduced": false,
  "monitoringMode": false,
  "maxItems": 1000
}
```

# Actor output Schema

## `results` (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 = {
    "states": [
        "TX"
    ],
    "maxItems": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/forsalebyowner-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 = {
    "states": ["TX"],
    "maxItems": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/forsalebyowner-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 '{
  "states": [
    "TX"
  ],
  "maxItems": 1000
}' |
apify call memo23/forsalebyowner-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/forsalebyowner-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/YhBzi0Buc2MdlT0Tp/builds/MQjBDPknyhhTfEkM0/openapi.json
