Propwire Scraper - Property Leads, Owners & Equity Data avatar

Propwire Scraper - Property Leads, Owners & Equity Data

Pricing

from $1.00 / 1,000 property records

Go to Apify Store
Propwire Scraper - Property Leads, Owners & Equity Data

Propwire Scraper - Property Leads, Owners & Equity Data

Scrape Propwire.com: 157M+ US MLS & off-market properties with owner names, mailing addresses, equity, foreclosure and auction details, mortgages, transfers, owner portfolios, tax and full MLS records. Filter by lead type, property type, value, year built, sale date and MLS status.

Pricing

from $1.00 / 1,000 property records

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

4

Total users

3

Monthly active users

4 days ago

Last modified

Categories

Share

Propwire Scraper: Property Leads, Owners & Equity Data

Propwire Scraper turns Propwire into a lead-generation API for US real estate. Look up one address or APN, paste Propwire links, or sweep whole states with lead-type filters (absentee owners, pre-foreclosures, high equity, auctions, tired landlords and more, 41 flags in total). Every record carries the search-card fields (address, value, equity, beds/baths, size, MLS snapshot), and when Full property records is on, also the owner names and mailing address, ownership length, owner portfolio, foreclosure and auction details, mortgage and transfer history, tax assessments, parcel/zoning data and the full MLS record when one exists. Export the dataset to JSON, CSV or Excel, or read it straight through the API.

Why This Scraper?

  • Three ways to find properties. Address or APN lookup, pasted Propwire links (search or property pages), or a state/city/ZIP/county sweep with lead-type filters. No need to build search URLs by hand.
  • 41 built-in lead-type flags. Absentee owners, pre-foreclosures, high/low/negative equity, free and clear, auctions, bank-owned (REOs), vacant homes and lots, out-of-state owners, tired landlords, cash buyers, tax liens, tax dodgers, bankruptcies, divorces, pre-probates, zombie properties and more.
  • Full ownership and financial detail on demand. Owner names and mailing address, ownership length, owner portfolio (properties owned, portfolio value and equity), foreclosure and auction details, current mortgages, mortgage and transfer history, tax assessments and exemptions, parcel/zoning and building specifications.
  • Nothing dropped. The complete source payload for every record rides in raw, plus a stable Propwire link in propwireUrl, so no nested owner, portfolio or MLS object is ever whitelisted away.
  • Built for lead monitoring. Recurring updates returns only new, updated and reappeared records on repeated runs of the same search, and Continue a previous run finishes one interrupted collection without re-billing rows it already returned.
  • Cost and size stay in your control. Max records is the single limit that stops a run, and Max pages per search is a separate runaway guard on any one search walk.
  • A refused run fails loudly instead of returning an empty dataset that looks like a successful scrape.

Use Cases

  • Real estate wholesalers and investors: build daily lead lists of absentee owners, pre-foreclosures and high-equity properties in a target market.
  • Landlord and portfolio outreach: identify tired landlords, cash flow rentals and multi-property owners for acquisition or partnership outreach.
  • Skip tracing and direct mail: pull owner names and mailing addresses for a filtered set of leads.
  • Foreclosure and auction deal sourcing: track pre-foreclosure, auction and bank-owned flags with dates, trustee, lender and notice detail.
  • Market and appraisal research: gather comparable sales, equity and tax-assessment data across a ZIP, city or county.
  • Recurring lead monitoring: schedule the actor to return only the new or changed leads in a market, for daily or weekly outreach.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
