Igni

Methodology

How Igni turns scattered, official building-permit records into fresh, structured leads — where the data comes from, how we classify and enrich it, how often it refreshes, and how we stay on the right side of each source's license. We document this openly because a data product is only as trustworthy as its sourcing.

Maintained by Igni Research. Last reviewed September 2026.

Where the data comes from

Every permit Igni surfaces originates from an official government open-data feed published by a city, county or metro agency — the same records anyone can request under public-records law. We connect to these through their published interfaces: Socrata open-data APIs, Esri ArcGIS feature services, and bulk CSV exports, depending on what each jurisdiction offers. We do not scrape behind logins or paywalls, and we do not buy permit data from intermediaries.

Before a jurisdiction goes live, we review its terms of use, license and robots policy, confirm the data flow, and record the source so it is auditable. Coverage today spans 127 cities in 40 US states and DC, and we add jurisdictions as we verify new feeds.

How often it refreshes

We poll each source on a schedule tuned to how it updates, ordering records newest-first so the freshest permits are captured as soon as the jurisdiction publishes them. In practice a newly issued or filed permit can reach a subscriber in under a day. When a city later corrects a record we re-ingest it, so late field corrections flow through rather than getting stuck at the version we first saw.

Normalization and deduplication

Each feed has its own field names, date formats and conventions. We map every source into one consistent permit shape — address, dates, permit type, status, valuation and work description — so a permit from one city is comparable to a permit from another. Permits are keyed by source, jurisdiction and version; a reissued permit number bumps the version rather than creating a duplicate, and a project that straddles a jurisdiction boundary is collapsed to a single record so you are not notified twice for the same work.

How we classify ADUs

Identifying accessory dwelling units is the core of our enrichment. When a jurisdiction provides a structured ADU flag or subtype, we use it directly — that is the most reliable signal. Where it does not, we run a keyword classifier over the permit's work description and use codes, tuned to avoid common false positives such as sheds, carports and re-roofs.

For the ambiguous cases the keywords cannot resolve confidently, we run a second stage that uses a Claude large language model to read the description and refine the classification — for example resolving “granny flat” into a detached ADU, or typing an ADU that the city flagged but did not categorize. This stage runs only on the uncertain tail, not on every permit, and it falls back to the keyword result if it is unavailable. A permit is only delivered as a confident ADU when its classification clears a confidence threshold; weaker signals are routed to review rather than overstated.

Location resolution and SB-9 / SB-10 flags

Many feeds omit a ZIP code or provide only coordinates. When a record lacks a usable ZIP, we resolve one — reverse-geocoding from the permit's point geometry, or forward-geocoding from its street address — using a free public geocoder, and quarantine the row rather than guess if neither works. For California, we attach informational SB-9 / SB-10 relevance flags to help surface lot-split and transit-corridor opportunities. These flags are estimates derived from available data, not a legal determination of eligibility.

How we estimate permit approval times

The approval times on our city pages are calendar days from a permit's application date to its issue date, computed from the historical records each source publishes. We group applications into cohorts by the month they were filed and use cohorts that are between 3 and 36 months old — old enough for most permits to have reached a decision, recent enough to reflect how the office works today.

Some applications in those cohorts are still pending. Dropping them would make approvals look faster than they are, and counting them as issued today would be wrong too, so we treat them as right-censored and estimate the time-to-issue curve with the Kaplan–Meier method. The median and the typical range (25th to 75th percentile) are read off that curve; when too few permits have been issued for a figure to be estimated, we leave it out rather than guess.

We break the figures down by segment: building permits versus trade permits (electrical, plumbing, mechanical and similar), residential versus commercial use, valuation band, and ADU filings, which for this purpose we identify with keyword detection over the work description (the first stage described above, without the language-model step). A segment is shown only when it has at least 30 permits. Classification follows each source's own permit types and descriptions, so it inherits their inconsistencies.

These are historical, typical figures — not a prediction for any individual project and not a guarantee. Scope, application completeness, resubmittals and review workload all move a single permit's timeline, and a jurisdiction's process can change. The per-lead expected issue dates in paid plans apply the same curve to a pending permit's application date and carry the same caveat.

How we measure permit activity and forecast it

The permit-activity figures on our city pages are monthly counts of the permits each source publishes, bucketed by issue month — or, for a source that does not publish issue dates, by application month. The current month is left out because it is incomplete, and the most recent months are marked provisional: cities often publish records late, so those counts can still rise. The year-over-year change compares the last 12 months with the 12 months before, both by permit type (residential building, commercial building, trade permits and ADU filings) and overall.

For the forecast we try three candidate models on each series: a seasonal-naive model (the same month last year), a damped Holt–Winters model fitted on log counts, and a trailing mean. We pick the one that performed best in a rolling-origin backtest — repeatedly forecasting one to six months ahead from past cut-off points and scoring the error against what actually happened — and quote that typical error next to the chart. The shaded range is an empirical 10th–90th percentile band built from the same backtest errors, not a textbook formula. A seasonal forecast needs at least 36 months of history; shorter series get no forecast rather than a guess. A forecast whose backtest error (sMAPE) is above 30% is not published at all — typically small series such as ADU filings, where month-to-month noise swamps the trend — and the chart shows the history and year-over-year change only.

Some feeds change what they publish — a permit type starts appearing, or a backlog is issued in one batch — and the counts jump for reasons unrelated to construction. We flag such a level shift when a series steps up to at least 1.5× the prior year's median, the step is checked against the same months a year earlier (so a seasonal peak does not count), and the new level persists for at least six months. When a shift is flagged we suppress the year-over-year comparison across it and fit the forecast only on the new level; the city page notes the shift and marks it on the chart. Genuine, gradual growth — such as Boulder's or Bernalillo County's — is not flagged.

The counts reflect what each city publishes to its open-data feed, not a complete census of construction. Feeds differ in how far back they go, which permit types they include and how promptly they update, and a change in what a city publishes moves the numbers too — so compare a city with its own past more readily than with another city. A forecast is a statistical estimate with a range, not a prediction for any individual project, and it cannot anticipate policy changes or shocks that are not in the history.

Licensing and attribution

Open data is not the same as no rules. We track the license of every source — public-records statutes, public-domain dedications, and permissive licenses such as Creative Commons Attribution (CC BY). Where a source requires attribution, we carry that credit through to where its data is shown, and where a source's terms are restrictive we do not onboard it. Several jurisdictions in our coverage require attribution by name, and we honor those obligations as a condition of using the data.

Verify independently

Igni reflects the public record as the source published it. Government feeds contain errors, omissions and corrections, and permitting and housing rules change and vary by jurisdiction. Our data and classifications are informational signals to act on, not legal, financial or construction advice — always confirm a permit and any eligibility against the issuing authority before relying on it. Questions about our methodology, or a record you think is wrong? Email legal@igni.pro or use our contact form.