Maricopa County Property Records & Owner Data Scraper avatar

Maricopa County Property Records & Owner Data Scraper

Pricing

from $8.00 / 1,000 property records

Go to Apify Store
Maricopa County Property Records & Owner Data Scraper

Maricopa County Property Records & Owner Data Scraper

Export all 1,742,671 Maricopa County (Phoenix, AZ) parcels from the county assessor's own data. Filter by legal class, city, ZIP, property type, value and sale year. 38 fields per record: owner name, mailing address, absentee and out-of-state flags, values and sale history. No monthly subscription.

Pricing

from $8.00 / 1,000 property records

Rating

0.0

(0)

Developer

Abhay kumar

Abhay kumar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

What does the Maricopa County Parcel & Property Lead Scraper do?

The Maricopa County Parcel & Property Lead Scraper pulls public parcel and assessor records directly from the Maricopa County Assessor's public ArcGIS REST service (Parcel Data View FeatureServer) and exports them as clean, standardized real-estate lead lists. For every matched parcel it returns the parcel ID (APN), situs (property) address, owner name, owner mailing address, assessed value, value gain, last sale date and price, legal class, registered-rental flag, subdivision, year built, living area, lot size, and latitude/longitude — already filtered to the cities, ZIPs, property types, and legal classes you care about. Try it free on the Apify platform: click Start actor, fill in a couple of filters, and download your leads.

Because it runs on Apify, you get API access, scheduling (refresh a lead list weekly), webhooks and integrations (Zapier, Make, Google Sheets, Airtable), and run monitoring out of the box — no infrastructure to maintain.

Note: Maricopa County exposes this data as a FeatureServer that supports server-side pagination and ordering. The scraper uses the query operation with returnGeometry=false, so it pulls full attribute records without geometry, paging up to 2,000 records at a time in a single sorted pass.

Why use the Maricopa County Parcel & Property Lead Scraper?

Real-estate investors, wholesalers, land buyers, and tax professionals spend hours manually exporting county data and reformatting it. This Actor does the export, cleaning, and enrichment in one run and targets the most common lead-generation use cases:

  • Absentee owners — owners whose mailing address differs from the property address (landlord & inheritance leads).
  • Out-of-state owners — owners mailing to a non-AZ address (often motivated, non-local sellers).
  • High value-gain properties — parcels where assessed value minus last sale price exceeds a threshold you set (appreciation since the last sale).
  • Long-time & never-sold ownerssold_before_year combined with include_never_sold (on by default) surfaces owners who haven't sold in years or have no sale on record at all — the longest-held, often free-and-clear leads.
  • Registered rentals — toggle registered_rentals_only to keep only parcels the county has flagged as rentals (its Rental field), or select legal class 4.2 (Residential rental) for the tightest residential-rental match.
  • Legal-class targeting (primary filter) — multi-select any of Arizona's 12 legal-class codes (primary residence, second home, rental, commercial, agricultural/vacant, and more) to match exactly the ownership category you want. This is the most precise ownership-category filter; select 4.1 + 4.2 together to surface the ~441,910 non-owner-occupied residential parcels that make up the core investor segment.
  • Property-type targeting — single family, condo/townhouse, multi-family, vacant land, commercial, and more. This filters by physical structure type; for ownership-category targeting prefer legal class above.
  • Tax-exempt parcels — toggle exempt_only to isolate (or later exclude) government / non-profit owned parcels with an active exemption.
  • Geographic targeting — by city and/or ZIP code list.

The standardized schema means every export drops straight into your CRM, spreadsheet, or dialer without manual column mapping.

How to use the Maricopa County Parcel & Property Lead Scraper

  1. On the Actor's page in Apify Console, click the Input tab and set your filters. Legal class is the primary filter — start there. For example, select legal classes 4.1 and 4.2 (the non-owner-occupied investor segment), enter a city, tick Absentee owners only, and optionally tick Out-of-state owners only or Registered rentals only to narrow further.
  2. Set max_results to cap how many records (and how much you spend) this run exports. The default is 1,000; the hard ceiling is 100,000.
  3. Click Start actor. The Actor logs each page it fetches, the number of records kept, and the running total.
  4. When the run finishes, open the Output / Dataset tab to preview, filter, and download your leads. Switch between the Parcel leads, Out-of-State Owners, Registered Rentals, and Non-Owner-Occupied (Investor) views to see lead-optimized column layouts.
  5. Schedule the Actor (Console -> Schedules) or call it via the Apify API to refresh leads automatically.

