Products API & Data Search Coverage Property History Alerts For Contractors Data Exports
Solutions Solar & Energy Roofing HVAC Real Estate Insurance Lenders & CRE Contractors
Pricing Refer & Earn API Docs Sign In Get Started
Insurance

Roof age and renovation history for underwriting and claims

Pull the permit history of any address at quote time: the last permitted roof, HVAC, solar and pool work, additions and demolitions. When nothing matches, the API tells you whether that means no permit or no coverage.

No credit card required. 100 free requests/day.

roof_age.sh
# Roof, HVAC and renovation dates for one address
curl "https://api.permit-stack.com/v1/property/history?address=10517%2035th%20Ave%20NE\
&city=Seattle\
&state=WA" \
  -H "X-API-Key: pk_your_key_here"

# "last_roofing_date": "2026-09-16"
# "last_hvac_date":    "2020-08-25"
# Seattle data through 2026-09-25 (current)

The short answer

Building permits are dated public records of work on a property. PermitStack normalizes 117M+ permits from 887 active data sources in 8,000+ cities across 48 states and DC, including 6.7M+ roofing permits, into one API. /v1/property/history turns an address into a permit timeline and a signals block with the latest roof, HVAC, solar and pool dates.

Every answer says how current its source is, and an empty answer says whether we cover that city. Start free, and check your market before you pay.

6.7M+

Roofing permits

Reroofs, tear-offs and repairs, one of 20 categories in a 117M+ permit database.

Daily

Source polling

The main ingest runs every day at 03:00 UTC, and each source reports the newest permit we actually hold.

$0

To evaluate

100 free requests per day, no card. Free keys see the last 30 days of permits; paid plans remove the date limit.

How underwriting and claims teams use permit data

Each example is a real request and a trimmed copy of the response it returned. The residential example has its street address redacted.

Paid plans (free keys see the last 30 days)

Roof and system dates at quote

One call to /v1/property/history returns every permit we hold at the address and a signals block built from them: the most recent roofing, HVAC, solar and pool permit dates, plus flags for additions, new construction, demolition, electrical and plumbing work. That is a dated, attributable fact for rating a roof or a system without sending anyone out.

data_currency names each source behind the answer and how current it is, so the date you rate on comes with its own provenance.

request
# A public community center in Seattle
curl "https://api.permit-stack.com/v1/property/history?address=10517%2035th%20Ave%20NE\
&city=Seattle\
&state=WA" \
  -H "X-API-Key: pk_your_key_here"
response (truncated)
{
  "found": true,
  "total_matches": 16,
  "summary": {
    "first_permit_date": "2007-11-14",
    "last_permit_date": "2026-09-16",
    "years_of_history": 19,
    "categories": {"ELECTRICAL": 9, "ROOFING": 1, "HVAC": 1,
                   "MECHANICAL": 1, "DEMOLITION": 1, ...},
    "signals": {
      "has_roofing": true,  "last_roofing_date": "2026-09-16",
      "has_hvac": true,     "last_hvac_date": "2020-08-25",
      "has_solar": false,   "has_pool": false,
      "has_addition": false, "has_demolition": true,
      ...
    }
  },
  "data_currency": [
    {"jurisdiction": "Seattle", "data_through": "2026-09-25", "status": "current", ...},
    {"jurisdiction": "Seattle Electrical", "data_through": "2026-09-26", "status": "current", ...},
    {"jurisdiction": "Seattle Trade", "data_through": "2026-09-25", "status": "current", ...}
  ],
  ...
}
Every plan

Tell "no permit" apart from "no data"

A clean history is only useful if you know the city is covered. When nothing matches, the answer carries a coverage block. In a jurisdiction we hold and keep current it says so, with the data-through date and the number of permits on file. Where we do not cover the city it says to treat the result as unknown. Route the second case to your usual inspection or third-party process.

covered city: no permit on record
# An address with no permits in Boulder, CO
curl "https://api.permit-stack.com/v1/property/history?address=9999%20Arapahoe%20Ave\
&city=Boulder\
&state=CO" \
  -H "X-API-Key: pk_your_key_here"
response (truncated)
{
  "found": false,
  "total_matches": 0,
  "coverage": {
    "confidence": "high",
    "covered": true,
    "jurisdiction": "Boulder",
    "data_through": "2026-09-27",
    "freshness": "current",
    "note": "Boulder is an actively-updated covered jurisdiction
      (338,034 permits on file, data through 2026-09-27). A 'no record'
      result here most likely means no permit exists for this address
      ...", ...
  }, ...
}
city we do not cover: unknown
# An address in a Texas city we do not cover
curl "https://api.permit-stack.com/v1/property/history?address=1000%20S%20Polk%20St\
&city=Amarillo\
&state=TX" \
  -H "X-API-Key: pk_your_key_here"
response (truncated)
{
  "found": false,
  "total_matches": 0,
  "coverage": {
    "confidence": "none",
    "covered": false,
    "note": "This address's city does not match one of our covered
      jurisdictions (we cover 47 active jurisdiction(s) in TX). Treat
      'no record' as UNKNOWN unless the city itself is covered.", ...
  }, ...
}
Every paid plan

Roofing activity after a weather event

After hail or wind, count roofing permits filed or issued in the affected city or ZIP to size restoration activity, then page through the addresses to match against your book. count_only=true skips the rows and returns just the total. Totals are exact up to 10,000; above that the API says total_capped rather than inventing a number.

request
# Roofing permits in Fort Worth since July 1
curl "https://api.permit-stack.com/v1/permits/search?city=Fort%20Worth\
&state=TX\
&category=roofing\
&date_after=2026-07-01\
&count_only=true" \
  -H "X-API-Key: pk_your_key_here"
