Maricopa Building Permits Scraper
Pricing
from $9.60 / 1,000 permit records
Maricopa Building Permits Scraper
Export official Maricopa building permits with project addresses, parcels, status, type, descriptions and application/issuance dates. Filter the county GIS inventory for recurring project research; excludes municipal completeness and private contacts.
Pricing
from $9.60 / 1,000 permit records
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Refresh a project inventory from official Maricopa building permits in the county's public GIS. Export permit numbers, status, type, project address, parcel, description, and application/issuance dates into a structured dataset.
This Actor serves property researchers, construction analysts and teams refreshing county project inventories. It reads the county Building Permits GIS view, not every municipality's permit portal. It does not provide private contacts, contractor enrichment or a complete historical workflow log.
Who is it for?
Construction analysts, property researchers and data teams can refresh county permit project inventories, compare status snapshots and cite official permit evidence.
What does it do?
The Actor queries the official public county GIS inventory, applies your filters, deduplicates permits and saves normalized records to the default Apify dataset. Optional date filters use application dates. Leave filters unset for an unfiltered inventory sample.
Why use this Actor?
- Reuse one consistent permit schema for recurring inventory refreshes.
- Join project permits to parcel research using public parcel identifiers.
- Keep source query links for checking project evidence.
- Filter by a known permit, status, type, address substring or application date.
- Avoid downloading weekly spreadsheets when you need the current GIS inventory.
County public data can omit fields, change classifications or lag actual project activity. Verify important conclusions against the county's records.
Getting started
- Open the Actor's Input tab.
- Set
maxItemsto 20 for a first sample. - Optionally enter filters; every supplied filter combines with AND.
- Run the Actor and open the dataset.
- Download JSON, CSV, Excel or another Apify dataset export format.
Example input:
{"maxItems":20}
Input parameters
| Parameter | Meaning |
|---|---|
maxItems | Global unique-permit limit, default 100, range 1–100000; no zero/unlimited mode. |
permitNumber | Exact whole-field permit number, case-insensitive; trims outer whitespace. |
status | Exact whole-field county status, case-insensitive; trims outer whitespace. |
permitType | Exact whole-field county classification, such as Building (Commercial). |
addressContains | Case-insensitive literal substring of street address only; trims outer whitespace; rejects % and _. |
appliedFrom | Inclusive application-date lower bound, YYYY-MM-DD in UTC. |
appliedTo | Inclusive application-date upper bound, YYYY-MM-DD in UTC. |
No filter searches the project description. Date filters exclude records without application dates. Invalid dates, reversed ranges, unknown input fields and malformed limits fail the run rather than silently ignoring the request. A valid search with no matching permits succeeds with an empty dataset.
Filtering examples
Find a known permit:
{"permitNumber":"B202306811","maxItems":1}
Search a completed commercial project cohort:
{"status":"Complete","permitType":"Building (Commercial)","addressContains":"Bell","appliedFrom":"2023-01-01","appliedTo":"2023-12-31","maxItems":25}
The address filter is a substring, not geocoding or a whole-word query. Bell can match any address containing that sequence. Multiple filters narrow the same county source; there are no separate URL/discovery modes.
Extracted data
| Field | Meaning |
|---|---|
objectId | GIS object ID; useful for source provenance. |
permitNumber, permitCenterId | Public permit identifiers. |
permitType, workClass, status | County classifications and current status. |
address, zipCode, parcelNumber | Project location and public parcel reference. |
description | Source project description, potentially abbreviated. |
applicationDate, issuedDate | Source application and issuance dates, ISO UTC timestamps. |
expirationDate | GIS ExpirationDate field; metadata aliases it CreateDate, so do not assume compliance meaning without confirmation. |
workflowStep, workflowStepStatus, workflowStepDate | Current workflow step snapshot. |
workflowAction, workflowActionDate | Displayed workflow action and date. |
sourceUrl, scrapedAt | Official record-query link and extraction timestamp. |
Unavailable values are null. ZIP codes are text. Workflow fields represent the current displayed state, not a sequence of historical events.
Output example
A representative observed permit, shortened to core fields:
{"objectId":111765,"permitNumber":"B202306811","permitType":"Building (Commercial)","workClass":"Accessory","status":"Complete","address":"12302 W Bell RD","parcelNumber":"232-08-682A","description":"ELECTRICAL ENCLOSURE // GOTO B202303207","applicationDate":"2023-06-27T00:00:00.000Z","issuedDate":"2023-10-02T00:00:00.000Z","workflowStep":"Issue Permit","workflowStepDate":null}
The default dataset has a permit overview table. The SUMMARY key-value record reports saved count, budgetReached, requested filters and coverage. Export formats are provided by Apify rather than separate generated files.
How much does it cost to export Maricopa building permits?
A one-time $0.005 start event applies to each valid run, including a valid no-result query. Each unique permit saved has an item event. Rejected or duplicate records have no item event. There are no separate charges for workflow fields or the summary.
| Apify Store spend tier | Per permit |
|---|---|
| FREE | $0.0184 |
| BRONZE | $0.016 |
| SILVER | $0.01248 |
| GOLD | $0.0096 |
| PLATINUM | $0.0096 |
| DIAMOND | $0.0096 |
At BRONZE, estimated Actor charges are $0.021 for one permit, $0.325 for 20, and $1.605 for 100. Spend tiers follow qualifying aggregate monthly Apify Store spending, not this Actor's private volume ladder. The Actor checks charging capacity before querying pages and saving permits. If the budget cannot cover the start fee, it returns no records without querying the source; if it cannot cover another permit, it stops with partial results and SUMMARY.budgetReached=true. The saved count reflects delivered records, and undelivered records are not charged. Billing limits can therefore stop an export before the requested result limit. Consult the current pricing panel for applicable charges and platform terms.
Pagination and coverage
Results use ascending GIS object-ID keyset pages, up to 500 records per request, stopping at the global unique-permit limit or source exhaustion. Deduplication uses permit-center identity when available, otherwise permit number. A local 501-record check exercised more than one page.
The source can update during a run, so this is not a transactionally frozen snapshot. There is no guarantee of complete county history, municipal completeness or real-time updates. Record volume reflects the current public view and your filters.
Integrations
- Schedule an Apify Task with an overlapping application-date window and compare records by
permitCenterIdorpermitNumberin your database. - Export CSV to a spreadsheet for permit inventory review.
- Send dataset rows through an Apify integration or webhook into a warehouse.
- Join parcel identifiers to assessor research; permits and ownership records are different evidence types.
The Actor does not keep a cross-run change ledger, send alerts or infer new permits automatically. Recurring comparison is performed in your downstream workflow.
API usage
Replace APIFY_TOKEN with an environment variable containing your own token; never share it in an input or dataset.
curl -X POST "https://api.apify.com/v2/acts/automation-lab~maricopa-county-building-permit-records/run-sync-get-dataset-items" \-H "Authorization: Bearer $APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"maxItems":20}'
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/maricopa-county-building-permit-records').call({ maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/maricopa-county-building-permit-records').call(run_input={'maxItems': 20})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(items)
MCP usage
For Claude Code:
$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/maricopa-county-building-permit-records"
Claude Desktop, Cursor, and VS Code clients supporting HTTP MCP can use this actor-scoped configuration and their authenticated Apify connection:
{"mcpServers": {"apify": {"url":"https://mcp.apify.com?tools=automation-lab/maricopa-county-building-permit-records"}}}
Example prompts: “Get 20 county building permits with status Complete.” “Find county permit B202306811 and summarize its published workflow snapshot.” Actor availability depends on publication and your access permissions; do not paste credentials into prompts.
Legality and data handling
This independent Actor is not affiliated with or endorsed by Maricopa County or Apify. It uses public county GIS records and Apify's standard terms. No AI model is used during extraction and no scraped data is sent to a model provider. The icon is an original generated illustration, not a county seal.
Only public permit/project fields are collected; no owner-contact scraping, private contacts, sessions or residential proxies are used. Project addresses and descriptions may still contain personal information. Use data appropriately and avoid unlawful targeting, harassment or unsolicited spam.
Results and the summary remain in your Apify storage under your account's retention settings until deleted. This Actor does not implement a separate retention timer, external cache or private database. Delete runs/datasets/key-value records through Apify when no longer needed. Logs contain counts and error metadata, not project rows or credentials. The county GIS receives filter requests; Apify processes input, output, logs and billing. No other runtime paid service is required.
Troubleshooting and FAQ
Why did a valid query return no records?
Every filter combines with AND. Check a known permit with only permitNumber, then add filters individually. Source classifications are exact whole-field values.
Why is a date null? The public GIS omitted it. Null issuance date is not proof that a project never received a permit elsewhere.
Can I get every city's permits? No. County GIS is not a substitute for Phoenix, Mesa, Tempe or other municipal portals.
Can I search issuance dates or descriptions? Not in this version. Application-date and address filters are the supported date/text controls.
What happens when the source fails? Network timeouts, HTTP 429 and temporary server errors have up to three attempts per page with bounded backoff. Permanent GIS error envelopes fail immediately. A failed run may retain already-delivered partial rows and their charges; inspect its status before treating an export as complete.
Does it need login or a proxy? No user login or proxy is required for the public GIS route. There is no automatic paid fallback.
Related Actors and support
For complementary parcel ownership and valuation research, see Maricopa County Property Records Scraper. For a different county corpus, see Hillsborough County Building Permits Scraper.
Report Actor problems through the Apify Store Issues tab with the run link and reproduction input, excluding secrets. County record accuracy questions require checking the official source, not inferring missing fields from this export.