# ApartmentFinder Scraper with Contacts & Features (`fatihtahta/apartmentfinder-property-scraper`) Actor

Extract ApartmentFinder.com rental listings with asking rents, addresses, coordinates, photos, descriptions, contacts, amenities, floor plans, and unit availability. Use enrichment and coverage mode for market research, inventory monitoring, CRM enrichment, BI, and AI workflows.

- **URL**: https://apify.com/fatihtahta/apartmentfinder-property-scraper.md
- **Developed by:** [Fatih Tahta](https://apify.com/fatihtahta) (community)
- **Categories:** Real estate, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 80.0% 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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Apartment Finder Property Scraper

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

### Overview

Apartment Finder Property Scraper collects public rental listings with listing identity, asking-rent ranges, addresses, coordinates, property classifications, media, contact details, promotions, and unit availability when present. [Apartment Finder](https://www.apartmentfinder.com/) is a public rental-search marketplace whose listing data is useful for property discovery, market monitoring, inventory research, and operational analysis. The actor turns location-driven searches and supported filters into repeatable, structured collection jobs. Optional enrichment adds property descriptions, ratings, additional images, floor plans, unit rents, bedrooms, bathrooms, floor areas, availability dates, and amenities when those details are published. Results are delivered as grouped JSON records suitable for review, export, ETL pipelines, BI dashboards, search indexes, AI-agent workflows, and downstream APIs. Run summaries and an interactive map provide operational context alongside the primary dataset. The actor is designed for recurring public-data workflows while preserving the source-dependent and point-in-time nature of rental listings.

### What Makes This Actor Different

- **Pipeline-ready listing records:** Each record uses documented nested groups for source context, identity, listing classification, pricing, location, property attributes, media, contacts, availability, metrics, and source-specific attributes.
- **Stable identity for repeated runs:** `record_id` is the recommended idempotency key, with `listing.listing_id`, `entity.external_ids.apartmentfinder_listing_id`, and `url` available as supporting identifiers.
- **Coverage-aware collection:** `maximize_coverage` can collect deeper within the same selected criteria when a broad search reports more matching listings than are normally visible. It does not loosen the configured filters and still respects `limit`.
- **Optional detail enrichment:** `enrich_data` controls whether standard search records are supplemented with descriptions, ratings, additional images, property type, postal code, floor plans, unit availability, and amenity detail when available.
- **Operational run receipts:** Every successful run writes machine-readable `RUN-SUMMARY` JSON and a human-readable `RUN-SUMMARY.html` report with counts, timing, enrichment, location, coordinate, asking-rent, property-type, and artifact information.
- **Map-ready review:** Records expose numeric latitude and longitude when available, and `results-map` provides an interactive, deduplication-aware view of saved listing locations. A zero-marker report is still produced when a run has no usable coordinates.
- **Agentic handoff:** Optional user-authorized MCP connectors receive a concise run summary and public Apify output links when available; the full listing dataset remains in Apify unless a downstream workflow reads it separately.
- **Schema-aware field preservation:** Meaningful supported values are organized into stable public fields rather than a large flat record. Detail-dependent fields remain optional so downstream systems can distinguish absent source values from required identity and provenance.

### Who Should Use This Actor

- **Real estate investors and analysts:** Build scoped rental-market datasets for asking-rent comparisons, availability review, property-type segmentation, and location analysis.
- **Brokerages and property operations teams:** Monitor public inventory, unit availability, amenities, contact details, and listing status across selected markets.
- **Market research and analytics teams:** Produce repeatable geographic snapshots for dashboards, reports, alerting, and historical comparisons.
- **Proptech and data engineering teams:** Ingest grouped property-listing JSON into warehouses, CRMs, search systems, enrichment pipelines, and internal products.
- **AI agents and workflow automations:** Generate supported inputs, run bounded collection jobs, inspect run receipts, and route normalized listings into research or review steps.
- **Lead and CRM enrichment teams:** Add current public rental attributes, source links, contact numbers, pricing, and location context to existing property records.
- **Monitoring and operations teams:** Schedule consistent runs and use saved counts, enrichment status, coordinate coverage, and artifacts to review completion.

### Common Use Cases

- **Market intelligence:** Monitor public rental supply, asking rents, availability, property types, amenities, and geographic distribution.
- **Comparable listing research:** Collect listings for a city, neighborhood, ZIP code, property type, bedroom count, or price band.
- **Filtered rental discovery:** Identify listings matching pet policies, specialty-housing categories, deal categories, amenities, or keywords.
- **Property catalog enrichment:** Populate internal listing directories with source IDs, URLs, addresses, coordinates, media, and grouped rental attributes.
- **Unit availability analysis:** Use enriched floor-plan and unit records to review bedrooms, bathrooms, floor area, displayed rent, availability dates, and amenities.
- **Recurring reporting:** Schedule market snapshots for BI dashboards, inventory reports, alerts, or stakeholder review.
- **Change monitoring:** Compare repeated runs by stable key to identify asking-rent, availability, status, media, or attribute changes in an internal system.
- **Agentic research workflows:** Let an authorized workflow collect a scoped dataset, evaluate its run summary, and hand off results for analysis or human review.

### Real-World Questions This Data Can Answer

- Which public rental listings match a target location, price band, property type, bedroom count, bathroom count, amenity set, or keyword?
- What asking-rent ranges are visible across selected cities, neighborhoods, or ZIP codes at run time?
- Which matching listings advertise rent specials, price drops, or value-focused categories?
- Which properties publish coordinates, contact numbers, images, virtual-tour signals, or richer unit availability?
- Which available units match specific bedroom, bathroom, floor-area, rent, or amenity requirements?
- How have public asking rents, availability, or listing attributes changed compared with a previous internal snapshot?
- Which records have enough structured detail for CRM enrichment, dashboarding, search indexing, or analyst review?
- How many records were saved, enriched, and mapped in a completed run?

### Quick Start

1. Add at least one supported location, such as a city, state, ZIP code, neighborhood, or market.
2. Add optional rent, property, room, pet, amenity, specialty-housing, deal, or keyword filters.
3. Set a small `limit`, such as 10, for the first validation run and choose whether to enable enrichment or maximum matching coverage.
4. Start the actor in Apify Console and inspect the first dataset records.
5. Review the run summary and interactive map, then increase the limit, schedule the run, export the dataset, or connect it to a downstream workflow.

### Input Parameters

The actor builds Apartment Finder rental searches from one or more locations and optional listing filters.

| Parameter | Type | Description | Default |
| --- | --- | --- | --- |
| `location` | Array of strings | One Apartment Finder-supported city, state, ZIP code, neighborhood, or market per line. Each location is searched independently. | – |
| `min_price` | Integer | Minimum monthly rent in USD. Allowed range: 0–15,000. | – |
| `max_price` | Integer | Maximum monthly rent in USD. Allowed range: 0–15,000; must be at least `min_price` when both are set. | – |
| `deals_discounts` | String | Optional promotion category: `price_drop`, `best_value`, or `rent_specials`. | – |
| `bedroom_count` | String | Minimum bedroom scope: `studio`, `1`, `2`, `3`, or `4_plus`. | – |
| `bathroom_count` | String | Minimum bathroom scope: `1`, `2`, or `3_plus`. | – |
| `property_type` | Array of strings | Property categories: `houses`, `townhouses`, and/or `condos`. Empty means no property-type restriction. | `[]` |
| `pets_allowed` | String | Pet-policy filter: `dogs_only`, `cats_only`, or `pet_friendly`. | – |
| `amenities` | Array of strings | Required amenities: `air_conditioning`, `balcony`, `dishwasher`, `elevator`, `fireplace`, `fitness_center`, `garage`, `gated`, `parking_available`, `swimming_pool`, `wheelchair_accessible`, `utilities_included`, `lofts`, `furnished`, `laundry_in_unit`, `laundry_hookups`, or `laundry_on_site`. | `[]` |
| `speciality_housing` | Array of strings | Specialty categories: `income_restricted`, `military`, `senior`, `short_term`, `student`, `cheap`, and/or `luxury`. | `[]` |
| `keyword` | String | Optional comma-separated listing keywords, up to 100 characters. | – |
| `maximize_coverage` | Boolean | Collects deeper within the selected criteria when broad searches exceed the normally visible result set. Can increase run time. | `true` |
| `enrich_data` | Boolean | Adds property-page details such as descriptions, ratings, images, unit availability, floor plans, and amenities when published. | `true` |
| `limit` | Integer | Maximum number of listings to save. Minimum: 1. Empty means continue through listings available for the selected scope. | – |
| `mcpConnectors` | Array of Apify MCP connectors | Optional user-authorized connectors for concise post-run summary delivery. The full listing dataset is not sent through this handoff. | `[]` |

### Choosing Inputs

Begin with a location because the public input contract is location-driven. Each line in `location` defines a separate market search; use separate runs when you want clean city-, neighborhood-, or ZIP-level comparisons and a combined run when you want one consolidated dataset.

Price, room, property-type, pet, amenity, specialty-housing, deal, and keyword fields narrow the matching dataset. Leave optional filters empty for broader discovery, then add them gradually to understand how each condition changes results. Use `limit` to bound cost and output size while validating a new configuration.

Keep `enrich_data` enabled when descriptions, ratings, additional media, postal codes, floor plans, unit rents, availability, or amenities matter. Disable it when standard listing identity, pricing, location, primary media, contact, and source attributes are sufficient.

Enable `maximize_coverage` for broad locations, high-volume segments, recurring market snapshots, or searches where the source reports more matching listings than are normally visible. It seeks more matches inside the same criteria and respects `limit`; disabling it is appropriate for faster exploratory runs when the first visible result set is sufficient.

### Input Recipes

- **Validation run:** Use one city or ZIP code, leave most filters empty, set `limit` to 10, and disable `maximize_coverage`. Inspect both lightweight and enriched variants before increasing scope.
- **Targeted apartment search:** Combine one location with `min_price`, `max_price`, `bedroom_count`, `bathroom_count`, selected `amenities`, and a conservative limit.
- **Pet-friendly property segment:** Use a location, `pets_allowed`, one or more `property_type` values, and optional parking or laundry amenities.
- **Broad market discovery:** Use a location with minimal filters and a bounded limit. Enable `maximize_coverage` when deeper matching retrieval matters more than the fastest first pass.
- **Recurring monitoring:** Reuse the same location, filters, enrichment setting, and limit on a schedule. Upsert by `record_id` and compare selected pricing, availability, and status fields.
- **Segmented analysis:** Run separate jobs by city, neighborhood, property type, bedroom band, specialty-housing category, or rent band so downstream comparisons retain an explicit segment boundary.

### Example Inputs

#### Scenario 1: Small validation run

```json
{
  "location": ["Los Angeles, CA"],
  "limit": 10,
  "enrich_data": false,
  "maximize_coverage": false,
  "property_type": []
}
````

#### Scenario 2: Targeted pet-friendly rental search

```json
{
  "location": ["Atlanta, GA"],
  "min_price": 1500,
  "max_price": 3200,
  "bedroom_count": "2",
  "pets_allowed": "pet_friendly",
  "amenities": ["parking_available", "laundry_in_unit"],
  "limit": 100
}
```

#### Scenario 3: Enriched market-monitoring run

```json
{
  "location": ["Austin, TX"],
  "property_type": ["houses", "townhouses"],
  "deals_discounts": "rent_specials",
  "keyword": "transit, renovated",
  "maximize_coverage": true,
  "enrich_data": true,
  "limit": 500
}
```

### 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 contract contains one record family: `property_listing`. Optional detail groups vary by listing and enrichment status; they are documented separately from required record-envelope fields below.

#### Record envelope and stable identifiers

Every normal record includes `record_type`, `source_context`, and `entity`. The recommended idempotency key is `record_id`, which normally combines the source prefix and listing ID, as in `apartmentfinder:sample123`. Use it for upserts and deduplication; `listing.listing_id`, `entity.external_ids.apartmentfinder_listing_id`, and `url` provide supporting identity and audit links.

`source_context` identifies the source, search URL, page, position, and enrichment state. Stable identifiers make records easier to merge, deduplicate, sync, and compare across recurring runs without relying on mutable display names, rents, or addresses.

#### Example: property listing record

The following synthetic example follows the observed enriched record structure while avoiding a real address or phone number.

```json
{
  "record_type": "property_listing",
  "record_id": "apartmentfinder:sample123",
  "url": "https://www.apartmentfinder.com/California/Los-Angeles-Apartments/Sample-Residences-Apartments-sample123",
  "source_context": {
    "source_id": "apartmentfinder_property_scraper",
    "source_domain": "apartmentfinder.com",
    "source_url": "https://www.apartmentfinder.com/California/Los-Angeles-Apartments",
    "page_number": 1,
    "position": 1,
    "enrichment_status": "enriched"
  },
  "entity": {
    "name": "Sample Residences",
    "description": "Sample apartment community with studio, one-bedroom, and two-bedroom floor plans.",
    "url": "https://www.apartmentfinder.com/California/Los-Angeles-Apartments/Sample-Residences-Apartments-sample123",
    "external_ids": {
      "apartmentfinder_listing_id": "sample123"
    },
    "status": "available"
  },
  "listing": {
    "listing_id": "sample123",
    "transaction_type": "rent",
    "listing_status": "available"
  },
  "pricing": {
    "currency": "USD",
    "price_text": "$2,450 - $4,200",
    "min_price": 2450,
    "max_price": 4200,
    "bedroom_prices": [
      {
        "bedroom_label": "1 BED",
        "price_text": "$2,450+"
      },
      {
        "bedroom_label": "2 BEDS",
        "price_text": "$3,250+"
      }
    ]
  },
  "location": {
    "address": "100 Example Avenue",
    "city": "Los Angeles",
    "region": "CA",
    "postal_code": "90000",
    "country": "US",
    "latitude": 34.0522,
    "longitude": -118.2437
  },
  "property": {
    "property_type": "Apartment"
  },
  "media": {
    "main_image_url": "https://image1.apartmentfinder.com/sample/sample-residences.jpg",
    "image_urls": [
      "https://image1.apartmentfinder.com/sample/sample-residences-1.jpg",
      "https://image1.apartmentfinder.com/sample/sample-residences-2.jpg"
    ],
    "virtual_tour_available": true
  },
  "metrics": {
    "rating": 4.5
  },
  "contact_details": {
    "phones": ["(555) 010-0123"]
  },
  "availability": {
    "units": [
      {
        "unit_id": "sample-unit-1",
        "rental_type": 1,
        "model_id": "sample-model-a",
        "model_name": "Plan A",
        "unit_number": "Unit 210",
        "bedrooms": 1,
        "bedrooms_text": "1 Bedroom",
        "bathrooms": 1,
        "bathrooms_text": "1 Bathroom",
        "floor_area": 720,
        "floor_area_text": "720 Sq Ft",
        "area_unit": "sq ft",
        "available_from": "Available Now",
        "pricing": {
          "currency": "USD",
          "price_text": "$2,450",
          "min_price": 2450,
          "max_price": 2450
        },
        "is_new": true,
        "amenities": ["Air Conditioning", "Dishwasher", "Balcony"],
        "amenity_groups": [
          {
            "name": "Kitchen",
            "amenities": ["Dishwasher"]
          },
          {
            "name": "Outdoor Space",
            "amenities": ["Balcony"]
          }
        ]
      }
    ]
  },
  "attributes": {
    "promotions": ["Sample rent special"],
    "apartmentfinder": {
      "listing_tier": "Featured"
    }
  }
}
```

#### Run Summary, Map, and Artifacts

Run artifacts are stored in the default key-value store and are linked from the actor output page. They are not dataset rows.

| Artifact | Purpose |
| --- | --- |
| `RUN-SUMMARY` | Machine-readable JSON receipt with start/finish times, duration, sanitized public input, requested limit, saved record-family counts, enrichment totals, searched locations, city/region/country breakdowns, coordinate coverage, currencies, asking-rent range, property-type counts, representative listings, and artifact keys. |
| `RUN-SUMMARY.html` | Human-readable report with headline totals and representative listings for operator review. |
| `results-map` | Interactive map of records with valid coordinates, including inspected, mapped, skipped-coordinate, and deduplicated-marker counts. |
| `RUN-SUMMARY-ERROR` | Best-effort diagnostic JSON written only when final summary generation cannot be completed after listings were saved. |

Use these artifacts as a run receipt: verify the saved count, compare recurring runs, inspect enrichment and coordinate coverage, review location distribution, attach a summary to an operational ticket, or decide whether a different input scope is needed. Coverage mode is recorded in the sanitized input; saved totals and requested limit show the resulting bounded output. The dataset remains authoritative even if a secondary artifact cannot be produced.

### Field Reference

#### Record envelope

- **record\_type** *(string, required)*: Record family; currently `property_listing`.
- **record\_id** *(string or null, optional)*: Recommended stable deduplication and upsert key.
- **url** *(string or null, optional)*: Canonical public Apartment Finder listing URL.

#### Source context

- **source\_context** *(object, required)*: Public provenance and collection context.
- **source\_context.source\_id** *(string, required)*: Stable source identifier.
- **source\_context.source\_domain** *(string, required)*: Public source domain.
- **source\_context.source\_url** *(string, required)*: Search URL that produced the listing.
- **source\_context.page\_number** *(integer, required)*: One-based result-page number.
- **source\_context.position** *(integer, required)*: One-based listing position within the page.
- **source\_context.enrichment\_status** *(string, required)*: `lightweight` or `enriched`.

#### Entity and listing

- **entity** *(object, required)*: Listing display identity and public description.
- **entity.name** *(string, optional)*: Property or community display name.
- **entity.description** *(string, optional)*: Enriched public property description.
- **entity.url** *(string, optional)*: Listing URL repeated within the identity group for convenient nested consumption.
- **entity.external\_ids** *(object, optional)*: Source-specific external identifiers.
- **entity.external\_ids.apartmentfinder\_listing\_id** *(string or null, optional)*: Apartment Finder listing ID.
- **entity.status** *(string, optional)*: Public entity status, such as `available`.
- **listing** *(object, optional)*: Listing classification fields.
- **listing.listing\_id** *(string or null, optional)*: Source listing ID.
- **listing.transaction\_type** *(string, optional)*: Transaction mode; observed records use `rent`.
- **listing.listing\_status** *(string, optional)*: Point-in-time public listing status.

#### Pricing

- **pricing** *(object, optional)*: Displayed asking-rent information.
- **pricing.currency** *(string, optional)*: Currency code; observed US listings use `USD`.
- **pricing.price\_text** *(string, optional)*: Source-displayed rent or rent range.
- **pricing.min\_price / pricing.max\_price** *(number, optional)*: Normalized lower and upper monthly asking-rent values when parseable.
- **pricing.bedroom\_prices** *(array of objects, optional)*: Bedroom-level rent labels in source order.
- **pricing.bedroom\_prices\[].bedroom\_label** *(string, optional)*: Displayed bedroom category.
- **pricing.bedroom\_prices\[].price\_text** *(string, optional)*: Displayed rent for that bedroom category.

#### Location

- **location** *(object, optional)*: Public address and map coordinates.
- **location.address** *(string, optional)*: Displayed street or property address.
- **location.city** *(string, optional)*: City.
- **location.region** *(string, optional)*: State or regional code.
- **location.postal\_code** *(string, optional)*: Postal code; preserve as text.
- **location.country** *(string, optional)*: Country code or label.
- **location.latitude / location.longitude** *(number, optional)*: Numeric coordinates used by the interactive map when valid.

#### Property, media, and metrics

- **property** *(object, optional)*: Enriched property attributes.
- **property.property\_type** *(string, optional)*: Source-provided property classification.
- **media** *(object, optional)*: Public listing media.
- **media.main\_image\_url** *(string, optional)*: Primary image URL.
- **media.image\_urls** *(array of strings, optional)*: Additional image URLs in source order.
- **media.virtual\_tour\_available** *(boolean, optional)*: Whether the listing advertises a virtual-tour option.
- **metrics** *(object, optional)*: Stable numeric source metrics.
- **metrics.rating** *(number, optional)*: Source-provided listing rating when available.

#### Contact details

- **contact\_details** *(object, optional)*: Public listing contact fields.
- **contact\_details.phones** *(array of strings, optional)*: Public phone numbers associated with the listing.

#### Unit availability

- **availability** *(object, optional)*: Enriched unit and floor-plan availability.
- **availability.units** *(array of objects, optional)*: Available or represented units in source order; an absent array means no enriched unit detail was saved.
- **availability.units\[].unit\_id** *(string, optional)*: Stable source unit or rental identifier.
- **availability.units\[].rental\_type** *(string or number, optional)*: Source rental-type value.
- **availability.units\[].model\_id / model\_name** *(string, optional)*: Floor-plan model identity and name.
- **availability.units\[].unit\_number** *(string, optional)*: Displayed unit number.
- **availability.units\[].bedrooms / bathrooms** *(number, optional)*: Normalized room counts.
- **availability.units\[].bedrooms\_text / bathrooms\_text** *(string, optional)*: Source display labels for room counts.
- **availability.units\[].floor\_area** *(number, optional)*: Normalized floor-area value.
- **availability.units\[].floor\_area\_text** *(string, optional)*: Source display form of floor area.
- **availability.units\[].area\_unit** *(string, optional)*: Measurement unit, such as `sq ft`.
- **availability.units\[].available\_from** *(string, optional)*: Source availability label or date text.
- **availability.units\[].pricing** *(object, optional)*: Unit-level displayed rent, normalized range, deposit, and currency values when present.
- **availability.units\[].lease\_terms** *(string, optional)*: Source lease information.
- **availability.units\[].description** *(string, optional)*: Unit or model description.
- **availability.units\[].is\_new** *(boolean, optional)*: Source new-unit signal.
- **availability.units\[].discounts** *(object, optional)*: Numeric savings or price-drop values when published.
- **availability.units\[].amenities** *(array of strings, optional)*: Deduplicated amenity names.
- **availability.units\[].amenity\_groups** *(array of objects, optional)*: Amenity names grouped by source category.
- **availability.units\[].amenity\_groups\[].name** *(string, optional)*: Amenity category name.
- **availability.units\[].amenity\_groups\[].amenities** *(array of strings, optional)*: Amenities in that category.

#### Source-specific attributes

- **attributes** *(object, optional)*: Meaningful Apartment Finder-specific values.
- **attributes.promotions** *(array of strings, optional)*: Public promotion titles or messages.
- **attributes.apartmentfinder** *(object, optional)*: Apartment Finder-specific grouped attributes.
- **attributes.apartmentfinder.listing\_tier** *(string, optional)*: Source marketplace listing tier when present.

### Data Model Notes

- **Identity fields:** Use `record_id` for primary matching and upserts. Keep the source listing ID and URL as secondary audit identifiers.
- **Source and provenance:** `source_context` explains which search, page, position, and enrichment mode produced a record.
- **Property and listing attributes:** Core display identity lives in `entity`; listing classification, pricing, location, media, contacts, availability, metrics, and source-specific values remain in separate semantic groups.
- **Pricing and availability:** Asking rents, availability labels, unit data, and statuses are point-in-time public values, not valuations or guarantees.
- **Nested objects:** Preserve nested JSON in JSON-first systems. The grouping prevents unrelated listing, property, and unit values from being conflated.
- **Optional fields:** Detail, media, contact, property, rating, unit, promotion, and coordinate fields depend on what a particular listing exposes and whether enrichment succeeds.
- **Repeated runs:** Compare records by `record_id`, then evaluate business fields such as pricing, availability, status, media, and attributes alongside the Apify run time and saved input configuration.

### 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 kept in stable public fields or grouped objects instead of being silently discarded; optional source values may still be absent for a specific record.
- **Best-effort extraction:** Fields may vary by region, availability, listing type, visibility, source experiments, or source-side changes.
- **Optional fields:** Null-check or presence-check optional fields in downstream code and dashboards.
- **Deduplication:** Use `record_id` as the primary stable key, with `listing.listing_id` and `url` as supporting values.
- **Freshness:** Results reflect publicly available data at run time.
- **Repeated runs:** Use `record_id` when syncing into warehouses, CRMs, search indexes, vector stores, or monitoring systems.
- **Schema awareness:** Rely on documented fields and handle newly missing optional fields gracefully.
- **Run receipts:** Use summary and map artifacts to audit saved counts, selected coverage mode, enrichment status, coordinate readiness, and output links without treating artifacts as replacement dataset records.

### Tips For Best Results

- Start with a small `limit` and inspect the output shape before increasing collection size.
- Use one city, neighborhood, ZIP code, property type, or rent band per run when clean segment comparisons matter.
- Leave optional filters empty for broad discovery, then add them one at a time.
- Keep `enrich_data` enabled only when the additional detail supports your downstream workflow.
- Enable `maximize_coverage` for broad matching searches when deeper retrieval within the same criteria matters more than the fastest exploratory run.
- Save the exact input used for scheduled monitoring and use `record_id` for repeated-run upserts.
- Review `RUN-SUMMARY`, the HTML report, and `results-map` before importing a changed configuration into a production pipeline.
- Inspect a small record sample after changing filters, enrichment, coverage mode, or limits.

### How to Run on Apify

1. Open Apartment Finder Property Scraper in Apify Console.
2. Add one or more locations and configure the supported rental filters.
3. Set a maximum number of listings and choose enrichment, coverage, and optional connector settings.
4. Click **Start** and wait for the run to finish.
5. Open the dataset, inspect the first records, and review the run summary and map.
6. Download the dataset in JSON, CSV, Excel, or another Apify-supported format.

### Agentic And API-First Usage

The actor can serve as a structured public property-data acquisition step inside larger automated workflows. Its documented input schema, stable record identity, grouped output, and run artifacts allow agents and orchestration systems to scope work, verify completion, and route results without relying on private operational context.

#### Agent workflow pattern

1. Generate or select a scoped input using only supported parameters.
2. Run the actor manually, on a schedule, or through Apify platform automation.
3. Wait for completion and read the dataset records.
4. Validate records against the Field Reference and expected record family.
5. Read `RUN-SUMMARY`, `RUN-SUMMARY.html`, and `results-map` to verify counts, selected coverage mode, limit behavior, enrichment, coordinates, and output readiness.
6. Upsert records into the downstream system using `record_id`.
7. Trigger market analysis, alerts, BI refreshes, search or vector indexing, CRM enrichment, lead review, or human verification.

For agentic use, keep prompts grounded in the documented parameters and begin with bounded validation runs. Give downstream AI steps the Field Reference, recommended idempotency key, and a representative record rather than asking them to infer missing fields. Treat optional listing fields as nullable. Store Apify run ID, input configuration, and export metadata alongside the dataset when building audit trails. When context is limited for Claude, Codex, internal copilots, or property workflow agents, pass the input schema, field reference, `record_id` guidance, run summary, and one output example.

### Scheduling & Automation

#### Scheduling

**Automated Data Collection**

Schedule recurring runs to keep internal rental-listing snapshots aligned with publicly visible source data.

1. Navigate to **Schedules** in Apify Console.
2. Create a daily, weekly, or custom-cron schedule.
3. Configure and save the location, filters, enrichment, coverage, and limit inputs.
4. Enable notifications for run completion.
5. Add webhooks when another system should process the completed run.

#### Integration Options

- **CRM enrichment:** Upsert source URLs, identifiers, asking rents, location, contacts, and property details into property or opportunity records.
- **BI dashboards and warehouses:** Track listing counts, asking-rent ranges, property mix, enrichment, availability, and geographic coverage over time.
- **Webhooks:** Trigger validation, ingestion, alerting, or reporting after each completed run.
- **Google Sheets or Airtable:** Review bounded listing sets, contact details, prices, and availability in lightweight operational workflows.
- **Search and vector indexes:** Make grouped listing descriptions, locations, amenities, and attributes available for discovery and retrieval workflows.
- **MCP connectors:** Authorize a compatible connector in Apify and select it in the actor input to receive a concise run summary and public dataset, summary, report, and map links when available.
- **No-code automation:** Use Zapier or Make when a completed dataset or webhook should trigger stakeholder review, CRM updates, or notifications.

### Export Formats And Downstream Use

Apify datasets can be exported for manual review or consumed by downstream systems.

- **JSON:** Preserve nested objects, arrays, booleans, numbers, and optional groups for applications, AI agents, and pipelines.
- **CSV or Excel:** Support spreadsheet review and lightweight analysis; nested values may require deliberate flattening.
- **API access:** Read completed dataset records from automated internal workflows.
- **BI and warehouses:** Build historical reporting, dashboards, market snapshots, and monitoring tables.
- **Search or vector indexes:** Support property discovery, semantic retrieval, agent context, and document-style review.

### Downstream Pipeline Guide

- **Idempotency:** Upsert by `record_id`; retain `listing.listing_id` and `url` as secondary identity fields.
- **Null handling:** Treat all fields outside required `record_type`, `source_context`, and `entity` as optional, and presence-check nested members.
- **Type handling:** Preserve numeric prices, coordinates, areas, ratings, booleans, arrays, and nested objects in JSON-first destinations.
- **Flattening:** Flatten nested paths deliberately for CSV or relational tables, while retaining the original JSON export for full fidelity.
- **Partitioning:** Store run date, input location, market segment, property type, and workflow name alongside records for analysis.
- **Change detection:** Compare repeated runs by `record_id`, then evaluate `pricing`, `listing.listing_status`, `availability`, `media`, and selected attributes.
- **Quality checks:** Monitor saved record count, duplicate keys, required envelope presence, asking-rent availability, coordinate fill rate, enrichment counts, and important optional-field fill rates.
- **Human review:** Route records with missing identifiers, unusual rents, changed availability, changed status, or priority segments into a review queue.
- **Retention:** Set separate policies for raw exports, run artifacts, normalized warehouse tables, and historical snapshots.

### Performance and Coverage Expectations

Recent local validation artifacts provide the following examples. They describe those runs only and are not performance guarantees.

| Run type | Example scope | Listings | Duration | Coverage notes |
| --- | --- | ---: | ---: | --- |
| Lightweight validation | Los Angeles, CA; `limit: 1`; enrichment disabled | 1 | 1.821 seconds | 1 standard listing, 1 valid map coordinate, 1 map marker |
| Enriched validation | Los Angeles, CA; `limit: 5`; enrichment enabled | 5 | 2.922 seconds | 5 enriched listings, 0 failed details, 5 valid coordinates, 5 map markers |

Execution time varies with filters, result volume, target availability, response size, enrichment depth, coordinate and map processing, and how much information each listing publishes. Highly filtered and low-limit runs can finish faster, while broad discovery, `maximize_coverage`, enrichment, or detail-rich unit records may take longer. Coverage mode prioritizes deeper retrieval within the selected criteria and can trade speed for more matching listings. The actor does not claim complete-market coverage, lossless extraction, or universal execution times.

### Limitations

- Results depend on what Apartment Finder publicly exposes at run time.
- Optional descriptions, contacts, ratings, images, property types, promotions, unit availability, and amenities may be absent on sparse listings.
- Very broad searches can take longer and may need a higher `limit` to retain more matches.
- Coverage-aware runs can take longer when many listings match the selected criteria.
- Source-side changes can affect visible fields, labels, and result availability.
- Asking rents, status, descriptions, and availability are point-in-time public signals and should be independently verified before operational decisions.
- The actor provides structured public rental-listing data, not MLS data, ownership verification, brokerage services, legal advice, financial advice, investment advice, appraisals, or valuations.

### Troubleshooting

- **No results returned:** Check location spelling, confirm that Apartment Finder has public matches, and remove optional filters one at a time.
- **Fewer results than expected:** Raise `limit`, remove overly narrow filters, or enable `maximize_coverage` for a broad matching search.
- **Some fields are empty:** Optional values depend on what each listing publicly provides and whether detail enrichment is available.
- **Duplicate-looking records:** Compare `record_id`, source listing ID, and URL. Similar names or addresses can represent distinct listings or communities.
- **Run takes longer than expected:** Lower `limit`, disable enrichment for validation, or split a broad market into smaller locations or price segments.
- **Output changed:** Compare the current record with the Field Reference and retain a small sample for support.
- **Downstream import failed:** Validate JSON, nullable fields, nested arrays and objects, numeric types, and destination-specific flattening requirements.
- **MCP delivery was not received:** Confirm that a compatible connector was authorized and selected in Apify; the dataset and key-value-store artifacts remain the primary outputs.

### FAQ

#### What data does this actor collect?

Public Apartment Finder rental listings with identity, asking rents, addresses, coordinates, listing status, media, contacts, promotions, and optional enriched property and unit details.

#### Which filters are supported?

Location, minimum and maximum monthly rent, deal category, minimum bedrooms and bathrooms, property types, pet policy, amenities, specialty housing, and keywords.

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

`limit` is a maximum, not a promised count. The selected locations and filters may have fewer public matches, or some records may no longer be visible.

#### What does `maximize_coverage` do?

It seeks more matching listings within the same selected criteria when a broad search reports more matches than are normally visible. It does not relax filters and still respects `limit`.

#### What does enrichment add?

When available, enrichment can add descriptions, ratings, property type, postal code, additional media, floor plans, unit rents, bedrooms, bathrooms, floor area, availability, lease information, and amenities.

#### Where are the run summary and map?

Open the actor output links or default key-value store for `RUN-SUMMARY`, `RUN-SUMMARY.html`, and `results-map`.

#### What limit should I use first?

Start with 10 or fewer listings to validate filters and output shape, then increase the limit after reviewing records and artifacts.

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

Upsert using `record_id`. Keep the source listing ID and URL for secondary checks and audit trails.

#### Can I schedule recurring runs and use the output with AI agents?

Yes. Apify schedules can repeat the same input, and the structured dataset plus run artifacts can feed agents, ETL jobs, dashboards, alerts, and review workflows.

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

Yes. Use Apify dataset export formats; retain JSON when nested groups and arrays matter.

#### Does this actor collect private data or provide official MLS or appraisal data?

No. It collects publicly visible Apartment Finder listing information and does not provide private records, official MLS completeness, ownership verification, appraisals, or professional advice.

### Compliance & Ethics

#### Responsible Data Collection

This actor collects publicly available rental-listing information from Apartment Finder for legitimate business purposes, including:

- **Real estate** research and public market analysis
- Property inventory monitoring and operational reporting
- CRM, BI, search, and data-enrichment workflows

Users are responsible for ensuring that their collection 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 the target site’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 where applicable.
- Review retention, access-control, and data-sharing policies before operationalizing the dataset.

### Support

Ask for help through the Actor page or its **Issues** tab. Include the redacted input, Apify run ID, expected behavior, actual behavior, and—when useful—a small output sample. For pipeline or export issues, also identify the downstream destination and format, such as JSON, CSV, Excel, a warehouse, CRM, or search index.

# Actor input Schema

## `location` (type: `array`):

Enter one Apartment Finder-supported location per line, such as Los Angeles, CA; Atlanta, GA; 90034; or a neighborhood name. Use focused markets for cleaner price comparisons and recurring monitoring, or add multiple locations for a broader export.

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

Only include listings matching a monthly rent at or above this USD amount. Use it with the maximum rent to create a comparable price band for analysis, alerts, dashboards, or CRM qualification.

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

Only include listings matching a monthly rent at or below this USD amount. The maximum must be greater than or equal to the minimum when both values are provided.

## `deals_discounts` (type: `string`):

Optionally narrow results to one Apartment Finder promotion category. Leave empty when discounts are not required for your rental search.

## `bedroom_count` (type: `string`):

Select Studio or the minimum number of bedrooms required. The 4+ option includes properties with four or more bedrooms.

## `bathroom_count` (type: `string`):

Select the minimum number of bathrooms required. Use this with bedrooms and property type to define a consistent housing segment.

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

Choose the rental property categories to include. Leave empty to avoid restricting the search by house, townhouse, or condominium type.

## `pets_allowed` (type: `string`):

Optionally require listings that accept dogs, cats, or pets generally. Leave empty when pet policy should not narrow the dataset.

## `amenities` (type: `array`):

Choose interior, accessibility, parking, laundry, or community features listings should match. Leave empty for broader discovery; add amenities for targeted tenant requirements or portfolio analysis.

## `speciality_housing` (type: `array`):

Optionally include Apartment Finder categories such as income-restricted, military, senior, short-term, student, budget, or luxury housing. Leave empty when no specialty category is required.

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

Enter optional comma-separated terms, up to 100 characters, to focus the search on listing text relevant to your workflow, such as rooftop, transit, renovated, or waterfront.

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

Enable this for large exports, market monitoring, and downstream analysis that may need more than the first 750 visible matches. Keep it off for faster validation runs or narrowly filtered searches.

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

Keep this enabled for CRM enrichment, detailed BI datasets, availability tracking, and AI-assisted property review. Turn it off for faster collection when identity, rent, location, primary media, and other search-result fields are sufficient.

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

Choose the maximum number of matching listings to save. Leave empty to continue through all listings available for the selected locations, filters, and coverage setting.

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

Choose user-authorized connectors for a concise post-run handoff containing saved listing totals, duration, searched locations, enrichment and map status, plus public dataset, summary, report, and map links when available. Leave empty to only save the primary dataset and key-value-store artifacts.

## Actor input object example

```json
{
  "location": [
    "Los Angeles"
  ],
  "property_type": [],
  "amenities": [],
  "speciality_housing": [],
  "maximize_coverage": true,
  "enrich_data": true,
  "limit": 100,
  "mcpConnectors": []
}
```

# Actor output Schema

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

Grouped Apartment Finder rental listing records suitable for review, export, deduplication, CRM enrichment, dashboards, and ETL pipelines.

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

Machine-readable end-of-run summary with saved totals, enrichment, location, coordinate, asking-rent, property-type, and artifact breakdowns.

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

Human-readable end-of-run report with key listing totals and representative records.

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

Interactive map of saved listings with valid coordinates, including mapped, skipped, and deduplicated marker totals.

# 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/apartmentfinder-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/apartmentfinder-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/apartmentfinder-property-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "ApartmentFinder Scraper with Contacts & Features",
        "description": "Extract ApartmentFinder.com rental listings with asking rents, addresses, coordinates, photos, descriptions, contacts, amenities, floor plans, and unit availability. Use enrichment and coverage mode for market research, inventory monitoring, CRM enrichment, BI, and AI workflows.",
        "version": "0.1",
        "x-build-id": "uJrFEUwFoagOZKokS"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fatihtahta~apartmentfinder-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fatihtahta-apartmentfinder-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~apartmentfinder-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fatihtahta-apartmentfinder-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~apartmentfinder-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fatihtahta-apartmentfinder-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": "Add Locations (city, state, ZIP code, neighborhood, or market)",
                        "type": "array",
                        "description": "Enter one Apartment Finder-supported location per line, such as Los Angeles, CA; Atlanta, GA; 90034; or a neighborhood name. Use focused markets for cleaner price comparisons and recurring monitoring, or add multiple locations for a broader export.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "min_price": {
                        "title": "Set the Minimum Monthly Rent",
                        "minimum": 0,
                        "maximum": 15000,
                        "type": "integer",
                        "description": "Only include listings matching a monthly rent at or above this USD amount. Use it with the maximum rent to create a comparable price band for analysis, alerts, dashboards, or CRM qualification."
                    },
                    "max_price": {
                        "title": "Set the Maximum Monthly Rent",
                        "minimum": 0,
                        "maximum": 15000,
                        "type": "integer",
                        "description": "Only include listings matching a monthly rent at or below this USD amount. The maximum must be greater than or equal to the minimum when both values are provided."
                    },
                    "deals_discounts": {
                        "title": "Focus on a Deal or Discount Category",
                        "enum": [
                            "price_drop",
                            "best_value",
                            "rent_specials"
                        ],
                        "type": "string",
                        "description": "Optionally narrow results to one Apartment Finder promotion category. Leave empty when discounts are not required for your rental search."
                    },
                    "bedroom_count": {
                        "title": "Choose the Minimum Bedroom Count",
                        "enum": [
                            "studio",
                            "1",
                            "2",
                            "3",
                            "4_plus"
                        ],
                        "type": "string",
                        "description": "Select Studio or the minimum number of bedrooms required. The 4+ option includes properties with four or more bedrooms."
                    },
                    "bathroom_count": {
                        "title": "Choose the Minimum Bathroom Count",
                        "enum": [
                            "1",
                            "2",
                            "3_plus"
                        ],
                        "type": "string",
                        "description": "Select the minimum number of bathrooms required. Use this with bedrooms and property type to define a consistent housing segment."
                    },
                    "property_type": {
                        "title": "Select One or More Property Types",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Choose the rental property categories to include. Leave empty to avoid restricting the search by house, townhouse, or condominium type.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "houses",
                                "townhouses",
                                "condos"
                            ],
                            "enumTitles": [
                                "Houses",
                                "Townhouses",
                                "Condos"
                            ]
                        },
                        "default": []
                    },
                    "pets_allowed": {
                        "title": "Filter by Pet Policy",
                        "enum": [
                            "dogs_only",
                            "cats_only",
                            "pet_friendly"
                        ],
                        "type": "string",
                        "description": "Optionally require listings that accept dogs, cats, or pets generally. Leave empty when pet policy should not narrow the dataset."
                    },
                    "amenities": {
                        "title": "Select Required Property Amenities",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Choose interior, accessibility, parking, laundry, or community features listings should match. Leave empty for broader discovery; add amenities for targeted tenant requirements or portfolio analysis.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "air_conditioning",
                                "balcony",
                                "dishwasher",
                                "elevator",
                                "fireplace",
                                "fitness_center",
                                "garage",
                                "gated",
                                "parking_available",
                                "swimming_pool",
                                "wheelchair_accessible",
                                "utilities_included",
                                "lofts",
                                "furnished",
                                "laundry_in_unit",
                                "laundry_hookups",
                                "laundry_on_site"
                            ],
                            "enumTitles": [
                                "Air Conditioning",
                                "Balcony",
                                "Dishwasher",
                                "Elevator",
                                "Fireplace",
                                "Fitness Center",
                                "Garage",
                                "Gated",
                                "Parking Available",
                                "Swimming Pool",
                                "Wheelchair Accessible",
                                "Utilities Included",
                                "Lofts",
                                "Furnished",
                                "In-Unit Laundry",
                                "Laundry Hookups",
                                "On-Site Laundry"
                            ]
                        },
                        "default": []
                    },
                    "speciality_housing": {
                        "title": "Select Specialty Housing Categories",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optionally include Apartment Finder categories such as income-restricted, military, senior, short-term, student, budget, or luxury housing. Leave empty when no specialty category is required.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "income_restricted",
                                "military",
                                "senior",
                                "short_term",
                                "student",
                                "cheap",
                                "luxury"
                            ],
                            "enumTitles": [
                                "Income Restricted",
                                "Military",
                                "Senior",
                                "Short-Term Housing",
                                "Student",
                                "Cheap | budget-focused listings",
                                "Luxury Housing"
                            ]
                        },
                        "default": []
                    },
                    "keyword": {
                        "title": "Add Listing Keywords",
                        "maxLength": 100,
                        "type": "string",
                        "description": "Enter optional comma-separated terms, up to 100 characters, to focus the search on listing text relevant to your workflow, such as rooftop, transit, renovated, or waterfront."
                    },
                    "maximize_coverage": {
                        "title": "Collect More Matching Listings Beyond the Visible Search Cap",
                        "type": "boolean",
                        "description": "Enable this for large exports, market monitoring, and downstream analysis that may need more than the first 750 visible matches. Keep it off for faster validation runs or narrowly filtered searches.",
                        "default": true
                    },
                    "enrich_data": {
                        "title": "Enrich Matching Listings with Property and Availability Details",
                        "type": "boolean",
                        "description": "Keep this enabled for CRM enrichment, detailed BI datasets, availability tracking, and AI-assisted property review. Turn it off for faster collection when identity, rent, location, primary media, and other search-result fields are sufficient.",
                        "default": true
                    },
                    "limit": {
                        "title": "Set the Maximum Number of Listings to Save",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Choose the maximum number of matching listings to save. Leave empty to continue through all listings available for the selected locations, filters, and coverage setting."
                    },
                    "mcpConnectors": {
                        "title": "Select MCP Connectors for Run-Summary Delivery",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Choose user-authorized connectors for a concise post-run handoff containing saved listing totals, duration, searched locations, enrichment and map status, plus public dataset, summary, report, and map links when available. Leave empty to only save the primary dataset and key-value-store artifacts.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
