Us Municipal Building Permits Accela Scraper avatar

Us Municipal Building Permits Accela Scraper

Pricing

from $6.00 / 1,000 building permit extracteds

Go to Apify Store
Us Municipal Building Permits Accela Scraper

Us Municipal Building Permits Accela Scraper

Search public Accela Citizen Access permits by agency, date and keyword. Extract permit status, project addresses, disclosed job values and contractor details. Export construction records for project monitoring, market research and prospecting.

Pricing

from $6.00 / 1,000 building permit extracteds

Rating

0.0

(0)

Developer

Arezdev

Arezdev

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Find municipal construction opportunities with permit dates, project addresses, job values, and public contractor details in one clean dataset.

Search public Accela Citizen Access records for solar, roofing, HVAC, electrical, planning, and commercial projects. Export JSON, CSV, Excel, or retrieve results through Apify's dataset API. Direct HTTP requests preserve session cookies without running a browser.

Best for monitoring public permits on compatible Accela Citizen Access portals. Verify the agency URL and search module first, then use a short date range. Agency names are presets, not universal coverage; use CUSTOM when a municipality changes its portal.

How to use

  1. Choose an agency and public module, or select CUSTOM and enter the current official Citizen Access URL.
  2. Set an inclusive filed-date range and optionally enter a keyword such as solar, roofing, or HVAC.
  3. Set the maximum records and whether to retrieve contractor details, then start the Actor.
  4. Filter the dataset to status: SUCCESS for extracted permits. ERROR rows explain unavailable pages without a permit event fee.

The form starts with San Antonio (the COSA portal), the Building module, September 1-5, 2026, and a three-row sample. The API default is 25 rows. The legacy SANJOSE selector remains available, but its former Accela endpoint returned HTTP 404 during review. Use the municipality's current official portal when a preset becomes unavailable.

Preset agency identifiers are used literally as paths on https://aca-prod.accela.com/. Agencies can use another host or identifier, and a preset does not guarantee current availability. For example, San Antonio's public portal uses COSA; enter that URL with CUSTOM. Verify the agency's official portal before changing the target.

What data can you extract?

FieldsMeaning
agencyCode, permitNumberSelected agency and public record identifier
statusExtraction result: SUCCESS or ERROR
permitType, permitStatusAgency's permit type and business status
filedDateFiled date normalized to YYYY-MM-DD when recognized
address, projectDescriptionPublic project location and description
jobValuationPublic job value in USD as a number
contractorName, contractorBusinessPublic professional and business
contractorPhone, contractorLicenseNumberPublic contractor phone and license
applicantNamePublic applicant name
detailUrl, scrapedAtRecord link and extraction time in UTC
errorMessageSafe ERROR diagnostic; null on successful records

Every row has the same flat fields. Unpublished information remains null. Agency layouts and available fields vary; see Accela's record documentation. Where several professionals are present, the first public professional is used.

Input settings

SettingDefaultNotes
agencyCodeSANANTONIOSANJOSE, ATLANTA_GA, TAMPA, DENVER, CLEVELAND, SACRAMENTO, OAKLAND, SANANTONIO, CUSTOM
customAccelaPortalUrlUnsetRequired for CUSTOM; agency base or full CapHome URL
moduleNameBuildingBuilding, Permits, or Planning
startDate, endDate2026-09-01, 2026-09-05Inclusive, valid calendar dates
keywordFilterUnsetCase-insensitive literal substring in listing number, type, status, address, and description; up to 256 characters
fetchContractorDetailstrueAlso retrieves valuation and applicant data
maxItems251–2,000; editor prefill 3; includes ERROR rows
timeoutSecs205–60 seconds per HTTP attempt
proxyConfigurationUnsetDirect first; datacenter fallback on 403/429/503

Set useApifyProxy to false to force direct connections. Providing proxyUrls forces those proxies exclusively. Otherwise, blocked requests try SHADER datacenter and default datacenter access. A configured final tier, including residential groups, is allowed only when useApifyProxy is explicitly true. Runtime-supplied Apify proxy credentials are required; this Actor never requests the account profile to discover them. Proxy traffic can incur separate charges.

{
"agencyCode": "ATLANTA_GA",
"moduleName": "Building",
"startDate": "2026-09-01",
"endDate": "2026-09-05",
"keywordFilter": "solar",
"fetchContractorDetails": true,
"maxItems": 3,
"timeoutSecs": 20,
"proxyConfiguration": { "useApifyProxy": false }
}

Temporary HTTP 502, 503 and 504 responses on GET requests receive at most one retry per route, with a cancellable wait of up to two seconds. Longer Retry-After instructions are not shortened, and form submissions are not retried this way.

