Skip to main content

How to Append Roof Age to Your Roofing Customer List (Turn a Dead Database Into a Work Queue)

Emily Crawford, Home Maintenance Editor··31 min readRoofing Business Operations
On this page

Most roofing companies are sitting on a goldmine they treat like a junk drawer. It's the customer list. Years of estimates, inspections, repairs, past jobs, web form fills, trade-show badges, referral names a rep scribbled on a business card. Thousands of addresses, every one of them a household that once raised a hand or let you onto their property. And almost all of them are gathering dust because nobody knows which ones are worth a call today.

The instinct is to blast the whole list. Mail everyone, email everyone, have a rep dial down the alphabet. That's expensive, it annoys people who got a new roof from you four years ago, and it buries the handful of genuinely due homeowners under a thousand dead names. The smarter move is to add one piece of information to every row that changes everything: roughly how old is the roof at that address right now, and what storms has it taken since it went on. That single enrichment turns a flat list into a ranked work queue. The customers whose roofs are finally aging out float to the top, and the ones who are nowhere near due drop to the bottom where they belong until their time comes.

Appending roof age to a customer list is a concrete, repeatable data project. It has a clean sequence: get the file in order, standardize the addresses so they'll match, attach a roof-age range and storm signal to each one, score and segment the results, then load it back into your CRM and actually work it. Below is the full workflow, the field structures, the matching gotchas that wreck these projects, worked examples with real numbers, and the honest limits of what a roof-age append can and can't tell you. Done right, it's the cheapest pipeline a roofing company owns, because you already paid to acquire every name on it.

Why roof age is the field your CRM is missing

Your CRM probably tracks name, address, phone, email, and a job history. What it almost never tracks is the one variable that determines whether a homeowner is in-market: the condition and age of the thing you sell. A roofer's product has a service life. Asphalt shingles, the overwhelming majority of the residential stock you'll ever touch, give you somewhere around 15 to 20 years of real protection for standard 3-tab and roughly 20 to 30 for architectural, less in brutal sun and hail country. That means every roof you've ever quoted is on a clock, and the clock is the single best predictor of when that household becomes a buyer again.

Without a roof-age field, your database is timeless in the worst way. A name you collected in 2009 looks identical to one from last month. You can't tell the 22-year-old roof you bid and lost from the 6-year-old roof you installed. So you treat them the same, which means you either ignore both or pester both. Add an age range to every row and the list sorts itself: the homeowner whose roof is reading 19 to 23 years old is a call worth making this week; the one you re-roofed in 2021 is a referral and review request, not a sales pitch.

There's a second reason this field matters more for roofers than almost any other trade. The thing that ages a roof fastest isn't time, it's weather. A hailstorm can put a decade of wear on a roof in fifteen minutes. So the complete version of the field isn't just age, it's age plus storm exposure: how old the roof is, and what the sky has done to it since. Stack those two and you don't just know who's due on the calendar, you know whose roof a storm may have pushed over the edge ahead of schedule.

What "roof age" really means before you append it

Set expectations honestly up front, because the contractors who get burned on these projects are the ones who expected a precision the data can't deliver. Roof age, appended at scale, is a range, not a date. Nobody can hand you a file that says the roof at 412 Maple went on July 9, 2008. What good enrichment gives you is a defensible bracket: this roof reads 16 to 20 years old, or this one reads under 5. That range is built from a few overlapping signals, none of them perfect alone:

  • Aerial and satellite imagery, read for surface condition (granule loss, color uniformity, curling, algae streaking, visible patches) and, more powerfully, compared across historical captures to find the window when a roof changed from old-and-light to new-and-dark. That brackets a re-roof to a span of years.
  • County year-built data, a strong proxy in neighborhoods where roofs are largely original. A 2002 subdivision with no re-roof permits is full of ~23-year-old roofs.
  • Re-roof permit records, which confirm exactly which addresses got a new roof and when, where the jurisdiction requires and enforces permits. This is the most precise signal you'll get, but coverage is patchy because plenty of re-roofs go unpermitted.
  • Your own job history, which is the most accurate signal of all for the addresses you've actually worked. If you installed a roof in 2019, you know its age cold. Never let an append overwrite what you already know.

The append blends these into a per-address range. Treat it as a prioritization signal, not a measurement. You're going to call the homeowner, inspect the roof, and confirm everything anyway. The point of the field is to decide who to call first, and for that, a range is plenty.

Step 1: Get your list export-ready

Before anyone can append anything, your data has to leave your CRM in a clean, matchable shape. This step is unglamorous and it's where most projects quietly fail, because garbage addresses can't be matched to roofs, and unmatched rows are wasted money.

Pull the right fields

Export a flat file (CSV is universal) with, at minimum:

  • A unique record ID from your CRM. This is non-negotiable. It's the key you'll use to merge the appended data back in without creating duplicates or scrambling rows. If your CRM doesn't expose one, add a row number before you export and keep the original file untouched.
  • Street address, unit/apt, city, state, ZIP as separate columns where possible. A single mashed-together address column matches worse than parsed components.
  • Owner name, phone, email for working the list later (not needed for matching, but you want them riding along).
  • Any job history you have: last service date, what you did, roof material if known, original install date if you installed it.
  • Record source and date (web form 2021, past customer, bought list, trade show) so you can judge data quality and consent later.

Decide what's even worth appending

Not every row deserves the spend. Before you append, prune:

  • Commercial and multi-family addresses if you only do residential (or vice versa). Roof-age logic and the buying conversation are completely different.
  • Renters and obvious non-decision-makers where you can identify them. A renter can't authorize a roof.
  • Out-of-area addresses outside the territory your crews actually serve.
  • Records you installed recently — you already know the roof age, and it's young. Tag them for referral/review campaigns, not for the append.

What's left is your append universe: residential addresses, in your service area, where you don't already know the roof is new. That's the set worth spending on.

Step 2: Standardize and validate the addresses

This is the single highest-leverage step in the entire project, and the one contractors skip. Roof data is keyed to a physical address. If your address strings are messy, they won't match the roof, and an unmatched row returns nothing. The difference between a sloppy file and a clean one can be a 60 percent match rate versus a 95 percent one — and you're paying either way.

Run it through address standardization

The gold standard for U.S. addresses is CASS-certified standardization, the same system the USPS uses to validate and format deliverable mail. It does several things that directly raise your match rate:

  • Standardizes the format: "123 North Main Street Apartment 4" becomes the canonical "123 N MAIN ST APT 4" that data systems expect.
  • Corrects and completes ZIP codes, appending the ZIP+4 and the correct city/state.
  • Flags undeliverable, vacant, and non-existent addresses so you don't pay to append a ghost.
  • Appends a delivery point and, often, a stable unique address key that downstream systems match on far more reliably than raw text.

Many append vendors run this for you, but knowing it happened — and seeing the match/no-match report — is how you judge whether you got your money's worth.

De-duplicate before you spend

Lists accumulate duplicates: the same homeowner entered as a web lead, a past customer, and a bought-list record, often with three spellings of the street. Appending the same roof three times is wasted money and creates three competing rows in your CRM. Standardizing the addresses first makes duplicates visible (they collapse to the same canonical string), so de-dupe after standardization, not before. Keep the richest record as the survivor and merge the rest into it.

Fix or drop the unmatchable

After standardization you'll have a bucket of addresses that wouldn't validate: typos, PO boxes, partial addresses, rural routes without a street number. Triage them. The cheap ones to fix (an obvious typo, a missing ZIP a tool can fill) are worth saving. The hopeless ones (a PO box, "the blue house on County Road 7") get set aside — you can't append a roof to an address that doesn't resolve to a building.

A quick data-hygiene checklist

  • Every row has a stable unique ID I can merge back on.
  • Address components are parsed into separate columns.
  • The file has been run through CASS-certified standardization.
  • Undeliverable, vacant, and non-residential addresses are flagged.
  • Duplicates collapsed after standardization, richest record kept.
  • Renters/out-of-area/recently-installed rows pruned or tagged.
  • I kept an untouched copy of the original export.

Step 3: Append the roof-age range

Now the actual enrichment. You have three broad ways to attach a roof-age range to each clean address, and they trade off cost, speed, and scale.

Option A: Do it by hand (small lists, highest control)

For a few hundred addresses, a person can do this in-house. For each address: pull current aerial imagery and read condition, scan the imagery history for a re-roof transition, check county year-built, and look up re-roof permits where available. Record an age range and a confidence note. It's slow — figure a few minutes per address done well — but it's free if you have the labor, it's auditable, and it forces your team to learn what the signals actually look like. Use it when the list is small or when you want to spot-check an automated append.

Option B: Use a data/append vendor (large lists, hands-off)

For thousands of addresses, you hand the clean file to a service that matches each address to roof data and returns an enriched file. The good ones return an age range, a confidence level, and the signals behind it. This is the realistic path at list scale, because no sales manager is going to hand-read 8,000 roofs. The cost is per-record, so the data-hygiene work from Step 2 directly controls your bill — you don't want to pay to append unmatchable junk.

Option C: Append age and storm exposure together (the version built for roofers)

This is where a roofing-specific platform earns its place. RoofPredict is built to take a list of addresses and return, per address, an estimated roof-age range from aerial imagery and a storm-exposure signal modeled for that specific roof — the hail and wind that physically passed over that individual address, not a whole ZIP painted with one storm. For a roofer the storm layer isn't a nice-to-have; it's half the answer, because weather is what ages a roof off-schedule. An append that returns age alone tells you who's due on the calendar. An append that returns age plus per-roof storm exposure tells you who's due on the calendar and who a recent storm may have pushed there early.

A few honest things about what this kind of append does and doesn't do, because the category overclaims constantly:

  • It enriches, it doesn't prove. A high score means a roof is statistically likely to be old and storm-exposed — a strong reason to call and inspect. It is not evidence of damage on any specific roof. You confirm condition on the ladder, every time.
  • Age is a range, never a date. Aerial imagery can bracket when a roof changed; it cannot read an install date. Anyone selling you exact install dates from imagery is selling you confidence they don't have.
  • Storm exposure is odds and physics, not a damage report. A modeled 1.5-inch hail exposure means the roof was probably hit hard enough to matter. Whether it's actually damaged is a separate question answered by an inspection.
  • It's not a lead service and it doesn't call for you. It enriches the list you already own with the two signals that decide who's due. The selling is still yours.

Whichever option you choose, the output is the same shape: every matched address now carries a roof-age range and, ideally, a storm signal. Unmatched rows get flagged so you know what didn't enrich and can decide whether to fix and resubmit them.

The fields a good append returns

At minimum, a useful enriched file gives you, per address:

Field Example What it's for
Roof age range "16-20 yrs" Primary sort: how due on the calendar
Age confidence High / Medium / Low How much to trust the range; low = verify before acting
Last re-roof signal "permit 2018" / "none found" Negative filter: cross off recently redone roofs
Roof material (if read) Architectural asphalt Recalibrates the age threshold per address
Storm exposure "1.75in hail, 14 mo ago" The off-calendar pusher; recency matters
Match status Matched / No match Whether the row enriched at all

Don't accept an append that returns a bare number with no confidence and no signal trail. You need to know how sure the data is so you don't put your best rep on a low-confidence guess.

Step 4: Score and segment the enriched list

A file full of age ranges isn't a campaign yet. You have to turn the data into segments your team can act on. The cleanest way is a simple priority model that combines age and storm into a handful of buckets.

A four-bucket model

Lay every matched record into one of four buckets using age and storm exposure:

Roof age Storm exposure Bucket Play
Old (15+ yrs) Recent, significant A — Hot Call first. Age and storm both point to replacement.
Old (15+ yrs) Little / none B — Aging retail Call on end-of-life and condition. No storm clock; work steadily.
New (<7 yrs) Recent, significant C — Storm watch Young roof, real exposure. Worth an inspection offer.
New (<7 yrs) Little / none D — Dormant Don't sell. Referral/review/maintenance touch only.

Most of your immediate revenue is in bucket A. Bucket B is your steady, no-clock backfill — the reactivation calls you make in slow weeks. Bucket C is the storm-season exception worth a look. Bucket D isn't dead; it's just not now, and it stays in your nurture stream until age moves it up.

A simple per-record score you can compute in a spreadsheet

If you'd rather rank than bucket, score each record:

  1. Age score (0-50): scale the roof-age range against your material-adjusted end-of-life. A roof at 100 percent of expected life scores 50; one at half-life scores 25; a new roof scores near 0.
  2. Storm score (0-30): size of exposure (hail diameter / wind speed) times a recency decay (full points if recent and inside any actionable window, fading as it ages).
  3. Relationship score (0-20): boost records where you have history — a past customer or a homeowner you quoted converts far better than a cold bought-list name. Reward the warmth you already earned.

Sum to a 0-100 priority score, sort descending, and you have a call list ranked by who's most likely to need you and most likely to answer because they know your name. Work it top down.

Don't forget the negative filters

Scoring tells you who to call. Negative signals tell you who to skip, and skipping fast is half the productivity gain:

  • Recent re-roof permit or new-reading imagery → cross off, regardless of year-built.
  • You installed it → referral/review track, not a sales call.
  • Renter / absentee owner flag → deprioritize; they can't or won't decide.
  • Low age-confidence on a borderline record → verify with a windshield check or a soft call before committing a rep.

Step 5: Load it back into your CRM without making a mess

The enriched file is worthless until it's back in the system your team works from. This merge is where projects create duplicate contacts, overwrite good data with worse, and scramble rows — so do it deliberately.

Merge on the unique ID, never on name or address

This is why Step 1 insisted on a stable record ID. You merge the appended fields back onto the original records by that ID. Merging on name or address invites mismatches (two Smiths, a standardized address that no longer string-matches the original) and creates duplicates. ID-to-ID is clean.

Add new fields; don't overwrite what you know

Create dedicated custom fields in your CRM — roof_age_range, roof_age_confidence, last_reroof_signal, storm_exposure, roof_priority_bucket, append_date — and write the appended data into those. Never let an append overwrite a roof age you already know from your own job history; your install record beats any model. Stamp every appended record with the append date so you know how stale the enrichment is later.

Make the data actionable in the tools reps already use

Data nobody sees changes nothing. Wire the new fields into:

  • Saved views / smart lists for each bucket (Hot, Aging retail, Storm watch, Dormant) so a manager can pull "all bucket-A homeowners in these ZIPs" in one click.
  • Call and route lists sorted by priority score, handed to reps as a worklist, not a database dump.
  • Mail and email segments so the printer and the email tool pull from the same scored truth instead of a blanket export.

Plan to refresh it

A roof-age append is a snapshot. Roofs age, storms hit, homeowners re-roof. Bucket D records cross into B as they age out; bucket A records get worked and removed; new storms reshuffle everyone underneath them. Re-append on a sane cadence — annually for the age layer is reasonable, and after any significant storm for the exposure layer in the affected ZIPs. The append_date stamp tells you what's gone stale.

Mapping the fields into the CRM you actually run

The merge mechanics differ by platform, and the wrong approach in each one creates the same duplicate-and-overwrite mess. A few platform-specific notes so the load step doesn't undo the enrichment.

  • Roofing-specific CRMs (JobNimbus, AccuLynx, Leap, and the like). These usually let you create custom contact or job fields and bulk-import by a record key. Create the six append fields as custom fields first, then import the enriched file mapped to your existing record key — most of these tools choke if you import without a key and will happily make duplicate contacts. Check whether the import updates existing records or only inserts new ones; you want update-on-key.
  • General CRMs (HubSpot, Salesforce, Zoho). Use the platform's record ID or a custom external-ID field as the dedupe key on import. In HubSpot, an import that matches on Record ID updates in place; matching on email or address risks creating new contacts. In Salesforce, an upsert keyed on an External ID field is the clean pattern. Map the appended columns to custom fields you create beforehand.
  • Spreadsheet or mailing-house lists with no CRM. If your "CRM" is a spreadsheet, the append is even simpler: VLOOKUP or a join on the record ID brings the new columns alongside the originals. Keep the appended columns clearly named and dated, and hand the mailing house a filtered export (just the buckets you're mailing) rather than the whole sheet.

Whatever the platform, the rule is identical: create the destination fields first, import on a stable key, update-don't-duplicate, and never map an append column on top of a field you already trust.

The economics of an append, in plain numbers

Contractors hesitate on enrichment because it's a line item with no immediate job attached. It helps to frame it against what a lead actually costs. You don't need exact figures to see the shape of it — work it with your own numbers using this structure.

An append is priced per record, and after the hygiene step you're only paying to enrich matchable addresses. Compare that to acquisition: a purchased or generated roofing lead is a far larger per-unit cost, it arrives cold, and it's frequently sold to several competitors at once, so your close rate on it is diluted by the field you're fighting. The append works the opposite end of the funnel — warm households who already know you — at a fraction of the per-unit price.

The number that decides the project is your cost per surfaced opportunity: the total append spend divided by the count of genuinely due records it brings to the surface (your Hot and Aging-retail buckets). On a list of any real size, that figure tends to land well below what a single bought lead costs, and the surfaced records convert higher because they're warm. Run the arithmetic before you commit: spend, expected match rate, expected share of the matched file that lands in the due buckets, and your historical close rate on warm reactivation contacts. If the cost per surfaced opportunity beats your blended cost per acquired job, the append pays for itself on the first campaign — and unlike a lead, the enriched data keeps working until the next refresh.

The trap is judging the append by the dormant majority. Most of any list is dormant (newer roofs, not due), and that's fine — you're not paying for the dormant records to convert, you're paying for the data to separate the due minority from them so you stop wasting outreach on the wrong households. The dormant rows aren't a loss; they're the noise the append filters out so the signal is workable.

Turning the enriched list into a campaign

A scored, segmented, loaded list is still just data until a motion runs against it. Each bucket wants a different touch, and matching the motion to the bucket is where the enrichment turns into booked inspections.

Bucket A (Hot) — phone first, fast

These are old roofs with recent storm exposure, and they're time-sensitive because storm windows close and competitors saturate. Work them by phone, top-down by priority score, this month. The opener is warm and honest: you're an existing relationship checking in after the storm that came through, you're doing free inspections in the area, and you'd be glad to take a look. Because they know your name, contact and booking rates run far ahead of cold outreach. Don't let this bucket sit; its value decays.

Bucket B (Aging retail) — steady reactivation

Old roofs, no storm clock. These are your slow-week backfill, the calls and mailers that smooth the feast-or-famine cycle. There's no urgency, so work them as a standing reactivation rhythm: a monthly slice of the bucket gets a condition-led touch ("we noticed your roof is reaching the age where we usually start seeing wear; want a free, no-pressure assessment?"). Past customers in this bucket are gold — they've already bought from you once. Mine your own installed base here for the homes now aging out of warranty.

Bucket C (Storm watch) — soft inspection offer

Newer roofs with real storm exposure. Most won't need you, but a meaningful minority will have damage that warrants a look. A light touch is right: an email or a single call offering a free post-storm inspection, no hard sell. You're casting for the exceptions, not working the whole bucket hard.

Bucket D (Dormant) — nurture, don't sell

Newer roofs, no storm. Selling here annoys people and burns goodwill. Keep them in a low-frequency nurture stream — seasonal maintenance tips, a referral ask, a review request from anyone you installed — so you stay top-of-mind for when their roof eventually ages up into bucket B. The next refresh moves a chunk of D into B; your nurture is what keeps them yours when it does.

Close the loop

Whatever motion you run, log the result back against the record: contacted, inspection booked, inspected, signed, dead-and-why. Two payoffs. The dead-door reasons audit your append (if a Hot record logs "re-roofed last year," your re-roof signal missed one, and you tighten it next refresh). And the conversions tell you which buckets and ZIPs are paying, so you spend the next append where it earned. Over a few cycles this loop is what compounds a list into an asset instead of a one-time campaign.

A full worked example, start to finish

Concrete numbers make the workflow real. Say you're an operations lead at a residential roofer with a 12,000-record customer list built over fifteen years: past customers, lost estimates, web leads, two bought lists, and trade-show names.

Step 1 — Prune to the append universe. You drop 2,400 records: commercial addresses, known renters, out-of-area, and 1,300 homes you re-roofed in the last six years (tagged for referrals instead). You're left with 9,600 residential addresses worth appending.

Step 2 — Standardize. CASS standardization validates 9,100 of the 9,600. It flags 500 as undeliverable, PO boxes, or unresolvable. You salvage 180 obvious typos and discard 320. De-duplication collapses 700 duplicate households down. Clean, matchable universe: about 8,400 addresses.

Step 3 — Append age + storm. The enrichment matches 7,950 of the 8,400 (a 95 percent match rate, thanks to the clean addresses) and flags 450 no-matches. Each matched row comes back with an age range, confidence, re-roof signal, material, and storm exposure.

Step 4 — Score and segment. The buckets fall out:

  • Bucket A (Hot — old + recent storm): about 1,150 records.
  • Bucket B (Aging retail — old, no storm): about 2,600 records.
  • Bucket C (Storm watch — newer + storm): about 700 records.
  • Bucket D (Dormant — newer, no storm): about 3,500 records.

The append just told you that roughly 1,150 households in a list you already owned are due right now and storm-exposed, with another 2,600 due on age alone. Before the append those 3,750 names were indistinguishable from the 3,500 dormant ones.

Step 5 — Work it. You load the buckets back into the CRM on record ID, build saved views, and run three motions: reps call bucket A top-down by priority score this month; bucket B becomes the steady reactivation call list for slow weeks; bucket C gets a soft "we're inspecting roofs after the storm" touch. Bucket D stays in the nurture stream, and you re-append next year when a chunk of it crosses into B.

The math that matters: you didn't buy a single new lead. You spent on cleaning and enriching a list you already owned, and surfaced ~1,150 immediate prospects who already know your name. That's the cheapest pipeline in the building.

What pros get wrong

The same mistakes sink these projects across the industry. Avoiding them is most of the edge.

Appending a dirty list. Skipping standardization to save a step tanks your match rate and you pay to append rows that never resolve. The hygiene work in Step 2 isn't optional overhead; it's what determines whether 60 percent or 95 percent of your spend returns anything.

Treating the age range as a date. Telling a homeowner "our records show your roof was installed in 2007" when the append says "16 to 20 years" is dishonest and it'll blow up on the first homeowner who re-roofed in 2015. The range is a targeting signal. Speak in ranges and conditions, not manufactured precision.

Ignoring the relationship score. A past customer or a homeowner you once quoted is worth several cold bought-list names, because they answer the phone and they remember you. Many contractors append everything equally and forget that the warm records on their own list are the highest-converting rows in the file. Mine your own book first.

Merging on address instead of ID. This is the classic CRM disaster: duplicate contacts multiply, notes get orphaned, and reps call the same homeowner twice with different scripts. Merge on the stable record ID, always.

Overwriting known data. Letting an append stomp on a roof age you know from your own install record throws away your most accurate signal to replace it with a model's estimate. New fields, never overwrite.

Appending once and never refreshing. A one-time append decays. Roofs age into the hot bucket every year and storms reshuffle the deck. The contractors who win treat enrichment as a recurring rhythm, not a one-off purchase.

Confusing exposure with damage on the phone. "Our data shows you have hail damage" is wrong on the facts and a compliance problem. The data shows exposure and age — a reason to inspect. You document actual condition on the roof. Keep those words straight (more on this below).

Edge cases that break the simple model

The age-plus-storm append is the right backbone, but a few situations don't fit cleanly.

Roofs you installed under solar. A homeowner with solar panels almost certainly had a sound roof when the panels went on, and detaching and resetting panels for a re-roof is expensive enough that they delay. Flag solar addresses as lower priority and factor detach-reset into any conversation.

Mixed-material neighborhoods. Your end-of-life math changes by material. A 2010 architectural-shingle tract isn't an age play in 2025; a 2008 3-tab tract is. If the append returns material, use it to recalibrate the threshold per address instead of applying one age number everywhere.

Stale imagery on fresh re-roofs. Aerial captures refresh on a cadence that varies by area — yearly in dense suburbs, every few years in rural zones. A roof redone last spring may still read old in last year's capture, so the freshest-looking "due" records deserve a windshield check before a rep commits a day. The re-roof permit signal and a soft confirming call catch most of these.

Bought-list records with thin consent. Some of your list came from purchased data. Before you blast it, mind your contact-consent obligations: honor the Telephone Consumer Protection Act and the FTC's telemarketing and Do-Not-Call rules for calls and texts, and CAN-SPAM for email. A roof-age append makes the list smaller and sharper, which actually helps compliance — you're contacting fewer, more relevant people — but it doesn't manufacture consent you never had. Scrub against the Do-Not-Call registry and respect opt-outs.

Absentee and rental conversions. A street that scores well on age can convert poorly if it's heavy with rentals and absentee owners who can't or won't decide. Where you can append owner-occupancy, let it deprioritize those records below their raw age score.

The storm-and-claims line you don't cross

A chunk of the value in appending storm exposure is that it surfaces roofs a recent storm may have damaged. That's legitimate and useful — but the moment a storm enters the conversation, you're in a regulated space, and the words you use matter. None of this is legal advice; check your own state's department of insurance. The principles that keep ethical contractors safe:

  • You document conditions and provide an estimate. The homeowner files. The insurer decides coverage. Stay in that lane. The append tells you which roofs likely qualify for a closer look on age and storm exposure; it does not tell you a claim will be approved, and neither should you.
  • Don't promise a payout, an approval, or that the damage "will be covered." That's the insurer's determination based on the policy and the documented damage, not yours to promise.
  • Don't offer to waive, rebate, or eat the deductible, and don't advertise a "free roof." In most states that's illegal and a fast way to lose your license. The deductible is the homeowner's responsibility.
  • Don't present storm exposure as proof of damage. The modeled exposure is a reason to inspect, not evidence. You establish damage on the roof and document it with photos and an accurate, Xactimate-aligned estimate of the repair, which you hand to the homeowner.
  • Don't interpret the homeowner's policy or negotiate the claim on their behalf for a fee. Documenting your own scope and stating facts about your work to the carrier is fine; adjusting or negotiating the claim is public adjusting, which is license-required.

Used correctly, the storm-exposure field simply helps you prioritize which past customers to call for an honest, free inspection after a storm. You look at the roof, you document what's actually there, you write an accurate estimate, and the homeowner takes it from there. That's both the compliant path and the one that earns referrals.

How this compares to buying new leads

It's worth being blunt about why enriching your own list beats the alternatives, because the trade is flooded with companies selling you fresh names.

A bought lead is a stranger who may have been resold to four of your competitors, with no relationship and no reason to trust you. Appending roof age to your existing list does the opposite: it works the households who already know your name — past customers, people you quoted, web visitors who reached out once — and tells you precisely which of them are due now. The acquisition cost is already sunk. You're paying cents per record to enrich, not dollars per lead to acquire, and the records convert better because the relationship is warm.

This isn't an argument against ever buying leads or running new acquisition. It's an argument for working the asset you already own first, because it's cheaper and converts higher, and most roofers leave it completely untapped. The append is what makes that asset legible. Without roof age, your list is a flat pile of names. With it, the list tells you who to call this week.

A manager's append-project checklist

Run the whole project against this:

  • Exported a flat file with a stable unique record ID per row.
  • Parsed address components into separate columns.
  • Pruned commercial, renter, out-of-area, and recently-installed records.
  • Ran CASS-certified address standardization; reviewed the match report.
  • De-duplicated after standardization, kept the richest record.
  • Chose an append path (in-house / vendor / age+storm platform) by list size.
  • Confirmed the append returns range + confidence + signal trail, not a bare number.
  • Scored and bucketed records (Hot / Aging retail / Storm watch / Dormant).
  • Applied negative filters (recent re-roof, you-installed-it, renter, low confidence).
  • Merged back into the CRM on record ID, into new fields, never overwriting known data.
  • Built saved views, call lists, and mail/email segments off the scored data.
  • Stamped every record with an append date and set a refresh cadence.
  • Briefed reps on exposure-vs-damage language and the claims compliance lines.

Bringing it together

Appending roof age to your customer list is the highest-leverage data project a roofing company can run, because it doesn't acquire anything — it makes what you already own usable. The sequence is the same every time: clean and standardize the addresses so they'll match, append an age range and, ideally, a per-roof storm signal, score and bucket the results, then load them back into your CRM on record ID and actually work the hot list. You can assemble the age layer by hand for small lists, hand a clean file to a vendor at scale, or use a roofing-specific platform like RoofPredict to return age and storm exposure together. Either way the logic holds: age is a range not a date, storm exposure is odds not proof, and the field exists to tell you who to call first — not to make a promise you'll have to break on the roof.

The companies that win the next slow season won't be the ones who buy the most leads. They'll be the ones who finally figured out that the most due, most reachable customers they have were sitting in the database the whole time, waiting for one field to surface them.

FAQ

What does it mean to append roof age to a customer list?

It means adding a new piece of data to every address in your CRM or mailing list: an estimated roof-age range for that specific home, ideally alongside its storm exposure. Instead of a flat list of names, you get a list you can sort by how close each roof is to the end of its service life. The customers whose roofs are aging out rise to the top, and the ones with new roofs drop down until their time comes.

How accurate is an appended roof age?

It's a range, not an exact date. Good enrichment brackets each roof — say 16 to 20 years — using aerial imagery condition and history, county year-built data, and re-roof permits where available. Nobody can return a precise install date from imagery at scale, and you should be suspicious of anyone who claims to. The range is accurate enough for its job, which is deciding who to call first. You confirm the real condition on the roof when you inspect.

Why is address standardization so important before appending?

Roof data is keyed to a physical address, so if your address strings are messy the data can't match and the row returns nothing. Running the file through CASS-certified standardization (the USPS validation standard) fixes formats, corrects ZIPs, flags undeliverable addresses, and adds a stable key data systems match on. It's the difference between a 60 percent and a 95 percent match rate, and since you pay per record either way, it directly controls your cost.

Should I append roof age myself or use a service?

It depends on list size. For a few hundred addresses, an in-house person can read aerial imagery, year-built, and permits per address — slow but free and auditable. For thousands of records, hand a clean file to a data or roofing-specific append vendor that returns enriched rows at scale; no sales manager will hand-read 8,000 roofs. A roofing platform that returns age plus per-roof storm exposure together is the most useful version for a contractor.

What's the difference between appending roof age and buying leads?

Buying leads acquires strangers, often resold to several competitors, with no relationship. Appending roof age enriches the list you already own — past customers, lost estimates, web inquiries — and tells you which of those warm households are due now. The acquisition cost is already sunk, so you pay cents per record to enrich instead of dollars per lead to acquire, and warm records convert better because the homeowner already knows your name.

What does RoofPredict actually do for a customer-list append, and what are its limits?

It takes a list of addresses and returns, per address, an estimated roof-age range from aerial imagery and a storm-exposure signal modeled for that specific roof rather than a whole ZIP painted with one storm. That gives you both signals that decide who's due. Its honest limits: it enriches and ranks, it doesn't prove damage; age is a range, never a date; storm exposure is odds and physics, not a damage report; and it doesn't call or sell for you. You still inspect every roof.

How do I merge the appended data back into my CRM without creating duplicates?

Merge on a stable unique record ID, never on name or address. Export with that ID intact, append the data, then join the new fields back onto the original records by ID. Write the data into dedicated new fields (roof age range, confidence, storm exposure, priority bucket, append date) rather than overwriting existing ones, and never let an append overwrite a roof age you already know from your own install history.

How often should I re-append roof age to my list?

Treat it as a recurring rhythm, not a one-time purchase. The age layer is reasonable to refresh annually, since roofs age into the due bucket every year. The storm-exposure layer should be refreshed after any significant storm in the affected ZIPs, because weather reshuffles priorities fast. Stamp every record with its append date so you can see what's gone stale and refresh selectively instead of redoing the whole list.

Can I use the appended storm data to tell customers their roof has damage?

No. The storm-exposure field tells you a roof was probably hit hard enough to be worth inspecting; it does not prove damage on any specific roof. Telling a homeowner the data shows they have damage is wrong on the facts and a compliance problem. Use it to prioritize which past customers to call for an honest, free inspection, then document the actual condition on the roof. The homeowner files any claim and the insurer decides coverage.

Generally yes for your own customers, but mind the rules, especially for bought-list records. Honor the Telephone Consumer Protection Act and FTC Do-Not-Call requirements for calls and texts, and CAN-SPAM for email. Scrub against the Do-Not-Call registry and respect opt-outs. Appending roof age actually helps compliance because it shrinks your outreach to fewer, more relevant homeowners, but it doesn't create consent you never had. Check your state's rules.

The Roofline by RoofPredict

Stay Ahead of Roofing Market Changes

Join The Roofline by RoofPredict for weekly roofing intelligence: material price signals, storm demand, insurance and regulatory updates, sales tactics, and local contractor opportunities.

By signing up, you agree to receive The Roofline by RoofPredict. Unsubscribe anytime.

Sources

  1. National Roofing Contractors Association (NRCA)nrca.net
  2. Insurance Institute for Business & Home Safety (IBHS)ibhs.org
  3. USPS CASS (Coding Accuracy Support System)postalpro.usps.com
  4. USPS Address Information Servicesusps.com
  5. FTC National Do Not Call Registry & Telemarketing Sales Ruleftc.gov
  6. FTC CAN-SPAM Act Compliance Guideftc.gov
  7. NOAA Storm Prediction Centerspc.noaa.gov
  8. National Weather Service Storm Reportsweather.gov
  9. U.S. Census Bureau Building Permits Surveycensus.gov
  10. International Residential Code (ICC)iccsafe.org
  11. Texas Department of Insurance: Roofing and Storm Claimstdi.texas.gov
  12. U.S. Bureau of Labor Statistics: Roofersbls.gov
  13. USGS / EarthExplorer Historical Aerial Imageryusgs.gov
  14. RoofPredictroofpredict.com

Related Articles