recordType"property"
id12345678
propwireUrlPropwire link to the property
address / city / state / zip"100 Main St" / "Anytown" / "FL" / "32000"
propertyType"SFR" (also "CONDO", "LAND", "COMMERCIAL", more)
bedrooms / bathrooms3 / 2
buildingAreaSf / lotSizeSf1650 / 6500
yearBuilt1998
estimatedValue / estimatedEquity / estimatedEquityPercentage344800 / 182400 / 53
lastSoldDate / lastSoldPrice"2021-06-17" / 250000
daysOnMarket42
mlsListPrice / mlsStatus325000 / "ACTIVE"
leadTypes["ABSENTEE_OWNER", "HIGH_EQUITY"]
ownerNames / ownerTypes["SAMPLE JANE"] / ["INDIVIDUAL"] (when enabled)
ownerOccupied / ownershipYearsfalse / 5 (when enabled)
ownerMailingAddress"PO Box 1000, Sample Town, NJ 07000" (when enabled)
portfolioPropertiesOwned / portfolioValue4 / 1240000 (when enabled)
foreclosureActive / auctionDatetrue / "2026-12-02" (when enabled)
apn / zoning"12-34-56-78-90" / "R1" (when enabled)
taxAssessedValue270000 (when enabled)
imageUrl / photoCountcover photo URL / 28
detailFetchedtrue when the full record was read for this row
sourceType"search", "searchUrl", "address" or "url"
changeType / changedFields / firstSeenAt / lastSeenAt"NEW" / ["estimatedValue"] / timestamps (Recurring updates only: the change label, what moved, when first and last seen)
rawthe complete verbatim source payload: full owner, portfolio, foreclosure, mortgage, transfer, tax, parcel and MLS objects

How to Use

  1. Fill in one of the three sections: addresses or APNs, links, or the search filters (states, cities/ZIPs/counties, lead types, property types, value, year built and more). Whichever you fill in wins, in that order.
  2. Leave Full property records on (default) for owner, foreclosure, mortgage and tax detail, or turn it off for search-card fields only.
  3. Set Max records and Max pages per search to control run size and cost, then click Start.
  4. Export the dataset as JSON, CSV or Excel, or read it through the API.

Address lookup (one full record per address):

{
"addresses": ["1600 Example Ave, Orlando, FL 32801"],
"addressMatchMode": "first",
"fetchDetails": true
}

Links mode (a pasted property link, or a search link walked forward):

Note: if you call the API without startUrls at all (the key omitted), the built-in sample property link applies, and links take priority over the search filters. Pass an empty array ("startUrls": []) to run the search filters below instead.

{
"startUrls": [
"https://propwire.com/realestate/100-Sample-St-Anytown-FL/87654321/property-details"
],
"fetchDetails": true
}

Search filters, statewide pre-foreclosure sweep under $500k:

{
"searchStates": ["FL"],
"searchLeadTypes": ["preforeclosure", "high_equity"],
"searchPropertyTypes": ["SFR", "CONDO"],
"searchEstimatedValueMin": 100000,
"searchEstimatedValueMax": 500000,
"fetchDetails": true,
"maxItems": 100
}

Recurring updates, daily lead monitoring, only what changed:

