# Trulia Property Scraper with Contacts & Features (`fatihtahta/trulia-property-scraper`) Actor

Extract Trulia property listings with prices, coordinates, photos, full descriptions, amenities, history, and available agent contacts. Use enrichment and coverage mode for comps, market research, inventory monitoring, CRM, BI, ETL, and AI workflows.

- **URL**: https://apify.com/fatihtahta/trulia-property-scraper.md
- **Developed by:** [Fatih Tahta](https://apify.com/fatihtahta) (community)
- **Categories:** Real estate, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Trulia Property Scraper

**Slug:** `fatihtahta/trulia-property-scraper`

### Overview

Trulia Property Scraper collects public property listings with prices, addresses, coordinates, property characteristics, listing status, media, availability, attribution, and available contact details. [Trulia](https://www.trulia.com/) is a public real estate search service whose listing pages can support property discovery, market monitoring, comparable-listing research, and operational review. The actor turns a Trulia market URL or location-based buy, rent, or sold search into repeatable structured collection. Optional enrichment adds fuller descriptions, galleries, features, history, and available agent or agency information to the same listing records. Results are delivered as structured dataset records suitable for review, export, ETL pipelines, BI dashboards, AI-agent workflows, and downstream processing. Stable identifiers, grouped objects, and run-level artifacts make recurring runs easier to compare and audit. The actor is designed for dependable recurring acquisition of data that Trulia exposes publicly at run time, without implying complete market coverage or continued listing availability.

### What Makes This Actor Different

- **Pipeline-ready property records:** Each row uses a documented `property_listing` envelope with stable identity, provenance, listing, pricing, location, property, media, availability, relationship, contact, and source-specific groups.
- **Deduplication-friendly identity:** `record_id` is the recommended upsert key, while `url`, `listing.listing_id`, `property.property_id`, and source identifiers provide additional audit context when available.
- **Standard and enriched collection:** Standard runs retain search-result listing data. Enriched runs can add descriptions, larger image galleries, structured features, price or tax history, and available public listing contacts without changing the base record family.
- **Coverage-aware collection:** `maximize_coverage` can collect deeper within the selected location, listing mode, and criteria when a broad search exposes more matching listings than are normally visible at once. It does not relax the selected scope and continues to respect `limit`.
- **Operational run receipts:** `RUN-SUMMARY` and `RUN-SUMMARY.html` report saved counts, duration, coverage state, enrichment outcomes, location and pricing breakdowns, warnings, representative records, and artifact keys.
- **Map-ready review:** Valid `location.latitude` and `location.longitude` values feed a stable interactive `results-map` artifact. The map reports mapped, skipped, and deduplicated marker counts, including a clear zero-location state.
- **Agentic usability:** Input recipes, stable field names, bounded summaries, output links, and a detailed field reference make the actor suitable for Claude, Codex, internal agents, and workflow automations without private operational context.
- **Optional MCP handoff:** User-authorized Apify MCP connectors can receive a compact run summary and available dataset, report, and map links after the primary outputs are ready. Full listing rows are not sent through this default connector path.

### Who Should Use This Actor

- **Real estate investors and analysts:** Build scoped listing datasets for public comparable research, supply analysis, price segmentation, and location review.
- **Brokerages and property operations teams:** Monitor public inventory, listing status, advertised prices, open-house availability, and public attribution across recurring runs.
- **Market research and analytics teams:** Create repeatable snapshots for neighborhood, property-type, bedroom, bathroom, area, and pricing analysis.
- **Proptech and data engineering teams:** Ingest nested, typed JSON into warehouses, search indexes, internal applications, CRM systems, and enrichment pipelines.
- **BI and reporting teams:** Feed dashboards with listing counts, property mix, asking prices, geography, media coverage, and point-in-time status signals.
- **AI agents and workflow automations:** Run a defined property search, validate the run receipt, summarize findings, and route records into a downstream review or alert workflow.
- **Lead and enrichment teams:** Add public property, agent, agency, media, and contact context to an existing listing or opportunity record when enrichment exposes it.

### Common Use Cases

- **Market intelligence:** Capture public listing supply, asking prices, status, property mix, and geographic distribution for a selected market.
- **Comparable-listing research:** Collect structured property attributes for a city, ZIP code, neighborhood, sale market, rental market, or recently sold segment.
- **Recurring inventory monitoring:** Repeat the same input on a schedule and compare stable records for new, missing, repriced, or updated listings.
- **Listing enrichment:** Add public descriptions, property features, image galleries, history, attribution, and available contacts to lightweight listing records.
- **Portfolio and location research:** Review addresses, coordinates, neighborhoods, dimensions, amenities, and nearby-school context when available.
- **CRM and directory population:** Upsert public property listings and related agent or agency context into operational systems using `record_id`.
- **Dashboard refreshes:** Produce JSON-first snapshots for pricing, property characteristics, status, enrichment, and map coverage reporting.
- **Agentic research workflows:** Let an automated agent define a supported search, inspect run artifacts, analyze records, and prepare a human review queue.

### Real-World Questions This Data Can Answer

- Which public Trulia listings are visible for a specific city, ZIP code, neighborhood, or market and listing mode?
- What asking-price, property-type, bedroom, bathroom, and area mix appears in the collected segment?
- Which records appear new, removed, repriced, or updated when compared with a previous internal snapshot?
- Which listings expose coordinates, photo galleries, 3D-home signals, open houses, tours, or richer property features?
- Which public agent, agency, developer, attribution, or contact values are available for enriched records?
- How many listings were saved, enriched, mapped, skipped, or deduplicated in a particular run?
- Did a broad run use deeper matching coverage, reach its requested limit, or finish with a coverage warning?

### Quick Start

1. Choose either one supported Trulia market-search URL or a `location` such as `Austin, TX`.
2. Select `deal_type`: `buy`, `rent`, or `sold`.
3. Set a small `limit`, such as 5 or 20, for the first validation run and decide whether `enrich_data` is needed.
4. Start the actor in Apify Console and inspect the first dataset records plus the run summary and map.
5. After validating the record shape, raise the limit, enable `maximize_coverage` when appropriate, export the dataset, or create a schedule.

### Input Parameters

The public input supports a Trulia market URL or location-based search, listing mode, enrichment, deeper matching coverage, optional MCP summary delivery, and a result limit.

| Parameter | Type | Description | Default |
| --- | --- | --- | --- |
| `url` | array of strings | One supported Trulia city or market search URL. URL mode is authoritative when supplied; individual property-detail URLs are not supported as search seeds. Provide one URL per run. | – |
| `location` | string | City, state, ZIP code, neighborhood, or Trulia-supported market used to build a search when `url` is absent. | – |
| `deal_type` | string | Listing mode. Allowed values: `buy`, `rent`, `sold`. For URL mode, choose the value that matches the supplied Trulia page. | `buy` |
| `enrich_data` | boolean | Adds available descriptions, galleries, property features, history, attribution, and public contact context. Disable for a lighter validation or monitoring run. | `true` |
| `maximize_coverage` | boolean | Collects deeper within the same selected criteria for broad searches. Intended for larger runs; the configured `limit` still applies. | `true` |
| `mcpConnectors` | array of connector resources | Optional user-authorized Apify connectors for compact post-run summary delivery. The primary dataset and run artifacts remain authoritative. | `[]` |
| `limit` | integer | Maximum property records to save. Minimum: 1. Leave empty to use the actor's standard bounded run behavior. | – |

### Choosing Inputs

Use `url` when you already have a supported Trulia city or market search page and want a repeatable target. Supply one URL and select the matching `deal_type`; the URL takes precedence over `location`. Use `location` when you want the actor to build a buy, rent, or sold search from a city, state, ZIP code, neighborhood, or market name.

Start with a small `limit` and inspect several records before increasing volume. Keep `enrich_data` enabled when descriptions, feature details, photo galleries, history, or public listing contacts matter; disable it when lightweight search-result fields are enough. Enable `maximize_coverage` for broad markets, high-volume segments, recurring inventory collection, or cases where Trulia reports more matches than are normally visible. Leave it disabled for faster exploratory runs when the first result set is sufficient. For cleaner comparisons, segment recurring work into separate runs by geography and `deal_type` rather than mixing unrelated markets.

### Input Recipes

- **Validation run:** Use one focused `location`, select `deal_type`, keep `maximize_coverage` off, and set `limit` to 5. Enable or disable enrichment based on the fields you plan to inspect.
- **Repeatable market URL:** Supply one known Trulia market URL, choose its matching `deal_type`, and set a conservative `limit`. Reuse the same input for consistent snapshots.
- **Broad market discovery:** Use a city or metro-level `location`, minimal configuration, and a sensible limit. Review the run summary before expanding volume.
- **Maximum matching coverage:** Use a broad location, set a limit of at least 950 or leave it empty, and enable `maximize_coverage` to collect deeper within the same criteria.
- **Enriched research run:** Use a focused URL or location, enable `enrich_data`, and set a bounded limit to collect fuller property, media, history, attribution, and contact context.
- **Recurring monitoring:** Save one stable URL or location-and-mode configuration, run it on a schedule, and compare records by `record_id` plus price, status, and update fields.

### Example Inputs

#### Example: location-based sale listings

```json
{
  "location": "Austin, TX",
  "deal_type": "buy",
  "enrich_data": true,
  "maximize_coverage": false,
  "limit": 20
}
````

#### Example: repeatable rental-market URL

```json
{
  "url": [
    "https://www.trulia.com/for_rent/Los_Angeles,CA/"
  ],
  "deal_type": "rent",
  "enrich_data": false,
  "maximize_coverage": false,
  "limit": 50
}
```

#### Example: broad sold-market research

```json
{
  "location": "Phoenix, AZ",
  "deal_type": "sold",
  "enrich_data": true,
  "maximize_coverage": true,
  "limit": 950
}
```

### Output

#### Output destination

The actor writes results to an Apify dataset as JSON records. The dataset is designed for direct consumption by analytics tools, ETL pipelines, AI agents, and downstream APIs with minimal post-processing.

The current public dataset contains one documented record shape: `property_listing`. Run summaries, reports, maps, and diagnostics are separate key-value-store artifacts, not dataset records.

#### Record envelope and stable identifiers

Every row requires `record_type`, `record_id`, `url`, `source_context`, and `entity`. Use `record_id` as the recommended idempotency key for deduplication and upserts. The typed identifier is stronger than title or address matching and makes records easier to merge, synchronize, and compare across repeated runs. `url` and `source_context.source_url` provide public source traceability, while `listing.listing_id`, `property.property_id`, and nested external IDs provide additional matching context when present.

When loading repeated runs, upsert by `record_id` and compare point-in-time business fields such as `pricing.price`, `listing.listing_status`, `listing.updated_at`, and availability values. Keep run date and input segment alongside the record in your destination system.

#### Example: property listing record

The following example is synthetic but preserves the supported public structure and value types. Optional groups appear only when the source exposes them and enrichment succeeds.

```json
{
  "record_type": "property_listing",
  "record_id": "987654321_ZPID",
  "url": "https://www.trulia.com/home/1842-sample-ave-austin-tx-78704-987654321",
  "source_context": {
    "source_id": "trulia_property_scraper",
    "source_domain": "trulia.com",
    "source_url": "https://www.trulia.com/home/1842-sample-ave-austin-tx-78704-987654321",
    "seed_type": "location",
    "seed_value": "Austin, TX",
    "page_number": 1,
    "position": 3,
    "language": "en",
    "country": "US",
    "enrichment_status": "enriched",
    "enrichment": {
      "requested": true,
      "status": "enriched",
      "enriched": true
    }
  },
  "entity": {
    "title": "1842 Sample Ave",
    "description": "Updated sample residence with an open living area and a fenced yard.",
    "external_ids": {
      "typed_home_id": "987654321_ZPID",
      "zpid": "987654321"
    }
  },
  "listing": {
    "listing_id": "987654321_ZPID",
    "listing_type": "RESALE",
    "listing_status": "active_for_sale",
    "status_text": "For Sale",
    "deal_type": "sale",
    "posted_at": "2026-07-08T14:30:00+00:00",
    "updated_at": "July 10, 2026",
    "status_flags": {
      "is_active_for_sale": true,
      "is_active_for_rent": false,
      "is_recently_sold": false,
      "is_foreclosure": false
    },
    "external_ids": {
      "mls_id": "SAMPLE-1842"
    },
    "source_attribution": "Sample regional listing source",
    "history": {
      "price_history": [
        {
          "formattedDate": "07/08/2026",
          "event": "Listed For Sale",
          "price": {
            "price": 725000,
            "formattedPrice": "$725,000"
          }
        }
      ]
    }
  },
  "pricing": {
    "price": 725000,
    "price_text": "$725,000",
    "currency": "USD",
    "price_per_area_text": "$402/sqft"
  },
  "location": {
    "address": "1842 Sample Ave, Austin, TX 78704",
    "street_address": "1842 Sample Ave",
    "city": "Austin",
    "region": "TX",
    "postal_code": "78704",
    "country": "US",
    "neighborhood": "South Austin",
    "latitude": 30.2451,
    "longitude": -97.7684
  },
  "property": {
    "property_id": "987654321",
    "property_type": "SINGLE_FAMILY_HOME",
    "bedrooms": 3,
    "bathrooms": 2.5,
    "floor_area": 1804,
    "area_unit": "sqft",
    "land_area": 0.16,
    "land_area_unit": "acre",
    "amenities": [
      "Interior: Fireplace",
      "Parking: Garage"
    ],
    "features": [
      {
        "group": "Interior Features",
        "name": "Fireplace",
        "value": "Yes"
      }
    ],
    "measurement_sources": {
      "floor_area": {
        "raw_text": "1,804 sqft"
      }
    }
  },
  "media": {
    "main_image_url": "https://static.trulia-cdn.com/pictures/sample-property.jpg",
    "image_urls": [
      "https://static.trulia-cdn.com/pictures/sample-property.jpg"
    ],
    "has_3d_home": true,
    "has_video": false,
    "total_photo_count": 24
  },
  "availability": {
    "tour_available": true,
    "open_houses": [
      {
        "date_label": "Saturday",
        "start_time": "11:00 AM",
        "end_time": "2:00 PM"
      }
    ]
  },
  "contact_details": {
    "phones": [
      "(512) 555-0142"
    ],
    "contacts": [
      {
        "role": "agent",
        "name": "Sample Listing Agent",
        "phone": "(512) 555-0142"
      }
    ]
  },
  "relationships": {
    "agent": {
      "name": "Sample Listing Agent",
      "phone": "(512) 555-0142"
    },
    "agency": {
      "name": "Sample Property Group"
    },
    "listing_source": {
      "attribution": "Sample regional listing source"
    }
  },
  "attributes": {
    "tags": [
      {
        "name": "New Listing",
        "level": "HIGHLIGHT"
      }
    ],
    "trulia": {
      "provider_summary": [
        "Sample Listing Agent, Sample Property Group"
      ]
    }
  }
}
```

#### Run Summary, Map, And Artifacts

The actor exposes the default dataset as the primary output and writes these stable run artifacts to the run's key-value store:

| Artifact | Format | Operational use |
| --- | --- | --- |
| `RUN-SUMMARY` | JSON | Machine-readable receipt with input scope, saved and duplicate counts, duration, coverage state, enrichment results, price and property breakdowns, coordinate/map counts, warnings, representative records, and artifact keys. |
| `RUN-SUMMARY.html` | HTML | Human-readable presentation of the same core counts and breakdowns for operators and stakeholders. |
| `results-map` | HTML | Clustered interactive map of listings with valid coordinates, plus mapped, skipped, and deduplicated marker counts. |
| `RUN-SUMMARY-ERROR` | JSON | Best-effort public diagnostic written only when a summary or map cannot be prepared after listing records are already saved. |

Use the summary as a run receipt before importing records: confirm saved totals, review warnings, see whether enrichment or deeper coverage was used, and determine whether a requested limit or incomplete-coverage condition affected the result. Property teams can review geographic distribution on the map, data teams can compare counts between recurring runs, and AI agents can use the bounded summary to decide whether to continue, alert, or request human review. These artifacts are not replacement listing rows.

### Field Reference

#### Record envelope

- **record\_type** *(string, required)*: Stable family label; currently `property_listing`.
- **record\_id** *(string, required)*: Preferred deduplication and upsert key.
- **url** *(string, required)*: Public Trulia property URL.

#### Source context

- **source\_context** *(object, required)*: Provenance, seed, page position, language, country, and enrichment context.
- **source\_context.source\_id** *(string, required)*: Source identifier.
- **source\_context.source\_domain** *(string, required)*: Public source domain.
- **source\_context.source\_url** *(string, required)*: Public source URL associated with the record.
- **source\_context.seed\_type / seed\_value / search\_query** *(string, optional)*: Input origin and resolved search text when available.
- **source\_context.page\_number / position** *(integer, optional)*: Source page and row position.
- **source\_context.language / country** *(string, optional)*: Source language and country context.
- **source\_context.enrichment\_status** *(string, required)*: Final row classification such as `enriched` or `lightweight`.
- **source\_context.enrichment** *(object, optional)*: Requested, status, and completion markers for enrichment.

#### Entity

- **entity** *(object, required)*: Human-facing property identity.
- **entity.title** *(string, required)*: Listing title or display address.
- **entity.description** *(string, optional)*: Public property description, usually available after enrichment.
- **entity.external\_ids** *(object, optional)*: Typed home, property, or related source identifiers.

#### Listing

- **listing** *(object, optional)*: Listing identity, mode, status, dates, attribution, flags, and history.
- **listing.listing\_id** *(string, optional)*: Source listing identifier.
- **listing.listing\_type / listing.listing\_status / listing.status\_text** *(string, optional)*: Source classification and normalized/display status.
- **listing.deal\_type** *(string, optional)*: Transaction mode such as sale, rent, or sold context.
- **listing.posted\_at / listing.updated\_at** *(string, optional)*: Source-provided listing and update timestamps or display dates.
- **listing.status\_flags** *(object, optional)*: Boolean status signals such as active sale, active rent, recently sold, foreclosure, or off-market.
- **listing.source\_attribution** *(string, optional)*: Public attribution text.
- **listing.external\_ids** *(object, optional)*: Listing-related identifiers such as an available MLS ID. This does not imply official MLS access.
- **listing.history** *(object, optional)*: Available price, status, last-sold, or related source history.

#### Pricing

- **pricing** *(object, optional)*: Numeric, display, range, fee, and change values.
- **pricing.price** *(number, optional)*: Primary asking, rental, or sold price value.
- **pricing.price\_min / pricing.price\_max** *(number, optional)*: Source price range for range listings.
- **pricing.price\_text** *(string, optional)*: Display-ready price.
- **pricing.currency** *(string, optional)*: Currency code, such as `USD`.
- **pricing.price\_type** *(string, optional)*: Source price classification when available.
- **pricing.price\_details** *(object, optional)*: Additional structured price context.
- **pricing.callout\_price\_text / pricing.price\_per\_area\_text** *(string, optional)*: Source display labels.
- **pricing.price\_change** *(object, optional)*: Available structured price-change context.
- **pricing.fees** *(object, optional)*: Available rental, HOA, or other public listing fee details.

#### Location

- **location** *(object, optional)*: Address, geography, coordinates, neighborhood, and nearby-school context.
- **location.address / location.street\_address** *(string, optional)*: Full and street-level public address.
- **location.city / location.region / location.postal\_code / location.country** *(string, optional)*: Geographic components.
- **location.neighborhood** *(string, optional)*: Source neighborhood label.
- **location.latitude / location.longitude** *(number, optional)*: Coordinate pair used by the map when both values are valid.
- **location.nearby\_schools** *(array or object, optional)*: Source-provided school context; shape can vary by listing.

#### Property

- **property** *(object, optional)*: Classification, rooms, measurements, features, amenities, and tax history.
- **property.property\_id** *(string, optional)*: Source property identifier.
- **property.property\_type** *(string, optional)*: Source category such as `SINGLE_FAMILY_HOME` or `MULTI_FAMILY`.
- **property.bedrooms / property.bedrooms\_max** *(number, optional)*: Bedroom value or range.
- **property.bathrooms / property.bathrooms\_max** *(number, optional)*: Bathroom value or range; decimals can represent partial baths.
- **property.floor\_area / property.area\_unit** *(number and string, optional)*: Interior area and unit.
- **property.land\_area / property.land\_area\_unit** *(number and string, optional)*: Lot or land area and unit.
- **property.amenities** *(array of strings, optional)*: Deduplicated, scan-friendly amenity labels.
- **property.features** *(array of objects, optional)*: Structured source feature records with available group, category, name, and value.
- **property.measurement\_sources** *(object, optional)*: Original measurement display text retained alongside normalized values.
- **property.tax\_history** *(object, optional)*: Available public tax or assessment history.

#### Media and availability

- **media** *(object, optional)*: Image URLs and 3D/video signals.
- **media.main\_image\_url** *(string, optional)*: Best available preview image URL.
- **media.image\_urls** *(array of strings, optional)*: Deduplicated image gallery URLs.
- **media.photos** *(array of objects, optional)*: Structured photo records and available size variants.
- **media.has\_3d\_home / media.has\_video** *(boolean, optional)*: Source media-availability signals.
- **media.total\_photo\_count** *(integer, optional)*: Source-reported photo total.
- **availability** *(object, optional)*: Tour and open-house context.
- **availability.tour\_available** *(boolean, optional)*: Source tour-action signal.
- **availability.open\_houses** *(array of objects, optional)*: Available date and time windows.

#### Contacts and relationships

- **contact\_details** *(object, optional)*: Deduplicated public contact values available for the listing.
- **contact\_details.phones** *(array of strings, optional)*: Public phone strings.
- **contact\_details.websites** *(array of strings, optional)*: Public agent or agency websites.
- **contact\_details.contacts** *(array of objects, optional)*: Role-aware public contacts.
- **relationships** *(object, optional)*: Related public real estate parties and attribution.
- **relationships.agent / relationships.agency / relationships.developer** *(object, optional)*: Available identity and public contact values for related parties.
- **relationships.listing\_source** *(object, optional)*: Listing-source attribution and summary context.

#### Source-specific attributes

- **attributes** *(object, optional)*: Meaningful Trulia-specific values that do not belong in a stronger canonical group.
- **attributes.tags** *(array of objects, optional)*: Deduplicated source tags with available name and level.
- **attributes.trulia** *(object, optional)*: Compact provider and attribution-visibility context.

### Data Model Notes

- **Identity:** Use `record_id` for primary matching, deduplication, and upserts. Treat title or address matching as a secondary review method.
- **Provenance:** Use `url`, `source_context.source_url`, and seed fields to trace a row to its public source and input scope.
- **Grouped values:** Main user-facing values live in `entity`, `listing`, `pricing`, `location`, `property`, `media`, `availability`, `relationships`, and `contact_details`.
- **Point-in-time values:** Prices, listing status, availability, descriptions, contacts, and media reflect what was publicly visible at collection time.
- **Optionality:** Null-check or presence-check nested groups; availability varies by property, listing mode, region, source visibility, and enrichment result.
- **Repeated runs:** Compare rows by `record_id` and retain Apify run metadata or your own observation timestamp alongside each snapshot.

### Data Quality, Guarantees, And Handling

- **Structured records:** Results are normalized into predictable JSON objects for downstream use.
- **Field preservation:** Meaningful schema-supported listing and property values are retained in stable public fields or grouped objects when exposed; optional source values may still be absent for a specific record.
- **Best-effort extraction:** Fields may vary by region, availability, listing type, source visibility, public-page variation, or source-side changes.
- **Optional fields:** Null-check optional properties in applications, imports, transformations, and dashboards.
- **Deduplication:** Use `record_id` as the strongest documented stable key, with `url` and nested identifiers as supporting context.
- **Freshness:** Results reflect publicly available data at run time; verify material property facts before operational decisions.
- **Repeated runs:** Use `record_id` when syncing into warehouses, CRMs, search indexes, vector stores, or monitoring systems.
- **Schema awareness:** Depend on documented fields and handle temporarily missing optional fields gracefully.
- **Run receipts:** Use summary and map artifacts to audit counts, coverage, skipped outcomes, enrichment, and map readiness without treating them as dataset records.

### Tips For Best Results

- Start with a `limit` of 5 or 20 to validate the output before scaling.
- Use one geography and one `deal_type` per run for cleaner recurring comparisons.
- Match `deal_type` to the supplied Trulia market URL.
- Enable `enrich_data` only when richer details justify the additional run work.
- Enable `maximize_coverage` for broad, high-volume matching searches where deeper collection matters more than shorter exploratory runtime.
- Schedule identical inputs for monitoring and upsert by `record_id`.
- Save the exact input configuration and run ID used for each recurring workflow.
- Review `RUN-SUMMARY`, the HTML report, the map, and a small record sample before production imports.

### How to Run on Apify

1. Open Trulia Property Scraper in Apify Console.
2. Add one supported Trulia market URL or enter a location, then choose `buy`, `rent`, or `sold`.
3. Configure enrichment, coverage, optional connector delivery, and the maximum result count.
4. Click **Start** and wait for the run to finish.
5. Open the dataset, summary, report, and map to inspect the result.
6. Download records in JSON, CSV, Excel, or another Apify-supported dataset format.

### Agentic And API-First Usage

Trulia Property Scraper can serve as a structured public property-data acquisition step inside a larger automated workflow. Its schema, stable identifier, run receipt, and grouped JSON make it suitable for agents that must define a scope, collect records, verify completion, and hand results to another system.

1. Generate or select an input using only the documented schema.
2. Run the actor manually, on a schedule, or through Apify platform automation.
3. Wait for completion and read the dataset records.
4. Validate required and optional fields against the Field Reference.
5. Read the run summary and map to verify counts, coverage state, limit behavior, skipped outcomes, coordinates, and export readiness.
6. Upsert records into the downstream system using `record_id`.
7. Trigger market analysis, alerts, BI refreshes, search or vector indexing, enrichment, or human verification.

For agentic use, start with small validation runs and keep prompts grounded in supported inputs. Provide downstream AI steps with the Field Reference, `record_id` guidance, one representative record, and the bounded run summary. Treat optional fields as nullable instead of asking an agent to infer unavailable values. Store the Apify run ID, input configuration, and export metadata outside the listing record when building an audit trail. When context is limited, systems such as Claude, Codex, internal copilots, and property workflow agents usually need the input schema, field reference, idempotency key, and one example rather than the entire page.

### Scheduling & Automation

#### Scheduling

**Automated Data Collection**

Schedule recurring runs to maintain point-in-time listing snapshots for dashboards, alerts, and change detection.

- Navigate to **Schedules** in Apify Console.
- Create a daily, weekly, or custom-cron schedule.
- Configure and save the input parameters.
- Enable notifications for run completion.
- Add webhooks when another system should process completed runs.

#### Integration Options

- **BI dashboards:** Monitor asking prices, status, property mix, enrichment, and geographic coverage over time.
- **Warehouses and ETL:** Load grouped JSON into historical listing tables and transformation pipelines.
- **CRM enrichment:** Sync public property, listing, agent, agency, and available contact context into operational records.
- **Webhooks and alerts:** Trigger validation, ingestion, Slack, email, or review workflows after completion.
- **Google Sheets or Airtable:** Review smaller exports, annotate listing segments, and coordinate lightweight operations.
- **Search and vector indexes:** Build structured or semantic property discovery for internal applications and agent retrieval.
- **MCP connectors:** Authorize a supported connector in Apify and select it in `mcpConnectors` to receive the compact listing-run summary and available dataset, report, and map links.

### Export Formats And Downstream Use

Apify datasets can be downloaded or consumed by downstream systems without changing the actor input.

- **JSON:** Best for APIs, applications, AI agents, nested records, and data pipelines.
- **CSV or Excel:** Useful for stakeholder review and lightweight analysis; nested groups may require flattening.
- **API access:** Supports automated ingestion into internal systems and recurring workflows.
- **BI and warehouses:** Supports reporting, historical analysis, market snapshots, and monitoring.
- **Search or vector indexes:** Supports structured discovery, semantic search, retrieval workflows, and agent context.

### Downstream Pipeline Guide

- **Idempotency:** Upsert by `record_id`; do not use title or position as the primary key.
- **Null handling:** Treat every field outside the required envelope as nullable or potentially absent.
- **Type handling:** Preserve numeric prices and areas, booleans, arrays, and nested objects in JSON-first systems.
- **Flattening:** Flatten selected nested paths deliberately for CSV or Excel, and retain the original JSON export for fidelity.
- **Partitioning:** Store observation date, run ID, input geography, `deal_type`, and workflow name alongside records.
- **Change detection:** Compare repeated rows by `record_id` and selected fields such as `pricing.price`, `listing.listing_status`, `listing.updated_at`, media counts, or availability.
- **Quality checks:** Monitor saved count, duplicate count, required identifiers, price/status fill rates, enrichment status, and coordinate coverage.
- **Human review:** Route missing critical values, unusual prices, changed status, or important segments into a review queue.
- **Retention:** Choose separate retention periods for raw JSON snapshots and normalized warehouse tables based on operational needs.

### Performance And Coverage Expectations

Example metrics from a saved validation artifact are provided as evidence, not as a runtime guarantee.

| Run type | Example scope | Listings | Duration | Coverage notes |
| --- | --- | ---: | ---: | --- |
| Enriched URL validation | Los Angeles buy-market URL, `limit: 5`, enrichment enabled | 5 | 3 seconds | 5 enriched, 5 mapped, 0 duplicates, 0 warnings; deeper coverage disabled |

Execution time varies with result volume, target availability, response size, enrichment depth, coordinate and map preparation, and how much information each listing exposes. Highly focused runs can finish faster, while broad discovery, `maximize_coverage`, enrichment, or detail-rich records may take longer. Coverage mode prioritizes deeper retrieval within the selected criteria and can trade speed for more matching records. The saved example should not be extrapolated to larger markets or treated as a completeness promise.

### Limitations

- Results depend on what Trulia publicly exposes at run time.
- Optional descriptions, history, schools, media, contacts, agents, agencies, fees, and availability may be absent on sparse records.
- URL mode supports market-search pages, not individual property-detail pages as seeds.
- Broad or coverage-aware searches can take longer and may still be constrained by the requested limit or public result availability.
- Regional, listing-status, visibility, and source-side presentation differences can change fields and visible results.
- Prices, descriptions, contacts, status, and availability are point-in-time public signals and should be independently verified before operational decisions.
- The actor provides structured public real estate information, not legal, financial, investment, valuation, appraisal, ownership, or brokerage advice.

### Troubleshooting

- **No results returned:** Check location spelling, ensure the URL is a supported Trulia market-search page, match `deal_type` to the intended market, and confirm public matches exist.
- **Fewer results than expected:** Raise `limit`, consider `maximize_coverage` for broad markets, or verify that enough matching public listings are available.
- **Some fields are empty:** Optional fields depend on the listing and whether enrichment exposes additional public detail.
- **Duplicate-looking records:** Compare `record_id`; similar addresses or titles can still represent distinct source records.
- **Run takes longer than expected:** Lower `limit`, disable enrichment for validation, or split broad work into separate geographic or deal-type segments.
- **Output changed:** Compare the current sample with the Field Reference and include a small redacted record when requesting support.
- **Downstream import failed:** Check JSON validity, nullable fields, nested objects, arrays, and whether the destination expects flattened columns.

### FAQ

#### What data does this actor collect?

Public Trulia property listings with identity, pricing, status, location, property characteristics, media, availability, attribution, and optional enriched history or contact context.

#### Which search inputs are supported?

Use one supported Trulia market-search URL or a location-based search, plus `deal_type` set to `buy`, `rent`, or `sold`. The public input does not expose separate price, bedroom, bathroom, property-type, or keyword filters.

#### Why did I receive fewer results than my limit?

`limit` is a maximum, not a guaranteed count. The selected public market may expose fewer matching listings, and source availability can change.

#### What does `maximize_coverage` do?

It collects deeper within the same selected geography, listing mode, and criteria when a broad search exposes more matching listings than are normally visible. It does not relax the scope and still respects `limit`.

#### What does enrichment add?

When available, enrichment adds fuller descriptions, galleries, structured features, history, attribution, and public agent, agency, or contact context. Individual rows can remain lightweight if those details are unavailable.

#### Where are the summary and map?

Open the run's Output or key-value-store links for `RUN-SUMMARY`, `RUN-SUMMARY.html`, and `results-map`.

#### How should I choose a first limit?

Start with 5 or 20 records, inspect the schema and optional-field fill, then increase the limit for production work.

#### How do I avoid duplicates across runs?

Upsert by `record_id` and retain a run date or observation timestamp in your downstream system.

#### Can I schedule and automate the actor?

Yes. Use Apify schedules, webhooks, API access, exports, or supported MCP summary delivery.

#### Can I export CSV, Excel, or JSON?

Yes. JSON preserves the nested contract best; CSV and Excel are useful when nested groups are flattened deliberately.

#### Does the actor provide private, official MLS, ownership, or appraisal data?

No. It collects publicly visible Trulia listing information and does not provide private records, verified ownership, official MLS access, appraisal-grade valuation, or professional advice.

### Compliance & Ethics

#### Responsible Data Collection

This actor collects publicly available property listing information from Trulia for legitimate business purposes, including real estate research and market analysis, operational listing monitoring, and data enrichment or reporting workflows. Users are responsible for ensuring that their collection, storage, and use comply with applicable requirements. This section is informational and not legal advice.

#### Best Practices

- Use collected data in accordance with applicable laws, regulations, and Trulia's terms.
- Respect individual privacy and personal information.
- Use data responsibly and avoid disruptive or excessive collection.
- Do not use this actor for spamming, harassment, discrimination, unlawful housing practices, or other harmful purposes.
- Follow relevant data protection, fair housing, consumer protection, and sector-specific requirements.
- Review retention, access-control, and data-sharing policies before operationalizing the dataset.

### Support

Use the Issues tab on the actor page when you need help. Include the redacted input, Apify run ID, expected behavior, actual behavior, and an optional small output sample. For export or pipeline problems, also include the destination system or export format and the field or nested group that failed. No service-level response commitment is implied.

# Actor input Schema

## `location` (type: `string`):

Enter a Trulia-supported location such as Austin, TX; 75001; Brooklyn, NY; or Los Angeles, CA. Use one focused market per run for cleaner comparisons, recurring monitoring, dashboard refreshes, and downstream deduplication.

## `deal_type` (type: `string`):

Choose sale listings, rental listings, or recently sold properties. Query-based runs use this mode with the location above. URL-based runs should select the mode that matches the supplied Trulia search page.

## `min_price` (type: `integer`):

Only include listings at or above this price.

## `max_price` (type: `integer`):

Only include listings at or below this price.

## `min_bedroom` (type: `string`):

Choose the minimum number of bedrooms.

## `min_bathroom` (type: `string`):

Choose the minimum number of bathrooms.

## `property_type` (type: `array`):

Select one or more property categories. Leave empty to include every category.

## `seller_type` (type: `array`):

Choose agent-listed properties, owner-listed properties, or both.

## `listing_type` (type: `array`):

Limit results to selected special listing categories.

## `listing_status` (type: `array`):

Apply recency and contract-status filters to the search.

## `min_building_year` (type: `integer`):

Only include properties built in or after this year.

## `max_building_year` (type: `integer`):

Only include properties built in or before this year.

## `min_floor_area` (type: `integer`):

Only include properties at or above this interior floor area.

## `max_floor_area` (type: `integer`):

Only include properties at or below this interior floor area.

## `keyword` (type: `string`):

Match a word or phrase in the listing, such as pool, waterfront, or fixer upper.

## `max_hoa_fee` (type: `integer`):

Only include listings with an HOA fee at or below this amount.

## `open_house_only` (type: `boolean`):

Only include listings with an upcoming open house.

## `3d_tour_only` (type: `boolean`):

Only include listings that advertise a virtual or 3D tour.

## `exclude_55_plus_communities` (type: `boolean`):

Exclude listings in age-restricted 55+ communities.

## `aircon_only` (type: `boolean`):

Only include listings that advertise air conditioning.

## `mls_id` (type: `string`):

Find a listing by its exact MLS identifier.

## `url` (type: `array`):

Paste a supported Trulia search URL, such as https://www.trulia.com/CA/Los\_Angeles/ or a matching Trulia for-sale, rental, or sold-results URL. Select the corresponding listing mode below so the collected records match the intended sale, rent, or sold market.

## `enrich_data` (type: `boolean`):

Keep this enabled to add fuller descriptions, photo galleries, property features and amenities, available price or tax history, and available agent or agency contact details. Turn it off for faster validation or monitoring runs when lightweight search-result fields are sufficient.

## `maximize_coverage` (type: `boolean`):

Enable this for large exports or market-wide analysis where the maximum result count is at least 950, or where no maximum is supplied. Leave it disabled for faster exploratory runs, scheduled samples, and bounded validation work.

## `limit` (type: `integer`):

Choose the maximum number of records to save in this run. Start with a small value such as 5 or 20 to validate the grouped dataset, then increase it for production ingestion. Leave empty to use the actor's standard bounded run behavior; combining an empty limit with maximum coverage can produce a substantially larger run.

## `mcpConnectors` (type: `array`):

Choose user-authorized MCP connectors for optional post-run delivery of a compact run summary with dataset, summary, report, and map links when Apify provides them. Leave empty to only save listings to the Apify dataset and key-value store.

## Actor input object example

```json
{
  "location": "Los Angeles",
  "deal_type": "buy",
  "property_type": [],
  "seller_type": [],
  "listing_type": [],
  "listing_status": [],
  "open_house_only": false,
  "3d_tour_only": false,
  "exclude_55_plus_communities": false,
  "aircon_only": false,
  "enrich_data": true,
  "maximize_coverage": true,
  "limit": 100,
  "mcpConnectors": []
}
```

# Actor output Schema

## `results` (type: `string`):

Grouped Trulia property listings saved to the default dataset for review, export, BI, CRM, ETL, alerts, and AI-agent workflows.

## `runSummaryJson` (type: `string`):

Machine-readable end-of-run summary with saved totals, public input scope, coverage, enrichment, location, pricing, property, media, availability, warnings, and artifact keys.

## `runSummaryHtml` (type: `string`):

Human-readable report rendering the same listing totals and breakdowns as RUN-SUMMARY.

## `resultsMap` (type: `string`):

Standalone clustered map for saved listings with valid coordinates. Runs without valid coordinates still provide a zero-location map report.

# 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 = {
    "location": "Los Angeles",
    "limit": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("fatihtahta/trulia-property-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 = {
    "location": "Los Angeles",
    "limit": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("fatihtahta/trulia-property-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "location": "Los Angeles",
  "limit": 100
}' |
apify call fatihtahta/trulia-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fatihtahta/trulia-property-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Trulia Property Scraper with Contacts & Features",
        "description": "Extract Trulia property listings with prices, coordinates, photos, full descriptions, amenities, history, and available agent contacts. Use enrichment and coverage mode for comps, market research, inventory monitoring, CRM, BI, ETL, and AI workflows.",
        "version": "0.1",
        "x-build-id": "VTb3OzAZcDg3jIUdK"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fatihtahta~trulia-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fatihtahta-trulia-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/fatihtahta~trulia-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fatihtahta-trulia-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/fatihtahta~trulia-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fatihtahta-trulia-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "location": {
                        "title": "Set a Location (city, state, ZIP code, neighborhood, or market)",
                        "type": "string",
                        "description": "Enter a Trulia-supported location such as Austin, TX; 75001; Brooklyn, NY; or Los Angeles, CA. Use one focused market per run for cleaner comparisons, recurring monitoring, dashboard refreshes, and downstream deduplication."
                    },
                    "deal_type": {
                        "title": "Choose the Property Listing Mode",
                        "enum": [
                            "buy",
                            "rent",
                            "sold"
                        ],
                        "type": "string",
                        "description": "Choose sale listings, rental listings, or recently sold properties. Query-based runs use this mode with the location above. URL-based runs should select the mode that matches the supplied Trulia search page.",
                        "default": "buy"
                    },
                    "min_price": {
                        "title": "Minimum Price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings at or above this price."
                    },
                    "max_price": {
                        "title": "Maximum Price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings at or below this price."
                    },
                    "min_bedroom": {
                        "title": "Minimum Bedrooms",
                        "enum": [
                            "1+",
                            "2+",
                            "3+",
                            "4+",
                            "5+"
                        ],
                        "type": "string",
                        "description": "Choose the minimum number of bedrooms."
                    },
                    "min_bathroom": {
                        "title": "Minimum Bathrooms",
                        "enum": [
                            "1+",
                            "2+",
                            "3+",
                            "4+",
                            "5+"
                        ],
                        "type": "string",
                        "description": "Choose the minimum number of bathrooms."
                    },
                    "property_type": {
                        "title": "Property Types",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select one or more property categories. Leave empty to include every category.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "house",
                                "condo",
                                "townhome",
                                "multi_family",
                                "land",
                                "mobile_manufactured",
                                "other"
                            ],
                            "enumTitles": [
                                "House",
                                "Condo",
                                "Townhome",
                                "Multi-Family",
                                "Land",
                                "Mobile/Manufactured",
                                "Other"
                            ]
                        },
                        "default": []
                    },
                    "seller_type": {
                        "title": "Seller Types",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Choose agent-listed properties, owner-listed properties, or both.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "agent_listed",
                                "for_sale_by_owner"
                            ],
                            "enumTitles": [
                                "Agent listed",
                                "For Sale By Owner"
                            ]
                        },
                        "default": []
                    },
                    "listing_type": {
                        "title": "Listing Types",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Limit results to selected special listing categories.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "new_construction",
                                "foreclosures",
                                "coming_soon"
                            ],
                            "enumTitles": [
                                "New Construction",
                                "Foreclosures",
                                "Coming Soon"
                            ]
                        },
                        "default": []
                    },
                    "listing_status": {
                        "title": "Listing Status Filters",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Apply recency and contract-status filters to the search.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "new_listings_past_week",
                                "price_reduced_past_week",
                                "include_accepting_backup_offers",
                                "include_pending_under_contract"
                            ],
                            "enumTitles": [
                                "New Listings (Past Week)",
                                "Price Reduced (Past Week)",
                                "Include Accepting Backup Offers",
                                "Include Pending & Under Contract"
                            ]
                        },
                        "default": []
                    },
                    "min_building_year": {
                        "title": "Minimum Year Built",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include properties built in or after this year."
                    },
                    "max_building_year": {
                        "title": "Maximum Year Built",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include properties built in or before this year."
                    },
                    "min_floor_area": {
                        "title": "Minimum Floor Area (sq ft)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include properties at or above this interior floor area."
                    },
                    "max_floor_area": {
                        "title": "Maximum Floor Area (sq ft)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include properties at or below this interior floor area."
                    },
                    "keyword": {
                        "title": "Keyword",
                        "type": "string",
                        "description": "Match a word or phrase in the listing, such as pool, waterfront, or fixer upper."
                    },
                    "max_hoa_fee": {
                        "title": "Maximum HOA Fee",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only include listings with an HOA fee at or below this amount."
                    },
                    "open_house_only": {
                        "title": "Open House Only",
                        "type": "boolean",
                        "description": "Only include listings with an upcoming open house.",
                        "default": false
                    },
                    "3d_tour_only": {
                        "title": "3D Tour Only",
                        "type": "boolean",
                        "description": "Only include listings that advertise a virtual or 3D tour.",
                        "default": false
                    },
                    "exclude_55_plus_communities": {
                        "title": "Exclude 55+ Communities",
                        "type": "boolean",
                        "description": "Exclude listings in age-restricted 55+ communities.",
                        "default": false
                    },
                    "aircon_only": {
                        "title": "Air Conditioning Only",
                        "type": "boolean",
                        "description": "Only include listings that advertise air conditioning.",
                        "default": false
                    },
                    "mls_id": {
                        "title": "MLS ID",
                        "type": "string",
                        "description": "Find a listing by its exact MLS identifier."
                    },
                    "url": {
                        "title": "Add a Trulia City or Market Search URL",
                        "type": "array",
                        "description": "Paste a supported Trulia search URL, such as https://www.trulia.com/CA/Los_Angeles/ or a matching Trulia for-sale, rental, or sold-results URL. Select the corresponding listing mode below so the collected records match the intended sale, rent, or sold market.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "enrich_data": {
                        "title": "Add Richer Property, Media, History, and Contact Details",
                        "type": "boolean",
                        "description": "Keep this enabled to add fuller descriptions, photo galleries, property features and amenities, available price or tax history, and available agent or agency contact details. Turn it off for faster validation or monitoring runs when lightweight search-result fields are sufficient.",
                        "default": true
                    },
                    "maximize_coverage": {
                        "title": "Collect More Matching Listings Beyond the Standard Result Window",
                        "type": "boolean",
                        "description": "Enable this for large exports or market-wide analysis where the maximum result count is at least 950, or where no maximum is supplied. Leave it disabled for faster exploratory runs, scheduled samples, and bounded validation work.",
                        "default": true
                    },
                    "limit": {
                        "title": "Set the Maximum Number of Property Listings to Save",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Choose the maximum number of records to save in this run. Start with a small value such as 5 or 20 to validate the grouped dataset, then increase it for production ingestion. Leave empty to use the actor's standard bounded run behavior; combining an empty limit with maximum coverage can produce a substantially larger run."
                    },
                    "mcpConnectors": {
                        "title": "MCP Delivery Connectors",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Choose user-authorized MCP connectors for optional post-run delivery of a compact run summary with dataset, summary, report, and map links when Apify provides them. Leave empty to only save listings to the Apify dataset and key-value store.",
                        "default": []
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
