Building Permits & Contractor License Intel
Pricing
from $3.00 / 1,000 permit records
Building Permits & Contractor License Intel
Unifies US building-permit + contractor-license portals into one schema: type, valuation, status, contractor, address. Value layer: contractor linking, property clustering, and scored high-intent trade signals (solar/roofing/HVAC) that cross-sell into trades lead-gen. Logged-out public records.
Pricing
from $3.00 / 1,000 permit records
Rating
0.0
(0)
Developer
Seibs.co
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
TL;DR for contractors, suppliers, solar/roofing/HVAC sales teams, insurers, and real-estate investors: Aggregates building-permit and contractor-license data from the fragmented US city/county/state government portals (public-by-law) into one normalized schema - permit type, declared valuation, status, contractor, address, dates, parcel - then adds the value layer that makes a permit sellable. A fresh permit is the highest-intent buying signal in the trades: a commercial HVAC permit is a service-contract lead, a roofing permit is a supplier's prospect, a solar/pool permit is an installer's lead. On top of the raw records it runs contractor linking (a contractor's permit footprint across jurisdictions + license), property clustering (multiple permits at one address = an active, capital-committed project), and scored trade signals (a 0-100 buying-intent score per permit with a cross-sell hint into the trades lead-finders). The underlying data is public, but it lives behind 50+ separate permit portals with no unified free API - the exact fragmentation Shovels (quote-gated) and BuildZoom monetize. Government public records, logged-out, PII-minimized. Free Apify plan covers exploration runs on your $5 platform credit.
Run it in 30 seconds
# Via the Apify Python SDKfrom apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("seibs.co/building-permits-intel").call(run_input={"mode": "trade_signals","jurisdictions": ["CHICAGO", "AUSTIN", "NYC", "SF", "SEATTLE"],"trades": ["solar", "roofing", "hvac", "pool"],"max_results_per_jurisdiction": 25})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Or via curl:
curl -X POST "https://api.apify.com/v2/acts/seibs.co~building-permits-intel/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"mode": "permit_search", "jurisdictions": ["CHICAGO","AUSTIN","SF"], "query": "roof"}'
Or click "Try for free" on this page if you prefer the no-code UI.
What you get
Each run produces:
- A clean dataset, filterable in the Apify console and downloadable as CSV or JSON
- An OUTPUT.html dashboard preview of your top records
- A sample-output preview at ./.actor/sample-output.json
- An
access_notesrecord up top documenting each jurisdiction's portal, platform, access method, proxy needs, any cost/bulk path, and a responsible-use note
What does Building Permits Intel do?
It queries each selected jurisdiction's public permit feed and normalizes every result into one schema: permit_number, jurisdiction, permit_type (normalized to new_construction / addition_alteration / roofing / solar / electrical / plumbing / mechanical / pool / demolition / ...), trade (the contractor specialty the permit signals demand for), status (normalized to issued / final / pending / expired / ...), valuation_usd + valuation_band, work_description, address/city/state/zip/parcel_id, contractors (name + trade + license + city), owner_name where public, and source_url. Then it runs the value layer:
- Trade classification - every permit is tagged with the trade it signals demand for (solar/roofing/HVAC/pool/electrical/plumbing/...) off the union of permit type, work description, and the contractor's declared trade, plus an intent priority.
- Contractor linking - groups permits by a normalized contractor key into a footprint per contractor: permit count, trades worked, jurisdictions, total + median declared valuation, and license number/type where the permit exposes it. Contractors on many permits or multiple jurisdictions are flagged
high_volume(the supplier/recruiter target). - Property clustering - multiple permits at one address (a remodel + electrical + plumbing, or a new-build sequence) cluster into a
permit_clusterrollup - a richer, capital-committed lead than a single permit. - Trade-signal scoring - scores each permit into a 0-100 buying-intent signal (trade priority x declared valuation x recency) and tags the portfolio lead-finder it cross-sells into.
Modes
| Mode | What it returns |
|---|---|
permit_search (default) | Normalized permits per jurisdiction (optional query, address, date_from/date_to, min_value, trades filters), plus contractor links and property clusters. |
permit_profile | Direct lookup for specific permits by permit_numbers=[{jurisdiction, permit_number}]. |
contractor_lookup | One contractor footprint record per requested contractor: permit count, trades, jurisdictions, total valuation, license. Charges contractor_enrichment per footprint. |
trade_signals | Permits scored into ranked, cross-sell-ready trade_signal records (intent score + cross-sell hint). Charges valuation_signal per signal. |
Coverage: verified metros + a national catalog
Permit portals share no schema and no unified API - that fragmentation is the moat we unify. Coverage is honestly tiered:
Fully-parsed feeds (5) - request + parser verified against the live portal with captured fixtures, returns real normalized permit data. All five are genuinely open Socrata open-data feeds (logged-out, no anti-bot, JSON):
| Jurisdiction | Feed | Valuation | Contractor | Notes |
|---|---|---|---|---|
| CHICAGO | City of Chicago Building Permits | reported_cost | Yes (contractor contacts) | Rich: work description + multiple contractor contacts per permit. |
| AUSTIN | City of Austin Issued Construction Permits | total_job_valuation | Yes (contractor_company_name + trade) | Permit class / work class + contractor trade. |
| NYC | NYC DOB Permit Issuance | (not in feed) | Yes (permittee + license #/type) | The contractor-license linkage layer; owner business name. |
| SF | San Francisco DBI Building Permits | estimated_cost / revised_cost | (not in feed) | Strong valuation + existing/proposed use & units. |
| SEATTLE | Seattle Built Environment Permits | estprojectcost | (when present) | Permit class/type + work description. |
Catalog-registered (28) - correct portal + platform (Socrata / ArcGIS / Accela / EnerGov / eTRAKiT / license board) + access method + anti-bot level recorded, anti-bot escalation pipeline wired, jurisdiction-specific parser pending (these return a documented jurisdiction_pending note). Includes major metros/counties - Los Angeles, Houston, Phoenix, San Antonio, San Diego, Dallas, San Jose, Denver, Portland, Las Vegas/Clark County, Miami-Dade, Nashville, Charlotte, Columbus, Fort Worth, Boston, Washington DC, Philadelphia, Atlanta - and state contractor-license boards - CSLB (CA), FL DBPR, AZ ROC, OR CCB, NV NSCB, UT DOPL, WA L&I, NC LBGC.
The Socrata metros in the catalog (LA, Dallas, Denver, Nashville, Boston, DC, Philadelphia, San Diego) phase in with a single field map - the SocrataPermitConnector base does the request building. The live access_matrix (all jurisdictions, with coverage and platform per entry) is emitted in the access_notes record on every run. Pass jurisdictions: ["ALL"] to query every jurisdiction, or ["FULL"] for the verified metros.
Anti-bot escalation (residential + browser)
The open Socrata feeds clear on a plain request. The catalog Accela/EnerGov metros and some license boards sit behind a JS/SPA layer or an edge WAF. The client escalates automatically instead of giving up:
- httpx over the DATACENTER proxy - cheapest, tried first; clears the open feeds outright.
- curl_cffi with real Chrome TLS impersonation over the RESIDENTIAL proxy - defeats JA3/TLS-fingerprint WAFs.
- Playwright/patchright headful browser over the RESIDENTIAL proxy - for true JS/SPA/CAPTCHA portals. Set
browser_cdp_url(orBROWSER_CDP_URL) to a warm anti-detect browser to pass Cloudflare-managed challenges; the per-search-CAPTCHA portals additionally need the opt-in solver (CAPTCHA_SOLVER_PROVIDER+CAPTCHA_SOLVER_KEY). - Fail-soft - if every tier is blocked/unavailable, the connector emits a documented
fetch_errorand the run still finishes SUCCEEDED.
Pricing (pay-per-event)
| Event | Price | When |
|---|---|---|
permit_record | $0.005 | Per normalized permit. |
valuation_signal | $0.008 | Per permit carrying a parsed dollar valuation, and per scored trade_signal in trade_signals mode. |
contractor_enrichment | $0.010 | Per contractor footprint resolved in contractor_lookup mode. |
scheduled_delta_run | $0.050 | Per scheduled monitor-mode run that emits a change digest. |
A run that returns nothing costs nothing. This undercuts the quote-gated incumbents (Shovels, BuildZoom) and turns a per-record pay-as-you-go price on data their sales teams gate behind annual contracts.
Monitor mode (new-permits watchlist)
Run this actor on an Apify Schedule and it switches to monitor mode: it diffs this run's permits against the last scheduled run and emits a change digest (new permits, status changes, finals) - the "alert me to new roofing permits in my metro" watchlist. Set monitor_webhook_url to post the digest to Slack. Charges one scheduled_delta_run per scheduled run.
Cross-sell into the trades lead-finders
Every trade_signal carries a cross_sell_actor hint pointing at the portfolio lead-finder that consumes it (a roofing/HVAC/solar permit feeds home-services; a new-build/demo permit feeds contract-heavy-smbs). Pipe a permit's address + trade into the matching lead-finder to enrich the property owner or the contractor into a full outreach record.
Legal & responsible use
- Public records. Building permits and contractor licenses are public-by-law government records. We access them logged-out, with no accounts, no cookies, and no paywalls bypassed.
- PII minimized. Contractor and applicant business names + cities are public on the filing and kept. Personal phone numbers are dropped; owner names are retained only as the public filing exposes them (many portals already redact to a business name).
- Intent, not surveillance. A fresh permit is a buying/intent signal for suppliers, installers, and insurers - use it for legitimate B2B outreach and risk assessment, not to harass property owners. Respect each portal's terms and your own counsel's guidance, especially when enabling the opt-in CAPTCHA solver.
AI agents & MCP
The overview dataset view is a narrow, token-efficient slice for LLM agents. A paid MCP twin (mcp-building-permits-intel) exposes search_permits, get_permit, lookup_contractor, and trade_signals as MCP tools for Claude, Cursor, OpenAI Assistants, and LangChain - and is x402 (USDC on Base) / Skyfire ready for token-less agentic payments.