{
"searchStates": ["FL"],
"searchLeadTypes": ["preforeclosure"],
"incrementalMode": true,
"stateKey": "daily-fl-leads",
"maxItems": 0
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/propwire-property-leads-scraper").call(
run_input={"searchStates": ["FL"], "searchLeadTypes": ["preforeclosure"], "maxItems": 50}
)
for record in client.dataset(run["defaultDatasetId"]).iterate_items():
print(record["address"], record["estimatedValue"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/propwire-property-leads-scraper').call({
searchStates: ['FL'],
searchLeadTypes: ['preforeclosure'],
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Record depth and caps

Full property records (fetchDetails, on by default) reads each property's full record and is billed once per property as a separate charge on top of the per-record price; a refused detail read keeps the search-card record and is never charged for that read. Max records is the single limit that stops a run (0 = unlimited). Max pages per search is a separate runaway guard on any one search walk (0 = as deep as the source serves). Propwire itself serves only the first 10,000 rows of any one search, and at most 10 states per search; narrow the states, locations or filters to go deeper. The run log warns when a search hits that limit.

Resume and recurring updates

  • Continue a previous run (resumeFromRunId): paste the run or dataset id of an earlier run of this actor to continue it. Records that run already returned are skipped, so an interrupted large collection can finish without paying for the same rows twice.
  • Recurring updates (incrementalMode): for running the same setup again and again (daily or weekly lead monitoring) over the same scope. Each record is classified NEW, UPDATED (with changedFields: property fields such as value, beds/baths, size, MLS price and status, plus equity, lead flags and owner detail drive updates), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only with emitExpired on, and never after a run that was capped, continued, or lost a source). What never counts as a change: volatile bookkeeping is excluded by default (image URLs, scrapedAt, position, the source fields and the stored raw payload), and ignoreFieldsForChanges names extra top-level fields to exclude, so a value that churns on every fetch in your setup stops re-billing unchanged records. A search larger than Propwire's 10,000-row limit is never read to its end, and properties beyond that limit can then be reported as EXPIRED, so keep each monitored search under 10,000 results before turning on emitExpired. stateKey names or shares one monitoring campaign's memory. With Recurring updates off, output is exactly as before.
  • The Changes tab: with Recurring updates on, the run's output has a second view, changes, showing only the identity columns plus changeType, changedFields, firstSeenAt, lastSeenAt and scrapedAt, so a monitoring campaign reads like a diff. The full record stays on every row and in the default view.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each property, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you have not authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where property pages should be created.

maxNotifyListings caps how many items each connector receives per run (default 50); the dataset keeps everything. The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
addressesarray(none)Street addresses or APNs, one per line. Each is resolved through Propwire's own lookup and returns that property's full record. Takes priority over links and search filters.
addressMatchModestringfirstWhen a lookup returns several parcel matches for one address (for example condos), first takes the top suggestion, all returns every match.
startUrlsarrayone sample property linkPropwire search links or property links. A search link is walked forward page by page; a property link returns that one record. Takes priority over search filters: if you call the API without startUrls at all (key omitted), the built-in sample property link applies: pass an empty array to run pure search filters instead.
searchStatesarray["FL"]US state codes to sweep state-wide. Used only when addresses and links are empty. At most 10 per search.
searchLocationsarray(none)Cities, ZIP codes or counties to narrow the states above, resolved through Propwire's own location lookup. Usable on its own too.
searchLeadTypesarray(none)Only return properties carrying these lead-type flags. Values marked premium on the site may require a Propwire account and can come back empty.
searchPropertyTypesarray(none)Restrict the sweep to these property types.
searchEstimatedValueMininteger(none)Only return properties estimated to be worth at least this much.
searchEstimatedValueMaxinteger(none)Only return properties estimated to be worth at most this much.
searchYearBuiltMininteger(none)Only return properties built in or after this year.
searchYearBuiltMaxinteger(none)Only return properties built in or before this year.
searchSoldSincestring(none)Only return properties last sold on or after this date, YYYY-MM-DD.
searchOwnerTypearray(none)Only return properties owned by individuals or by companies/LLCs/trusts. Leave empty for both.
searchMlsStatusstring(none)Only return properties currently in this MLS state. Leave empty for all statuses.
fetchDetailsbooleantrueRead each property's full record: owner, mailing address, ownership length, portfolio, foreclosure, auction, mortgage and transfer history, tax, parcel/zoning, building specs and the full MLS record when one exists. Without it, records carry only the search-card fields.
maxItemsinteger0Stop after this many property records across the whole run (0 = no limit).
maxPagesinteger0Runaway guard: an upper bound on how many result pages any single search walk may read (0 = as deep as the source serves).
resumeFromRunIdstring(none)Continue one earlier, interrupted run of this actor without re-collecting (or re-billing) rows it already returned.
incrementalModebooleanfalseTurn on for daily or weekly lead monitoring: later runs return only NEW, UPDATED and REAPPEARED records for the same scope. Property fields (value, beds/baths, size, MLS price and status), equity, lead flags and owner detail drive UPDATED; image URLs, scrapedAt, position and the source fields are excluded by default.
stateKeystring(none)Name a monitoring campaign to keep its memory stable, or share one memory across differently configured runs.
emitUnchangedbooleanfalseAlso return (and bill) records that have not changed since the last run, labelled UNCHANGED.
emitExpiredbooleanfalseAlso return (and bill) records that were present before and are no longer found, labelled EXPIRED. Never produced after a capped or continued run; keep the search under Propwire's 10,000-result limit when you use it.
ignoreFieldsForChangesarray(none)Recurring updates only: top-level record fields to leave out of change detection on top of the built-in defaults (image URLs, scrapedAt, position, the source fields and the stored raw payload). A field named here never drives UPDATED and is never named in changedFields, so a value that churns on every fetch in your setup stops re-billing unchanged records.
mcpConnectorsarray(none)Connector names authorized under Apify, Settings, Integrations (Notion, Linear, Airtable, Apify). Each selected connector receives a condensed summary per pushed record.
notionParentPageUrlstring(none)Notion parent page URL or id under which per-record pages are created. Notion connector only.
maxNotifyListingsinteger50Cap on items written to each connector per run (1-1000). Does not affect the dataset.
proxyConfigurationobjectResidential, USConnection used for every request. Propwire's own protection refuses ordinary datacenter connections, so the default requests the residential connection tier; it needs a plan that includes that tier, and the run automatically continues on backup connections if the tier is unavailable to it. You can also paste your own connection links.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"recordType": "property",
"id": 12345678,
"propwireUrl": "https://propwire.com/realestate/100-Main-St-Anytown-FL/12345678/property-details",
"address": "100 Main St",
"city": "Anytown",
"state": "FL",
"zip": "32000",
"county": "Sample",
"propertyType": "SFR",
"bedrooms": 3,
"bathrooms": 2,
"buildingAreaSf": 1650,
"lotSizeSf": 6500,
"yearBuilt": 1998,
"estimatedValue": 344800,
"estimatedEquity": 182400,
"estimatedEquityPercentage": 53,
"lastSoldDate": "2021-06-17",
"lastSoldPrice": 250000,
"daysOnMarket": 42,
"mlsListPrice": 325000,
"mlsListDate": "2026-08-07",
"mlsStatus": "ACTIVE",
"leadTypes": ["ABSENTEE_OWNER", "HIGH_EQUITY", "OUT_OF_STATE_OWNER"],
"ownerNames": ["SAMPLE JANE", "SAMPLE JOHN"],
"ownerTypes": ["INDIVIDUAL"],
"ownerOccupied": false,
"ownershipYears": 5,
"ownerMailingAddress": "PO Box 1000, Sample Town, NJ 07000",
"portfolioPropertiesOwned": 4,
"portfolioValue": 1240000,
"foreclosureActive": true,
"auctionDate": "2026-12-02",
"apn": "12-34-56-78-90",
"zoning": "R1",
"latitude": "28.500000",
"longitude": "-81.400000",
"taxAssessedValue": 270000,
"taxBilledAmount": "3400.00",
"imageUrl": "https://images.example.com/sample-cover.jpg",
"imageUrls": ["https://images.example.com/sample-1.jpg", "https://images.example.com/sample-2.jpg"],
"photoCount": 28,
"detailFetched": true,
"sourceType": "search",
"scrapedAt": "2026-09-25T12:00:00Z",
"changeType": "NEW",
"changedFields": [],
"firstSeenAt": "2026-09-25T12:00:00Z",
"lastSeenAt": "2026-09-25T12:00:00Z",
"raw": { "note": "the complete verbatim source payload: owner, portfolio, foreclosure, mortgage, transfer, tax, parcel and full MLS objects" }
}