response (truncated)
{
  "total": 217,
  "results": [],
  "total_capped": false,
  "total_unknown": false, ...
}
Business and above

Refresh the whole book without re-querying it

/v1/permits/sync is a cursor-based change feed: load a state or category once, then after each nightly ingest pull only the permits that are new or changed and join them to your policies on your side. Pages hold up to 50,000 permits. Developer plans can instead register webhooks (up to 10 per key) filtered by city, state, ZIP, category or keyword, dispatched within about 60 seconds of a permit reaching us.

request
# Texas roofing permits new or changed since Sept 28
curl "https://api.permit-stack.com/v1/permits/sync?state=TX\
&category=roofing\
&since=2026-09-28T00:00:00Z" \
  -H "X-API-Key: pk_your_key_here"
response (truncated, address redacted)
{
  "results": [
    {"permit_number": "RES-ROOF-26-001583", "status": "FILED",
     "category": "ROOFING", "property_type": "RESIDENTIAL",
     "address_street": "[redacted]", "address_city": "Dallas",
     "address_state": "TX", "address_zip": "75208",
     "description_raw": "RE-ROOF ON PROPERTY, REMOVE EXISTING ROOF, ...",
     "date_filed": "2026-09-12", "estimated_value": null,
     "updated_at": "2026-09-28T01:52:01Z", ...}
  ],
  "count": 1,
  "has_more": true,
  "next_cursor": "2026-09-28T01:52:01.633660+00:00|28b9589d-..."
}
Every plan (contact details on Developer and above)

Contractor vetting on claims

Check that the roofer or restoration company on a claim has a permit track record: /v1/contractors/search returns permit counts, first and last permit dates, specialties and the licence number where the source publishes one. /v1/contractors/{id}/permits lists the jobs themselves.

request
# A Seattle commercial roofer
curl "https://api.permit-stack.com/v1/contractors/search?name=Axiom%20Division%207\
&state=WA" \
  -H "X-API-Key: pk_your_key_here"
response (truncated)
{
  "total": 4,
  "results": [
    {"name": "Axiom Division 7 Inc",
     "license_number": "AXIOMD7920CF", "license_state": "WA",
     "city": "SEATTLE", "state": "WA",
     "total_permits": 43,
     "first_permit_date": "2017-07-10",
     "last_permit_date": "2026-09-10",
     "specialties": ["roofing"], "score": 74, ...},
    ...
  ]
}

What a permit record can and cannot prove

A dated roof permit is strong evidence. An empty history is weak evidence unless the source is covered and current, so the API says which case you are in.

Check your market before you pay

The coverage check is free and needs no account. It answers with the permits we hold for a city over the last 12 months, the date each source's data runs through, and whether that source is current or lagging. The same box sits in the pricing section of the homepage.

coverage_check.sh
curl "https://api.permit-stack.com/v1/coverage/check?city=Austin&state=TX"

Which plan fits

Quote-time lookups and book refreshes both fit on Business for most carriers and MGAs. Developer suits a pilot on a few markets; Scale is for national books.

Developer

$79/mo
or $790/year, two months free
  • 10,000 requests/day, 60/min
  • Webhooks (up to 10 per key)
  • /v1/metrics monthly series and city rankings
  • CSV export up to 50,000 rows per request
  • fields=full on search
Best fit for most teams

Business

$149/mo
or $1,490/year, two months free
  • 100,000 requests/day, 200/min
  • /v1/permits/sync change feed (cursor-based)
  • Property-owner mailing address, where the county publishes it
  • CSV export up to 200,000 rows per request
  • Priority support

Scale

$499/mo
or $4,990/year, two months free
  • 500,000 requests/day, 500/min
  • Everything in Business
  • 500 saved searches
  • Same-business-day support
  • Up to 2 prioritised coverage requests per quarter (best effort)

Every plan is self-serve through Stripe and you can start on the free tier (100 requests/day, last 30 days of permits). For licensing or redistribution, email support@permit-stack.com.

Questions we get from insurance teams

Can I get roof age from permit data?

You can get the date of the most recent roofing permit on record: /v1/property/history returns last_roofing_date alongside the full permit list for the address. That is the last permitted roof work, which is usually the replacement date. If the roof was replaced without a permit, or before the source's history begins, it will not appear, so check first_permit_date and the coverage block.

How do I know whether an empty result means no permits?

Every found: false answer carries a coverage block. In a covered, current jurisdiction it reads covered: true with confidence high and a data-through date. Where we do not cover the city it reads covered: false and tells you to treat the result as unknown.

Which risk signals are available beyond the roof?

The signals block reports the latest HVAC, solar and pool permit dates and flags battery storage, additions, new construction, demolition, electrical and plumbing work. Solar permits include system size in kW where the source states it.

How fresh is the data?

Sources are polled daily, with the main ingest at 03:00 UTC, and webhooks are dispatched within about 60 seconds of a permit reaching us. Some cities publish weeks after the fact, which is why every jurisdiction reports its own data_through date.

Which plan fits an insurer?

Business ($149/mo) fits most carriers and MGAs: 100,000 requests a day for quote-time lookups, the /v1/permits/sync change feed for book refreshes, and 200,000-row CSV exports. Scale ($499/mo) raises that to 500,000 requests a day with same-business-day support. For licensing or redistribution, email support@permit-stack.com.

Is my market covered?

Check before you pay. GET https://api.permit-stack.com/v1/coverage/check?city=Austin&state=TX needs no key and returns the permits we hold for that city over the last 12 months and how current each source is. The same check is in the pricing section of the homepage.

Rate the roof on the record

117M+ permits · 6.7M+ roofing · 887 active data sources · data-through date on every answer

Get Free API Key See pricing