If no parcels match your filters, the Actor sets a clear status message such as "No parcels matched the filters. Applied filters: ..." — it never exits silently with an empty dataset, which is the most common complaint about competing parcel scrapers.

Input

The Actor accepts a JSON input defined by the input schema. Full field descriptions are in the Input tab; a minimal example:

{
"legal_class_code": ["4.1", "4.2"],
"city": "Phoenix",
"zip_codes": ["85015", "85016"],
"absentee_only": true,
"out_of_state_only": false,
"registered_rentals_only": true,
"min_value": 100000,
"max_value": 500000,
"min_value_gain_amount": 25000,
"sold_before_year": 2018,
"include_never_sold": true,
"max_results": 1000
}
FieldTypeDefaultDescription
legal_class_codestring[][]Primary filter. One or more of Arizona's 12 legal-class codes (3.1, 3.2, 3.3, 4.1, 4.2, 4.8, 4.9, 2.R, 1.8, 1.9, 1.12, M), matched against LandLegalClassCode via an IN (...) clause. This is the most precise ownership-category filter. Select 4.1 + 4.2 for the ~441,910-parcel non-owner-occupied investor segment. Empty = all classes.
citystring""Situs city (e.g. Phoenix). Case-insensitive match against PropertyCity.
zip_codesstring[][]ZIP codes to filter by. Empty = all ZIPs.
property_typeenumPhysical structure type (coarser than legal class): single_family, condo_townhouse, apartment, multi_family, vacant_land, commercial, industrial, office, retail, mobile_home. Matched against PropertyUseDescription. For ownership-category targeting prefer legal_class_code.
min_value / max_valuenumberAssessed (Full Cash) value range in USD.
absentee_onlybooleanfalseOnly parcels where the owner mailing address differs from the situs address.
out_of_state_onlybooleanfalseOnly parcels whose OwnerState is not AZ (blank owner states are excluded).
registered_rentals_onlybooleanfalseOnly parcels the county has flagged as rentals (Rental = 'YES'). Combine with legal class 4.2 for the tightest residential-rental match.
exempt_onlybooleanfalseOnly parcels with an active tax exemption (ExemptStatus = 'Active') — government / non-profit owned.
min_value_gain_amountnumberMinimum value gain = assessed total - last sale price (appreciation since the last sale, not mortgage-adjusted equity). Parcels with no sale price have null value gain and are skipped when this is set; the skipped count is reported in the run status.
sold_before_yearintegerOnly parcels last sold before Jan 1 of this year.
include_never_soldbooleantrueWhen on (default), the sold-before-year filter also keeps parcels with no sale date (SaleDate IS NULL). Only takes effect when sold_before_year is set.
max_resultsinteger1000Max records to export (hard ceiling 100,000). 0 uses the default.

Output

Each result is one standardized parcel record in the default dataset. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Two representative items:

[
{
"parcel_id": "303-31-044",
"situs_address": "1234 W BETHANY HOME RD",
"city": "Phoenix",
"zip": "85015",
"owner_name": "SMITH JOHN A",
"owner_mailing_address": "1234 W BETHANY HOME RD",
"owner_mailing_state": "AZ",
"is_absentee": false,
"is_out_of_state": false,
"assessed_value_total": 218400,
"last_sale_date": "2015-03-18",
"last_sale_price": 168000,
"value_gain_amount": 50400,
"legal_class_code": "3.1",
"legal_class_description": "Primary residence (owner-occupied)",
"is_registered_rental": null,
"subdivision": "CHEERY LYNN ACRES",
"year_built": 1978,
"square_footage": 1652,
"lot_size": 7200,
"property_class": "SINGLE FAMILY",
"assessor_url": "https://www.maricopa.gov/assessor/parcel/303-31-044",
"treasurer_url": "https://www.maricopa.gov/treasurer/parcel/303-31-044",
"latitude": 33.5265,
"longitude": -112.0914,
"county": "Maricopa",
"state": "AZ",
"scraped_at": "2026-07-27T14:03:21.489000+00:00"
},
{
"parcel_id": "217-26-118",
"situs_address": "7890 N SCOTTSDALE RD UNIT 204",
"city": "Scottsdale",
"zip": "85250",
"owner_name": "JONES ROBERT L",
"owner_mailing_address": "5551 OCEAN BLVD",
"owner_mailing_state": "CA",
"is_absentee": true,
"is_out_of_state": true,
"assessed_value_total": 302000,
"last_sale_date": null,
"last_sale_price": null,
"value_gain_amount": null,
"legal_class_code": "4.1",
"legal_class_description": "Non-primary residence (second home / absentee)",
"is_registered_rental": "YES",
"subdivision": "MOUNTAIN SHADOW",
"year_built": 2004,
"square_footage": 1180,
"lot_size": null,
"property_class": "CONDO",
"assessor_url": "https://www.maricopa.gov/assessor/parcel/217-26-118",
"treasurer_url": "https://www.maricopa.gov/treasurer/parcel/217-26-118",
"latitude": 33.5021,
"longitude": -111.9262,
"county": "Maricopa",
"state": "AZ",
"scraped_at": "2026-07-27T14:03:21.502000+00:00"
}
]

The second record shows the important rule: when a parcel has no sale price on record, value_gain_amount is null — never faked. Records missing an address have is_absentee/is_out_of_state as null (cannot be determined) rather than a wrong guess. The is_registered_rental flag is the county's Rental value shown as-is ("YES" or blank).

Data table

FieldTypeDescription
parcel_idstringAssessor Parcel Number (APN)
situs_addressstringProperty street address
city / zipstringProperty city / ZIP
owner_namestringOwner of record
owner_mailing_addressstringOwner mailing address line 1
owner_mailing_statestringOwner mailing state
is_absenteebooleanMailing address differs from situs address
is_out_of_statebooleanOwner mailing state (OwnerState) is not AZ
assessed_value_totalnumberFull Cash Value (total)
assessed_value_landnumberFull Cash Value (land portion)
assessed_value_improvementnumberFull Cash Value (improvement portion)
last_sale_datestringLast sale date (YYYY-MM-DD, UTC)
last_sale_pricenumberLast sale price (USD)
value_gain_amountnumberassessed_value_total - last_sale_price; null if no sale price
legal_class_codestringArizona legal-class code (e.g. 3.1, 4.2)
legal_class_descriptionstringHuman-readable legal-class description
property_use_codeintegerCounty property-use code
is_registered_rentalstringCounty Rental flag ("YES" or blank)
exempt_statusstringTax-exempt status
limited_property_valuenumberLimited Property Value (LPV)
lot_size_acresnumberLot size in acres
poolstringPool presence
storiesnumberNumber of stories
bath_fixturesintegerBath fixture count
subdivisionstringSubdivision name
deed_datestringDeed date (YYYY-MM-DD)
assessor_urlstringDirect link to the parcel on the Assessor site
treasurer_urlstringDirect link to the parcel on the Treasurer site
year_builtintegerConstruction year
square_footagenumberLivable area (sqft)
lot_sizenumberLot size (sqft)
property_classstringCounty property-use description
latitude / longitudenumberParcel centroid coordinates
county / statestringAlways Maricopa / AZ
scraped_atstringUTC timestamp of the scrape

Pricing / Cost estimation

How much does it cost to scrape Maricopa County parcel data? This Actor is priced pay-per-event: you are charged once for every parcel record actually exported, via a single property-record event. Runs that return zero records cost nothing for data. You always control your spend up front with max_results.

For example, at a property-record price of $0.005 per record, exporting 1,000 leads costs about $5.00; 10,000 leads about $50.00. Set your max_results to match your budget.

Setting up pay-per-event in Apify Console