With Recurring updates on, every row also carries changeType, changedFields, firstSeenAt and lastSeenAt (shown above), and the run's output gains a Changes tab that shows only the identity columns plus those fields, so a monitoring campaign reads like a diff. The full record stays on every row in the default view.

Plan Requirement

Propwire's own protection refuses ordinary datacenter connections, so this actor requests the residential connection tier by default, pinned to the US. That tier needs a plan that includes it. Whether it is available to a run is observed, not assumed: before a connection is first used, the run opens a cheap tunnel check against it. When the residential tunnel is refused (a plan without that entitlement), the run prints this warning once and continues on backup connections:

----------------------------------------------------------------
The selected connection is unavailable to this run.
Apify free plans do not include residential proxies.
Continuing on a backup connection; some pages may still be unavailable.
For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.
----------------------------------------------------------------

The failover ladder is: your resolved connection first (residential by default), then the platform's automatic pool, then a backup residential pool, then a backup datacenter pool. The backup residential pool is only ever used after the platform's residential tunnel was confirmed open in that run, so a run without that entitlement is served by the backup datacenter pool. Every request runs under a per-fetch time budget with fresh exits on retry, so a dead connection costs seconds, not minutes. When no page could be loaded at all, the run fails loudly with one of three messages: "The proxy connection was refused for this account, so no page could be read" (the plan does not include proxy access, or your own connection links have invalid credentials), "No results: residential proxies are unavailable on this run ... and the backup connection could not load the requested Propwire pages", or "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search." Bring-your-own connection links are used exactly as given, with no backup pools added.

