Sacramento County Building Permits Scraper
Pricing
from $1.44 / 1,000 permit exporteds
Sacramento County Building Permits Scraper
Search Sacramento County GIS building permits by application, type, status, address, parcel and applied dates. Export work, valuation, contractor and dates; county GIS coverage only, no applicants or inspection history.
Pricing
from $1.44 / 1,000 permit exporteds
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
Refresh Sacramento County building permits for construction market research and sales prioritization. Search the county's public GIS permit layer and export application IDs, property addresses, parcels, work descriptions, valuations, contractors, statuses and dates.
The Actor reads the Sacramento County GIS Permits layer anonymously. Coverage follows that layer, primarily county-administered/unincorporated records, not every municipality in Sacramento County. It does not scrape applicant profiles or inspection history.
Who is it for?
- Construction suppliers researching projects by application type and status.
- Local analysts comparing permit valuations and work descriptions.
- Property researchers matching an application or parcel to county records.
- Data teams refreshing a bounded county permit extract on a schedule.
This is a record extraction tool, not a compliance determination, contractor endorsement, or guaranteed complete county census.
Why use it?
Use one normalized row per GIS record instead of manually reading map popups. Exact application and parcel filters help with repeat lookups. Address substring and applied-date filters narrow a research extract. Every row carries a source query link and collection timestamp.
No county login, session cookies, browser, residential proxy, paid source subscription, or user-supplied key is required. The runtime does not use AI. There are no hidden external dependency fees.
Get started
- Open the Input tab.
- Leave the filters blank for a sample of the GIS layer, or choose filters below.
- Set
maxItems, for example 100. - Start the Actor once and wait for it to finish.
- Inspect the dataset, then export JSON, CSV, Excel or other formats available in Apify.
The Console prefills a small 20-record example; when maxItems is omitted the runtime default is 100.
Default input:
{"maxItems":100}
Search Sacramento County building permits
Filters are combined with AND. Strings are trimmed at their edges. Exact filters compare the whole field case-insensitively; they do not remove punctuation or internal spaces.
| Input | Meaning |
|---|---|
application | Exact application identifier, such as MISR2021-00002 |
applicationType | Exact source type, such as Residential |
status | Exact source status, such as Completed |
addressContains | Case-insensitive contiguous substring within Address; not a geocoder |
parcelNumber | Exact source parcel string; preserve leading zeros and formatting |
appliedFrom | Inclusive UTC date on APPLIED_DATE, YYYY-MM-DD |
appliedTo | Inclusive UTC date on APPLIED_DATE, YYYY-MM-DD |
maxItems | Global saved-record limit, default 100, allowed 1–10000 |
Blank strings, invalid dates, reversed date ranges and unknown input properties are rejected. % and _ are not accepted in address searches because wildcard matching is not exposed. Missing dates do not match a date filter.
Example for a bounded residential extract:
{"applicationType":"Residential","status":"Completed","appliedFrom":"2021-01-01","appliedTo":"2021-01-31","maxItems":100}
An exact known application lookup:
{"application":"MISR2021-00002","maxItems":1}
What data is returned?
| Field | Content |
|---|---|
objectId | GIS row ID; can change after source republication |
application | County application identifier; preferred comparison key |
applicationType, applicationSubtype | Published type and subtype |
status | Status in the GIS snapshot |
address, parcelNumber | Property address and parcel string |
projectName, workDescription | Project and proposed work text |
valuation | Published valuation in USD; zero is preserved |
contractor | Published contractor field; may be OWNER BUILDER |
openedAt, appliedAt, issuedAt, finaledAt | Source dates converted to ISO UTC |
sourceUrl | Allowlisted GIS query link for this row |
scrapedAt | UTC collection time |
Unavailable optional values are null, not fabricated. There are no applicant profiles, email/phone enrichment, owner lookup, documents, geometry, inspection events, or full inspection history. A finaled date is just a source date, not an inspection report.
Output example
This abbreviated real application example omits property and contractor identifiers:
{"application":"MISR2021-00002","applicationType":"Residential","status":"Completed","projectName":"AREA: R01: Main Breaker Replacement","workDescription":"New Main 100 amp breaker","valuation":0,"appliedAt":"2021-01-01T22:23:03.663Z","issuedAt":"2021-01-06T08:00:00.000Z","finaledAt":"2021-01-11T08:00:00.000Z"}
The actual dataset includes every field in the table above. Use the source link to verify the current published row; the county may update it after extraction.
Source and freshness
The source is the Sacramento County GIS Permits layer. It is published by the Sacramento County GIS organization on ArcGIS Online. Refresh frequency and historical completeness are controlled by the county; this Actor does not promise real-time portal updates. Compare scrapedAt with the source's own dates rather than treating collection time as a filing date.
Limits and ordering
Results are ordered by descending GIS OBJECTID, not guaranteed newest application date. Pages contain at most 200 records. The limit applies globally after source filters, not per page. Zero and unlimited collection are not supported.
For repeat refreshes, use explicit applied-date windows and compare rows outside the Actor. There is no incremental cache, built-in alert, modified-since filter, historical snapshot service, or guaranteed change feed. Re-running produces a fresh per-run dataset. Compare primarily by application; investigate multiple source rows rather than assuming one application can never have more than one GIS row.
Pagination uses a strict object-ID cursor to avoid repeated rows within one run. It is not a transactional snapshot: changes or republication while a run is executing can affect completeness. A limit of 10000 is a cap, not a guarantee that a query has that many matches. Split large studies by applied-date range if appropriate.
How much does it cost to extract Sacramento County building permits?
Pay per event: a $0.005 start fee per valid run plus a per-permit charge. The BRONZE price is $0.0024 per permit. No-result valid runs pay the start fee only; invalid input is rejected before charging.
| BRONZE example | Estimated total Actor charge including start |
|---|---|
| 1 permit | $0.0074 |
| 10 permits | $0.029 |
| 100 permits | $0.245 |
Spend tiers depend on your qualifying aggregate monthly Apify Store spend, not private volume thresholds for this Actor. Higher tiers may reduce the per-permit price; the Pricing tab is authoritative. Estimates exclude separately applicable platform/account charges and may change with refunds, disputes, corrections or taxes. No earnings or payout guarantee is offered.
Rejected/duplicate source records and failed requests are not separately charged. If a run fails after delivering some rows, those rows remain partial output and may have their permit charges. A billing or upstream failure is not reported as a successful complete export.
Integrations
- Export CSV into a spreadsheet for a construction opportunity review.
- Send the default dataset to a database or BI pipeline and join on application/parcel.
- Schedule overlapping applied-date windows with Apify Schedules, then compare statuses downstream.
- Use Apify webhooks or Make/Zapier to move a completed dataset to your own systems.
Scheduling and change comparison are configured outside this Actor. A scheduled applied-date window does not detect every change to older records.
API examples
Use your Apify token from a protected environment variable. Start one run and preserve its ID. For long runs, poll the same run instead of creating another.
curl -X POST "https://api.apify.com/v2/acts/automation-lab~sacramento-county-building-permits/runs" \-H "Authorization: Bearer $APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"applicationType":"Residential","maxItems":100}'
JavaScript with the Apify client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({token: process.env.APIFY_TOKEN});const run = await client.actor('automation-lab/sacramento-county-building-permits').call({maxItems: 100});if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);const {items} = await client.dataset(run.defaultDatasetId).listItems({limit: 100});console.log(items);
Python:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/sacramento-county-building-permits').call(run_input={'maxItems': 100})if run['status'] != 'SUCCEEDED':raise RuntimeError(f"Run {run['id']}: {run['status']}")items = client.dataset(run['defaultDatasetId']).list_items(limit=100).itemsprint(items)
MCP and AI clients
The Actor itself uses no AI. Clients can discover its schema through the scoped Apify MCP endpoint when the Actor is available to that account.
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/sacramento-county-building-permits"
Claude Desktop, Cursor, and VS Code: add this equivalent remote HTTP MCP configuration using the client's MCP settings and supported transport:
{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com?tools=automation-lab/sacramento-county-building-permits"}}}
Configure authentication through your client's protected credential mechanism. Example prompts: “Look up application MISR2021-00002 and show its status, work description and valuation.” Or: “Export up to 20 Residential permits applied during January 2021; show application, status and valuation.”
- Discover actual tool names and argument schemas with
tools/list. Actor selection also exposes run/data helper tools; it does not expose exactly one tool. Discovery alone is not authorization to execute. - For an authorized invocation, start once and retain the run ID/status/storage IDs. These are metadata, not permit rows.
call-actorwaits at most 0–45 seconds (default 30). If pending, follow that same run with bounded backoff, for example 2/4/8/10 seconds within a 120-second total deadline. Set the client timeout above the chosen wait plus transport margin. On timeout check the known run, never blindly restart; if its ID is unknown report uncertainty. At the deadline report pending and stop. - On success fetch untransformed dataset JSON in pages of 20 rows with explicit fields/offsets, at most 100 source rows and 64 KiB of serialized UTF-8 content admitted to model context. Enforce bytes host-side before injection; omit or summarize oversized rows with disclosure. If the client cannot intercept responses, do not claim a hard byte guarantee. Advance source offsets, not transformed row counts. Report continuation offset and truncation when incomplete; keep full exports outside model context.
- Report terminal failures honestly, with any rows marked partial. No universal token-saving claim is made: discovery caching and visible context depend on the client.
Reliability and troubleshooting
Transient network errors, 429 and server 5xx responses receive at most three attempts per page with bounded backoff. Authentication, invalid query, malformed JSON and unexpected response structure fail closed. No automatic premium proxy fallback is enabled.
FAQ
Why no results? Verify the exact type/status or parcel formatting, remove a filter, and widen the applied-date range. A legitimate empty match succeeds with an empty dataset.
Why is a city permit missing? This county GIS layer is not every city's permit portal. Incorporated-city records may be outside its coverage.
Why are some dates or valuations missing? The county has not supplied the field for that row. A zero valuation is preserved and differs from null.
Can I retrieve applicants or inspections? No. Neither feature is implemented or implied by the finaled date.
What if the source fails halfway through? The run fails with partial rows retained, not a false success. Fix the input/source condition before retrying; do not combine partial datasets without deduplication.
Legality and responsible use
Public property and contractor fields may contain personal information, including sole-trader names or incidental names in work descriptions. Use only for a lawful, appropriate research purpose and respect applicable privacy and outreach rules. Public availability is not permission for spam. Verify significant decisions against official county records. This Actor is independent and is not affiliated with or endorsed by Sacramento County or Esri.
Processing uses the public Esri-hosted county GIS source, Apify compute/storage and our private GlitchTip diagnostics. Source requests include only your selected search filters; no third-party model receives input or records. No source credentials are needed. We do not deliberately log addresses, contractor names or raw response bodies; operational logs contain counts and error categories.
Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed; reports are retained for 30 days. Search filter values that are not secrets may remain in sanitized diagnostics. Do not enter private credentials or sensitive free text into filters.
Results and run input/logs are stored in your Apify account under its configured storage retention and deletion controls. The Actor adds no persistent global dataset, cookie jar, cross-run cache, or private archive of successful exports. Delete run datasets/input/logs through Apify when no longer needed; diagnostic deletion requests can be raised through the Actor Issues tab.
Support and related Actors
Report reproducible problems through this Actor's Apify Issues tab with the run ID and a non-sensitive example. Do not post credentials. User reports receive a substantive response within 14 calendar days.
Other jurisdictions are separate products, not substitutes for Sacramento coverage: