Trulia Scraper - Property Listings, Prices, Agents & History
Pricing
from $1.00 / 1,000 listing scrapeds
Trulia Scraper - Property Listings, Prices, Agents & History
Scrape Trulia.com property listings by location, filters, or URL. Extract prices, beds, baths, square footage, addresses, GPS coordinates, photos, agents, and brokers, plus detailed price and tax history, property features, and open house information.
Pricing
from $1.00 / 1,000 listing scrapeds
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
7 days ago
Last modified
Categories
Share
Trulia Scraper: Property Listings, Prices, Photos & Agent Contacts
Trulia Scraper turns Trulia into a clean property data feed for the United States. Search any US location for homes for sale, for rent, or recently sold, or paste Trulia search and property links you already have. Every listing comes back as one record with price, beds, baths, square footage, full address, GPS coordinates, photo gallery, status tags, and the listing agent and broker. Turn on detail mode to also pull price history, tax history, the full feature list, open houses, agent contact, and affordability data straight from each property page, then export to JSON, CSV or Excel, or read it through the API.
Why This Scraper?
- Rich cards out of the box. Search results already carry price, beds, baths, size, full address, neighborhood, GPS coordinates, photo gallery, status tags and the listing agent and broker name, with no extra fetch needed.
- Optional deep detail. One toggle adds price history, tax history, the full feature list, open houses, agent and broker contact, local protections, affordability data and estimated rent from the property page.
- Three listing channels. For sale, for rent, and recently sold, all from the same search fields.
- Real keyword filter. Narrow a location to listings whose text mentions a term such as pool, waterfront or garage.
- Two ways to start. Build a search from simple fields, or paste Trulia search and property links you already have, with automatic pagination on search links.
- Predictable runs. Detail mode is off by default so a standard run stays fast and low cost, and Max items keeps every run's size and spend capped.
- Built for schedules. Resume continues one interrupted crawl, and Incremental mode turns a recurring search into a feed of only what is new, updated or reappeared.
Use Cases
- Real estate investors and flippers: track new listings and price drops for sale in target neighborhoods.
- Rental market research: collect current for-rent inventory and pricing across a metro area or ZIP code.
- Market analysts and appraisers: build historical comps from recently sold listings, including price and sale history.
- PropTech and data teams: feed a normalized property dataset into an internal tool, model or dashboard.
- Relocation and lead-generation sites: enrich listing pages with fresh price, photo and agent contact data.
- Agents and brokers: monitor a search for new listings or status changes and get only the changes on a schedule.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
id | "00000001" |
url | "https://www.trulia.com/home/sample-address-ny-10000-00000001" |
listingType | "FOR_SALE" (also "FOR_RENT", "SOLD") |
propertyType | "SINGLE_FAMILY_HOME" |
price / formattedPrice | 750000 / "$750,000" |
streetAddress | "123 Sample Street" |
city / state / zipCode | "Sampletown" / "NY" / "10000" |
neighborhood | "Sample Heights" |
latitude / longitude | 40.0000 / -73.0000 |
bedrooms / bathrooms | 3 / 2 |
floorSpace | "1,800 sqft" |
lotSize | "0.25 acres" |
listingAgentName | "Agent Name" |
brokerName | "Sample Realty" |
heroImage | listing's main photo URL |
photos | array of gallery photo URLs |
tags | ["NEW", "OPEN SUN"] (status badges) |
dateListed | "2026-01-01" |
description | listing description text |
scrapedAt | "2026-01-01T00:00:00.000Z" |
With Fetch property details enabled, each record also gains priceHistory, taxes, features, openHouses, providerDetails (agent and broker contact), localProtections, affordability, estimatedRent, totalPhotoCount, detailFetched (whether this record's own detail fetch actually succeeded this run), plus the full homeDetails object.
Incremental mode only. When incrementalMode is on, a returned record also carries changeType (NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED), changedFields (populated only for UPDATED), firstSeenAt and lastSeenAt. An EXPIRED row is a tombstone built from the last snapshot this actor collected, not a fresh re-fetch of a listing that is gone.
How to Use
- Pick a Start mode: search by location, or paste direct Trulia URLs.
- In search mode, fill in Location, Listing type and optionally Keyword and Sort; in URL mode, paste one or more Trulia search or property links.
- Turn on Fetch property details if you need price history, taxes, features or agent contact, and set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Basic search:
{"mode": "search","searchLocation": "Austin,TX","searchListingType": "FOR_SALE","maxItems": 50}
Search with keyword and sort:
{"mode": "search","searchLocation": "Miami,FL","searchListingType": "FOR_SALE","searchKeyword": "pool","searchSort": "PRICE_LOW_TO_HIGH","maxItems": 100}
For rent, with full detail enrichment:
{"mode": "search","searchLocation": "Seattle,WA","searchListingType": "FOR_RENT","fetchDetails": true,"maxItems": 40}
Direct URLs (search URLs paginate, property URLs return one record each):
{"mode": "url","startUrls": ["https://www.trulia.com/sold/Denver,CO/","https://www.trulia.com/home/sample-address-co-80000-00000002"],"maxItems": 60}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/trulia-scraper").call(run_input={"mode": "search","searchLocation": "Austin,TX","searchListingType": "FOR_SALE","maxItems": 50,})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["streetAddress"], listing["formattedPrice"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/trulia-scraper').call({mode: 'search',searchLocation: 'Austin,TX',searchListingType: 'FOR_SALE',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.
Max items and Max pages
Max items is the run's overall cap on listings. When you paste several URLs, it is split evenly between them (each URL gets Max items divided by the number of URLs, rounded up), so every URL is represented. Max pages is an optional extra safety cap on pages walked per search or URL (Trulia serves 40 listings per page); leave it empty to walk every result page and let Max items decide when to stop.
Listings are deduplicated once across the whole run, not per URL, so the same listing is never returned twice even if two of your URLs overlap. Known limitation, URL mode with two or more URLs only: when a URL's share of Max items runs out partway through a results page, the listings on that page that were not collected are still marked as already seen for the rest of the run. If a later URL in the same run reaches one of those listings (two overlapping search areas, or a property URL for a home that appeared on that cut page), it is skipped without a warning and never returned by either URL, so the run can end with fewer listings than Max items allows. Raising Max items does not reliably avoid this, because a URL's share almost always ends mid-page. To avoid it, set Max items to 0 (unlimited) and bound the run with Max pages instead, or run overlapping URLs as separate runs. Search mode is not affected, because it runs one search per run.
Resume and recurring updates
Resume (resumeFromRunId) continues one specific interrupted or previous run: paste its run ID or dataset ID and this run skips listings already collected there, returning only what is left. Because Resume reads the listings actually saved in that earlier dataset, it is not affected by the limitation above. An automatic same-run checkpoint also lets a run continue after a platform migration or the Resurrect button, without any input needed. That checkpoint stores the run's "already seen" list, so it carries the limitation above into the continued run, and listings from the page being processed at the exact moment of a migration can be marked as seen before they were saved and then skipped. If a migrated or resurrected run looks short, start a new run with Resume pointed at it to collect only what is missing.
Incremental mode (incrementalMode) is for scheduling the same search or URL set repeatedly, for example daily. The actor remembers the previous run of that same search by itself, so no run ID needs to be pasted. The first run returns everything as NEW; later runs return only NEW, UPDATED and REAPPEARED listings by default, and duplicates or unchanged listings are suppressed and not billed. Turn on emitUnchanged or emitExpired only when you also want those rows returned, and billed for. State is scoped per location or URL, listing type, keyword, sort and the fetchDetails setting automatically; set stateKey to name or deliberately share a monitoring campaign. With fetchDetails on, a listing's property page is still fetched every run so change detection stays accurate, but the enrichment charge only applies to listings actually returned; a suppressed unchanged listing is neither pushed nor billed.
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 record, 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.
- Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where items should be created.
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
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search builds Trulia search URLs from the filters below; url takes Trulia search or property URLs you already have. |
searchLocation | string | New_York,NY | Search mode only. A US location as City,STATE. Spaces are converted to underscores automatically. |
searchListingType | string | FOR_SALE | Search mode only. FOR_SALE, FOR_RENT, or SOLD. |
searchKeyword | string | (empty) | Search mode only. Narrows results to listings whose text mentions this keyword. Leave empty for no keyword filter. |
searchSort | string | RECOMMENDED | Search mode only. RECOMMENDED, NEWEST, PRICE_LOW_TO_HIGH, or PRICE_HIGH_TO_LOW. Trulia may place a few promoted listings ahead of the chosen order. |
startUrls | array | (empty) | URL mode only. Trulia search URLs (paginated automatically) or property/home URLs (fetched as single detail records). Multiple URLs supported. |
fetchDetails | boolean | false | Include price history, tax history, the full feature list, open houses, listing agent and broker contact, affordability and more from the property page. Billed per enriched listing that is actually returned. |
maxItems | integer | 20 | Maximum number of listings to scrape across all searches and URLs in this run. Set 0 for unlimited. |
maxPages | integer | (unlimited) | Optional safety cap on search pages to walk per location or URL (40 listings per page). Leave empty to walk every result page; the run still stops at Max items. |
resumeFromRunId | string | (none) | Paste a previous run ID or dataset ID from this actor to continue a large crawl without returning or charging for listings already collected there. For recurring monitoring of the same search, use Incremental mode instead. |
incrementalMode | boolean | false | Turn on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings. |
stateKey | string | (none) | Optional. Names this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Left empty, the actor derives a key automatically from the location or URLs, listing type, keyword, sort, and fetchDetails settings. |
emitUnchanged | boolean | false | Incremental mode only. Also return (and bill for) listings unchanged since the last run, marked UNCHANGED. |
emitExpired | boolean | false | Incremental mode only. Also return (and bill for) listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search (not capped, not a resume). |
proxy | object | Residential (US) | Connection settings. Trulia requires a residential connection pinned to the United States; this is the default. |
mcpConnectors | array | (none) | Optionally send a summary of each record to apps you authorized under Integrations (Notion, Linear, Airtable, or Apify). |
notionParentPageUrl | string | (none) | Notion connector only. URL or id of the Notion page under which item pages are created. Ignored by other connectors. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run, from 1 to 1000. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"id": "00000001","url": "https://www.trulia.com/home/sample-address-ny-10000-00000001","listingType": "FOR_SALE","propertyType": "SINGLE_FAMILY_HOME","price": 750000,"formattedPrice": "$750,000","streetAddress": "123 Sample Street","city": "Sampletown","state": "NY","zipCode": "10000","neighborhood": "Sample Heights","latitude": 40.0,"longitude": -73.0,"bedrooms": 3,"bathrooms": 2,"floorSpace": "1,800 sqft","lotSize": "0.25 acres","listingAgentName": "Agent Name","brokerName": "Sample Realty","heroImage": "https://www.trulia.com/pictures/thumbs_4/sample/00000000-full.jpg","photos": ["https://www.trulia.com/pictures/thumbs_6/sample/00000000-full.jpg"],"tags": ["NEW"],"dateListed": "2026-01-01","description": "Sample listing description.","scrapedAt": "2026-01-01T00:00:00.000Z"}
Plan Requirement
Trulia only accepts connections from residential IP ranges in the United States, so this actor requires an Apify Residential proxy pinned to the US, which is already the default in the Connection field, so most users do not need to change anything. Datacenter connections are refused. The actor rotates across residential exits and can automatically move to an alternate connection after repeated failures. If a run returns zero listings, confirm the Connection field is still set to Residential (US).
FAQ
How much does it cost?
You pay per listing returned, with the optional property-detail enrichment billed only for listings that are actually returned. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Trulia?
This actor collects only publicly available real estate listing data. You are responsible for how you use it: follow Trulia's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts (price, address, specs) are generally factual data, but photos and some agent/broker content may be subject to third-party rights.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab with the same search or URL input and turn on Incremental mode. Each run then returns only new, updated and reappeared listings, and unchanged ones are not billed.
Why did my run return fewer listings than I expected?
The most common reason is Max items: raise it, or set it to 0 for unlimited, to walk every available result page. Max pages is a separate, optional cap on pages per search or URL; leave it empty to remove it. A search or keyword that is genuinely narrow can also just have few results on Trulia itself.
Why is a listing sometimes missing even though it is on Trulia?
Two common causes. First, this actor requires a Residential (US) connection; without it, a run typically returns zero listings. Second, in URL mode with several overlapping URLs, when one URL's share of Max items ends partway through a results page, the uncollected listings on that page are still treated as already seen for the rest of the run. If another URL in the same run reaches one of them, it is skipped without a warning rather than returned. Set Max items to 0 and use Max pages as the bound, or run overlapping URLs as separate runs, to avoid it. A run continued after a platform migration or Resurrect can also miss a few listings from the page in progress at that moment; a follow-up run with Resume pointed at it collects them.
Why did my run fail instead of returning an empty dataset?
If nothing could be read at all (for example, every request was refused), the run stops with a clear message so "no listings match" is never confused with "nothing could be read." Run it again in a few minutes, and double-check the Connection field is set to Residential (US).
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
๐ Want more real estate data?
Pair this actor with these related scrapers from the same team:
| ๐ View.com.au Scraper Scrape View.com.au properties for sale, rent and recently sold across Australia. Search... | ๐ Redfin Scraper Scrape redfin.com home listings: price, beds, baths, sqft, lot, year built, coordinates... |
| ๐ Realtor.ca From $1/1K. Scrape Realtor.ca property listings with prices, descriptions, images, agent... | ๐ Realtor.com From $0.9/1K. Extract property listings from realtor.com. Get comprehensive data... |
| ๐ Real Estate AU Extract detailed Australian real estate property listings with 30+ structured fields... | ๐ StreetEasy Scraper Scrape StreetEasy sales, rentals and in-contract listings across NYC and Jersey City... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ 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 abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.