FAQ

How much does it cost?

This actor charges per property record returned, plus a separate charge for each property whose full record was read (Full property records), and a per-run start charge. Records suppressed as unchanged under Recurring updates are never billed. The Pricing tab shows the current rates. Use Max records to cap the cost of any run.

This actor collects only publicly available property, ownership and MLS data as published by Propwire. You are responsible for how you use it: follow Propwire's terms and the laws that apply to you, including data-protection and telemarketing rules where you use owner contact details for outreach, and get legal advice if you plan commercial redistribution.

Can I get only new or changed leads on a schedule?

Yes. Schedule the actor from the Schedules tab with the same search filters and turn on Recurring updates. Each run then returns only NEW, UPDATED and REAPPEARED records for that scope, and unchanged ones are not returned or billed unless you turn on Also return unchanged records. If a field churns on every fetch in your setup and keeps re-billing rows, name it in Ignore fields when detecting changes and it stops driving updates from the next run on. The Changes tab of the output shows the campaign as a diff.

Why did a run return fewer properties than I expected?

A few honest reasons: Max records or Max pages per search stopped the run early; Propwire itself serves only the first 10,000 rows of any one search, so a very broad sweep needs narrower geography or filters; a location in Cities, ZIPs or counties could not be resolved and was skipped; or a lead-type flag marked premium on the site came back empty because it needs a Propwire account. The run log warns when a limit, the 10,000-row cut-off or an unresolved location stopped part of the collection.

Why did my run fail instead of returning an empty dataset?

If no page could be loaded at all, the run stops with one of three clear failure messages, because that is a connection problem, not evidence that no properties exist: the connection was refused for the account (a plan without proxy access, or own connection links with invalid credentials), a run without the residential entitlement whose backup connection could not load the pages, or a temporary connection problem on every attempt. Run it again in a few minutes, or check the Connection section of the input. A search that was genuinely read and holds nothing for your filters succeeds normally and says so on the run page.

Can I use it with AI agents or automation platforms?

Yes. Call it from the API, the Scheduler, or any Apify integration (Make, Zapier, n8n, Google Sheets, webhooks), or from an MCP client through Apify's own MCP server.

πŸ”— More scrapers you might like

Pair this actor with these related scrapers from the same team:

🏠 Auction.com Scraper
From $1/1K. Extract foreclosure, REO, short-sale, and auction listings from Auction.com...
🧩 Homes.com Scraper
Scrape US property records from Homes.com. Pick a city, state or ZIP and a channel (for...
🏠 Redfin Scraper
Scrape redfin.com home listings: price, beds, baths, sqft, lot, year built, coordinates...
🧩 Zillow Scraper
Scrape zillow.com properties for sale, for rent and recently sold across the US: price...
🏠 Crexi Scraper
Scrape crexi.com commercial listings: asking price, cap rate, square footage, units, year...
🏠 591.com.tw Scraper
Extract property listings from 591ζˆΏε±‹δΊ€ζ˜“ηΆ² 591.com.tw, Taiwan’s largest real estate...

πŸ‘‰ Browse all abotapi scrapers

πŸ’¬ Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • πŸ› οΈ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.