Pay-per-event events are configured in the Apify Console (or via the platform API) — there is no local file for them. To enable pricing for this Actor:

  1. In Apify Console, open the Actor -> Pricing and switch the pricing model to Pay per event.
  2. Add a primary event named property-record and set its unit price (e.g. $0.005).
  3. Set the synthetic apify-default-dataset-item event price to $0. The Python SDK automatically charges this event once for every item written to the default dataset, so if it is left priced it would double-charge alongside property-record. Setting it to $0 disables that charge safely (the SDK treats a falsy price as "no charge").
  4. Leave apify-actor-start at its default price — the platform handles the start event automatically. Never charge apify-actor-start from code: the SDK raises an error if you try to charge any apify-* synthetic event manually, and this Actor only ever charges property-record.

Testing pricing locally

To exercise the pay-per-event path on your own machine, set ACTOR_TEST_PAY_PER_EVENT=true (and optionally ACTOR_MAX_TOTAL_CHARGE_USD to cap a test run). This forces the SDK into PPE mode locally and writes a local charging-log dataset so you can confirm each property-record charge is recorded.

Tips or Advanced options

  • Control cost first: start with a small max_results (e.g. 100) and tight filters to sanity-check output, then scale up.
  • Combine filters for sharper leads: absentee_only + out_of_state_only + sold_before_year + min_value_gain_amount is a classic high-motivation investor query.
  • Keep never-sold owners: leave include_never_sold on (the default) with sold_before_year to capture owners with no sale on record — roughly half the county — who are often the longest-held, most motivated leads.
  • Target rentals two ways: select legal class 4.2 in legal_class_code for the tightest residential-rental match, or rely on the is_registered_rental flag (the county's Rental field) to catch every parcel the county has flagged.
  • Use ZIP lists: pass several ZIPs in zip_codes to target specific neighborhoods without a city-wide export.
  • Pagination is automatic: the Actor pages the FeatureServer (respecting the layer's maxRecordCount) and stops cleanly on the last short page — no manual offset math. A built-in duplicate-billing guard tracks every object ID pushed, so the county service can never make the same record get charged twice.
  • Built-in resilience: failed ArcGIS requests are retried with exponential backoff (up to 5 attempts); genuine query errors and 4xx responses are not retried, so bad input fails fast with a clear message.
  • Value gain is an estimate: value_gain_amount uses the county's assessed (Full Cash) value, which is typically lower than true market value — treat it as a ranking signal, not an appraisal. It is appreciation since the last sale, not mortgage-adjusted equity (lien/mortgage data is not in this dataset).

Known data limitations

Maricopa County does not publish tax amounts in its public parcel layer, so this Actor does not return them. Every field it does return is populated from the county's own records — see the Data table above for coverage.

last_sale_date, last_sale_price, and value_gain_amount are null for parcels with no recorded sale — roughly half the county (the longest-held, often free-and-clear leads). Set include_never_sold to false to exclude them from a sold_before_year filter.

exempt_status is populated only for the ~23,000 parcels with an exemption on record; it is null everywhere else. pool is populated for the parcels the county has flagged with a pool (roughly 24% countywide) and is null otherwise.

FAQ, disclaimers, and support

Is this data legal to scrape? Yes. Maricopa County parcel and assessor records are public records under Arizona public-records law and are published by the county for public access. This Actor only reads the county's public ArcGIS REST endpoint; it does not log in, bypass access controls, or access any non-public data.

Comply with the source. Users must respect the county GIS service's Terms of Service and rate limits. The Actor is designed for reliability over raw speed — it pages sequentially and retries transient failures rather than hammering the endpoint.

Use responsibly. Owner names and mailing addresses returned here are public record, but you remain responsible for complying with all applicable laws in how you use them — including the FCRA and equivalent rules, which generally prohibit using public-records data as a factor in credit, insurance, employment, or tenant-screening decisions without a permissible purpose. Do not use this data to harass, stalk, or discriminate.

Known limitations. value_gain_amount is null for any parcel with no sale price on record. See the Known data limitations section above for details on tax amounts, sale history, and sparse fields. Data freshness depends on the county's publication cycle; for authoritative values confirm against the Maricopa County Assessor site.

Support & feedback. Found a bug or want a feature? Open an issue on the Actor's Issues tab in Apify Console. Need a custom multi-county build, additional fields, or a different output schema? The maintainer can provide a tailored solution.