Maricopa County Property Records & Owner Data Scraper
Pricing
from $8.00 / 1,000 property records
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
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
queryoperation withreturnGeometry=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 owners —
sold_before_yearcombined withinclude_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_onlyto keep only parcels the county has flagged as rentals (itsRentalfield), 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_onlyto 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
- 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.1and4.2(the non-owner-occupied investor segment), enter acity, tickAbsentee owners only, and optionally tickOut-of-state owners onlyorRegistered rentals onlyto narrow further. - Set
max_resultsto cap how many records (and how much you spend) this run exports. The default is 1,000; the hard ceiling is 100,000. - Click Start actor. The Actor logs each page it fetches, the number of records kept, and the running total.
- 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.
- 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}
| Field | Type | Default | Description |
|---|---|---|---|
legal_class_code | string[] | [] | 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. |
city | string | "" | Situs city (e.g. Phoenix). Case-insensitive match against PropertyCity. |
zip_codes | string[] | [] | ZIP codes to filter by. Empty = all ZIPs. |
property_type | enum | — | Physical 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_value | number | — | Assessed (Full Cash) value range in USD. |
absentee_only | boolean | false | Only parcels where the owner mailing address differs from the situs address. |
out_of_state_only | boolean | false | Only parcels whose OwnerState is not AZ (blank owner states are excluded). |
registered_rentals_only | boolean | false | Only parcels the county has flagged as rentals (Rental = 'YES'). Combine with legal class 4.2 for the tightest residential-rental match. |
exempt_only | boolean | false | Only parcels with an active tax exemption (ExemptStatus = 'Active') — government / non-profit owned. |
min_value_gain_amount | number | — | Minimum 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_year | integer | — | Only parcels last sold before Jan 1 of this year. |
include_never_sold | boolean | true | When 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_results | integer | 1000 | Max 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
| Field | Type | Description |
|---|---|---|
parcel_id | string | Assessor Parcel Number (APN) |
situs_address | string | Property street address |
city / zip | string | Property city / ZIP |
owner_name | string | Owner of record |
owner_mailing_address | string | Owner mailing address line 1 |
owner_mailing_state | string | Owner mailing state |
is_absentee | boolean | Mailing address differs from situs address |
is_out_of_state | boolean | Owner mailing state (OwnerState) is not AZ |
assessed_value_total | number | Full Cash Value (total) |
assessed_value_land | number | Full Cash Value (land portion) |
assessed_value_improvement | number | Full Cash Value (improvement portion) |
last_sale_date | string | Last sale date (YYYY-MM-DD, UTC) |
last_sale_price | number | Last sale price (USD) |
value_gain_amount | number | assessed_value_total - last_sale_price; null if no sale price |
legal_class_code | string | Arizona legal-class code (e.g. 3.1, 4.2) |
legal_class_description | string | Human-readable legal-class description |
property_use_code | integer | County property-use code |
is_registered_rental | string | County Rental flag ("YES" or blank) |
exempt_status | string | Tax-exempt status |
limited_property_value | number | Limited Property Value (LPV) |
lot_size_acres | number | Lot size in acres |
pool | string | Pool presence |
stories | number | Number of stories |
bath_fixtures | integer | Bath fixture count |
subdivision | string | Subdivision name |
deed_date | string | Deed date (YYYY-MM-DD) |
assessor_url | string | Direct link to the parcel on the Assessor site |
treasurer_url | string | Direct link to the parcel on the Treasurer site |
year_built | integer | Construction year |
square_footage | number | Livable area (sqft) |
lot_size | number | Lot size (sqft) |
property_class | string | County property-use description |
latitude / longitude | number | Parcel centroid coordinates |
county / state | string | Always Maricopa / AZ |
scraped_at | string | UTC 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:
- In Apify Console, open the Actor -> Pricing and switch the pricing model to Pay per event.
- Add a primary event named
property-recordand set its unit price (e.g.$0.005). - Set the synthetic
apify-default-dataset-itemevent 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 alongsideproperty-record. Setting it to$0disables that charge safely (the SDK treats a falsy price as "no charge"). - Leave
apify-actor-startat its default price — the platform handles the start event automatically. Never chargeapify-actor-startfrom code: the SDK raises an error if you try to charge anyapify-*synthetic event manually, and this Actor only ever chargesproperty-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_amountis a classic high-motivation investor query. - Keep never-sold owners: leave
include_never_soldon (the default) withsold_before_yearto 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.2inlegal_class_codefor the tightest residential-rental match, or rely on theis_registered_rentalflag (the county'sRentalfield) to catch every parcel the county has flagged. - Use ZIP lists: pass several ZIPs in
zip_codesto 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_amountuses 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.