Native CSV export is preferred when enabled and sufficient for requested detail extraction. Otherwise, the Actor reads the grid, follows ASP.NET pagination, and preserves fresh WebForms state. Filtering precedes detail requests; permit numbers are deduplicated within the run. Portal JavaScript is never executed.

Both legacy CSV postbacks and current Accela downloads through Export2CSV.ashx are supported. The current download is fetched directly after its export postback using the same validated portal session.

Output example

Illustrative data showing the exact output shape:

{
"agencyCode": "ATLANTA_GA",
"permitNumber": "EXAMPLE-2026-001",
"status": "SUCCESS",
"permitType": "Residential Solar PV",
"permitStatus": "Issued",
"filedDate": "2026-09-02",
"address": "100 Example Avenue",
"projectDescription": "Install rooftop solar system",
"jobValuation": 24500,
"contractorName": "Example Contractor",
"contractorBusiness": "Example Solar LLC",
"contractorPhone": "+1 415-555-0100",
"contractorLicenseNumber": "EXAMPLE-123456",
"applicantName": "Example Applicant",
"detailUrl": null,
"scrapedAt": "2026-10-19T12:00:00.000Z",
"errorMessage": null
}

Spreadsheet formula prefixes are escaped in dataset strings. Valid phone numbers and numeric values are preserved.

Use the results in Clay, n8n, Make, or your API

Import CSV into Clay and join by permit number and address. In n8n or Make, start the Actor, wait for completion, retrieve dataset items, and filter SUCCESS rows. Use Apify schedules for daily date windows and deduplicate across runs by (agencyCode, permitNumber).

Retrieve /v2/datasets/{datasetId}/items?format=json&clean=true from api.apify.com for API integrations. Keep authentication in your automation platform's secret configuration.

Pricing and limits

The custom pay-per-event event is permit-scraped. Only SUCCESS records carry that event. ERROR rows cost $0 in permit event fees. Apify compute, storage, proxy, and separately configured platform events can still apply. Do not configure a separate default-dataset-item charge if ERROR records must remain free of result event fees.

The actual price is configured in Apify Console and displayed on the Store page; this repository does not set a live price. At an example rate of $0.005 per successful permit, 1,000 successes cost $5 in permit event fees. A run with 900 successes and 100 errors costs $4.50 at that rate. This is an example, not an advertised live price. See Apify PPE configuration.

Non-paying Apify users can save up to 25 total rows per run, including errors. Paying users can request up to 2,000. Local runs skip the free-plan gate but obey maxItems. Budget exhaustion stops new work and exits cleanly. Writes are serialized and flushed every 100 records or five seconds, and on shutdown.

Cloud defaults are 256 MB and a one-hour timeout. Up to 25 detail workers share four simultaneous network response slots. Decompressed response limits are 4 MiB for HTML/CSV, 2 MiB for JSON, and 15 MiB for XML. Recoverable incomplete HTML can yield a successful record when recognizable detail content remains; logs identify the recovery. Incomplete search pages do not continue pagination. Narrow the date range when exports are oversized.

FAQ and troubleshooting

Why does a run finish successfully with ERROR rows?

Network errors, TLS failures, unavailable portals, and unsupported pages become diagnostics. Invalid input is the only application-level reason for exit code 1. Check row statuses to confirm whether records were retrieved.

Why are contractor details or valuation null?

The agency may not publish those fields, the record may lack them, or detail fetching is disabled. A failed requested detail preserves listing data in an uncharged ERROR row.

Why are there no rows?

An explicit portal no-records message produces an empty dataset. Check the module, dates, and keyword. Unrecognized result pages produce an ERROR instead of silently claiming zero matches.

Can this solve CAPTCHAs or log in?

It supports public, browser-free searches and reports challenges or login requirements safely. Confirm anonymous access and a current official URL.

How are custom URLs protected?

Each destination and redirect must resolve entirely to public unicast addresses. Connections pin validated IPs while preserving the HTTP authority and TLS server name. Proxy CONNECT tunnels also target validated destination IPs. Local networks, URL credentials, nondefault destination ports, insecure redirect downgrades, cross-origin form submissions, and external detail links are blocked. TLS validation stays enabled.

How do I build and test locally?

Use Node.js 22 or newer:

npm ci
npm run build
npm test
npm run smoke -- ATLANTA_GA

The smoke command performs a real three-record direct-only search without initializing the Apify SDK or reading credential files. With no argument it uses the required default agency; it fails validation when no SUCCESS is returned. Append listing after the agency to skip detail requests.

For a full local Actor run, write input to storage/key_value_stores/default/INPUT.json and run npm start. Build the container with docker build -t accela-permits .; the final image runs as non-root node.

Before publication, configure Limited Permissions, register permit-scraped and its live price in Apify Console, and validate the chosen agency from the intended cloud region. The repository does not publish or change account settings.