How HVAC and heat pump contractors find homes with 20+ year old furnaces

Photo of Alex Wilkinson
Alex Wilkinson
CEO of Houski
2024-02-28

If you install furnaces, boilers, or heat pumps in the United States or Canada, you already know the math. The closer a home is to needing a system replacement, the higher your conversion rate. Cold-calling random neighbourhoods is expensive. Buying generic homeowner lists is worse. What you actually need is a way to filter homes by the age of their existing heating system and the type of system they have today.

That is exactly what Houski's property API was built for. With one query you can pull every detached home in your service area where the construction year suggests a furnace at end of life, then layer in heating type to separate gas furnace swap-outs from boiler conversions from prime heat pump candidates.

Why furnace age is the best lead signal you are not using

The average gas furnace has a service life of 15 to 20 years. Boilers can stretch to 25 or 30. Older central air units typically last 12 to 15 years. If a home was built in 2003 and still has its original forced air system, that system is on borrowed time. The homeowner has either already started getting nervous about the next breakdown, or they will be inside the next two heating seasons.

These are the homeowners who say yes to a quote. They are also the ones who qualify for the federal Oil to Heat Pump Affordability program (per Natural Resources Canada, the Canada Greener Homes Grant stopped accepting new applications in February 2024 and the final document upload deadline for existing applicants was December 31, 2025, while the Greener Homes Loan closed to new applications on October 1, 2025), plus provincial and utility rebates in British Columbia, Quebec, Nova Scotia, and elsewhere that stack on top. South of the border the federal section 25C tax credit ended with installs completed by December 31, 2025, and what remains is the state-run electrification rebate of up to $8,000 for income-qualified households, open in about a dozen states and rolling out through 2027, plus utility rebates from Xcel Energy, Puget Sound Energy, the New York and Massachusetts utilities, and the California programs.

A targeted list of homes built before 2005 with forced air heating is gold. The question is how to get one without a six-figure data contract.

Pulling the list with the Houski properties endpoint

Here is a working example that pulls single-family homes in Calgary built before 2005, currently on a gas furnace, with the address fields you need to mail or knock. The block below is a live call against the real API, the request code and the JSON response are generated every time this page is rendered:

API request
TypeScript code
const houski_data = async (): Promise<PropertiesResponse> => {

    // You must copy the PropertiesResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/properties');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'calgary');
    url.searchParams.set('construction_year_gte', '1980');
    url.searchParams.set('construction_year_lte', '2004');
    url.searchParams.set('country_abbreviation', 'ca');
    url.searchParams.set('heating_type_first_eq', 'Gas furnace');
    url.searchParams.set('property_type_in', 'House,Duplex');
    url.searchParams.set('province_abbreviation', 'ab');
    url.searchParams.set('select', 'address,community,postal_code,construction_year,heating_type_first,interior_sq_m,bedroom,estimate_list_price,latitude,longitude');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: PropertiesResponse = await houski_data();

// Log the response
console.log(data);
})();
API response
JSON
{
  "cache_hit": false,
  "cost_cents": 3.359999656677246,
  "data": [
    {
      "address": "52 Cedargrove Way SW",
      "bedroom": 5,
      "community": "Cedarbrae",
      "construction_year": 1984,
      "estimate_list_price": 645001,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 119.8449249267578,
      "latitude": 50.95145034790039,
      "longitude": -114.12571716308594,
      "postal_code": "T2W4V2",
      "property_id": "1000c277cd905d3b"
    },
    {
      "address": "28 Sundown Gr SE",
      "bedroom": 4,
      "community": "Sundance",
      "construction_year": 1988,
      "estimate_list_price": 697003,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 178.2809295654297,
      "latitude": 50.899044036865234,
      "longitude": -114.04895782470705,
      "property_id": "1001109ab2aebbc0"
    },
    {
      "address": "117 Sandpiper Place NW",
      "bedroom": 3,
      "community": "Sandstone Valley",
      "construction_year": 1988,
      "estimate_list_price": 733488,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 162.53387451171875,
      "latitude": 51.13548278808594,
      "longitude": -114.09813690185548,
      "postal_code": "T3K3T9",
      "property_id": "1001217184d8717b"
    },
    {
      "address": "7237 California Boulevard NE",
      "bedroom": 4,
      "community": "Monterey Park",
      "construction_year": 1995,
      "estimate_list_price": 648439,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 175.95835876464844,
      "latitude": 51.07606506347656,
      "longitude": -113.92584991455078,
      "postal_code": "T1Y6Y8",
      "property_id": "1001392d95458fc1"
    },
    {
      "address": "188 Mount Aberdeen Close SE",
      "bedroom": 3,
      "community": "McKenzie Lake",
      "construction_year": 1999,
      "estimate_list_price": 436317,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 114.5959014892578,
      "latitude": 50.93125915527344,
      "longitude": -113.97802734375,
      "postal_code": "T2Z3N2",
      "property_id": "1001894d82aeeb0c"
    },
    {
      "address": "121 Prestwick Way SE",
      "bedroom": 2,
      "community": "McKenzie Towne",
      "construction_year": 2001,
      "estimate_list_price": 508564,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 98.8488311767578,
      "latitude": 50.92182540893555,
      "longitude": -113.96497344970705,
      "postal_code": "T2Z3W7",
      "property_id": "1001f28c96629974"
    }
  ],
  "error": "",
  "pagination": {
    "current_page": 1,
    "has_next_page": true,
    "has_previous_page": false,
    "page_total": 22234
  },
  "price_quote": false,
  "result_total": 133401,
  "time_ms": 179,
  "ui_info": {
    "city": "Calgary",
    "city_id": "6ec95b53075d062c",
    "city_link": "ca/ab/calgary",
    "city_slug": "calgary",
    "country": "Canada",
    "country_abbreviation": "CA",
    "country_abbreviation_id": "9ace2b6431b7f1be",
    "country_abbreviation_link": "ca",
    "country_slug": "canada",
    "province": "Alberta",
    "province_abbreviation": "AB",
    "province_abbreviation_id": "aae1f05a0f89d2c7",
    "province_abbreviation_link": "ca/ab",
    "province_slug": "alberta"
  }
}

A run like this will pull thousands of qualified addresses across a city the size of Calgary. The same pull for Denver, a market with the same climate and the same furnace stock, with the state in the province_abbreviation parameter:

API request
TypeScript code
const houski_data = async (): Promise<PropertiesResponse> => {

    // You must copy the PropertiesResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/properties');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'denver');
    url.searchParams.set('construction_year_gte', '1980');
    url.searchParams.set('construction_year_lte', '2004');
    url.searchParams.set('country_abbreviation', 'us');
    url.searchParams.set('heating_type_first_eq', 'Gas furnace');
    url.searchParams.set('property_type_in', 'House,Duplex');
    url.searchParams.set('province_abbreviation', 'co');
    url.searchParams.set('select', 'address,community,postal_code,construction_year,heating_type_first,interior_sq_m,bedroom,estimate_list_price,latitude,longitude');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: PropertiesResponse = await houski_data();

// Log the response
console.log(data);
})();
API response
JSON
{
  "cache_hit": false,
  "cost_cents": 3.359999656677246,
  "data": [
    {
      "address": "B 1865 W Mosier Place",
      "bedroom": 2,
      "community": "Ruby Hill",
      "construction_year": 1983,
      "estimate_list_price": 310163,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 92.53142547607422,
      "latitude": 39.69609451293945,
      "longitude": -105.0097427368164,
      "postal_code": "80223",
      "property_id": "100fc407f5fc68df"
    },
    {
      "address": "71 400 S Steele Street",
      "bedroom": 4,
      "community": "Belcaro",
      "construction_year": 1989,
      "estimate_list_price": 3662103,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 502.23382568359375,
      "latitude": 39.709442138671875,
      "longitude": -104.94965362548828,
      "postal_code": "80209",
      "property_id": "101226e515be2994"
    },
    {
      "address": "9583 W Saratoga Place",
      "bedroom": 4,
      "community": "Marston",
      "construction_year": 1987,
      "estimate_list_price": 626482,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 175.95835876464844,
      "latitude": 39.62961196899414,
      "longitude": -105.10567474365234,
      "postal_code": "80123",
      "property_id": "1015be87e7a67d41"
    },
    {
      "address": "1940 S Raritan Street",
      "bedroom": 2,
      "community": "College View - South Platte",
      "construction_year": 1983,
      "estimate_list_price": 662345,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 87.70046997070312,
      "latitude": 39.68170928955078,
      "longitude": -105.00853729248048,
      "property_id": "101bc53d5024a7fa"
    },
    {
      "address": "2733 W Asbury Avenue",
      "bedroom": 2,
      "community": "College View - South Platte",
      "construction_year": 1983,
      "estimate_list_price": 555652,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 87.70046997070312,
      "latitude": 39.68073654174805,
      "longitude": -105.02129364013672,
      "postal_code": "80219",
      "property_id": "101e8abbd85490ee"
    },
    {
      "address": "4105 N Dunkirk Court",
      "bedroom": 3,
      "community": "Gateway - Green Valley Ranch",
      "construction_year": 1994,
      "estimate_list_price": 449872,
      "heating_type_first": "Gas furnace",
      "interior_sq_m": 158.30677795410156,
      "latitude": 39.773193359375,
      "longitude": -104.76210021972656,
      "postal_code": "80249",
      "property_id": "102be3e47f4e4e0b"
    }
  ],
  "error": "",
  "pagination": {
    "current_page": 1,
    "has_next_page": true,
    "has_previous_page": false,
    "page_total": 2047
  },
  "price_quote": false,
  "result_total": 12277,
  "time_ms": 125,
  "ui_info": {
    "city": "Denver",
    "city_id": "51cf91a470bf90bc",
    "city_link": "us/co/denver",
    "city_slug": "denver",
    "country": "United States",
    "country_abbreviation": "US",
    "country_abbreviation_id": "c148472ce4bd39d",
    "country_abbreviation_link": "us",
    "country_slug": "united_states",
    "province": "Colorado",
    "province_abbreviation": "CO",
    "province_abbreviation_id": "39e81999af72676b",
    "province_abbreviation_link": "us/co",
    "province_slug": "colorado"
  }
}

Swap the city and the province or state for your service area, and you have a clean prospect list.

Three plays this list unlocks

1. Heat pump conversion campaigns

Filter for homes with heating_type_first set to gas furnace and a construction_year between 1990 and 2005. These are perfect candidates for a cold climate air source heat pump retrofit because the ductwork is already in place. The homeowner is staring down a furnace replacement decision, and stacked state, provincial, and utility rebates push the math toward a heat pump over a like-for-like gas swap.

Direct mail with a quote example that subtracts the rebate gets opened. A flyer that says "your neighbour at 123 Maple just got a new system for $X after rebates" converts.

2. Boiler conversion and high-efficiency upgrades

Filter heating_type_first to hot water or in-floor, restrict to homes built before 1990, and you have a list of homeowners with cast iron radiators or in-floor systems hitting end of life. These are higher-ticket jobs with longer sales cycles and very little competition from generic heating, ventilation, and air conditioning (HVAC) marketing. Combine with foundation_type to flag homes with crawlspaces or older basements where a system replacement gets logistically interesting.

3. Air conditioning retrofit on furnace-only homes

Plenty of furnace homes have never had central cooling added. Cooling is only recorded when a record explicitly notes it, so you cannot reliably filter on its absence. Target the dependable signal instead: a gas furnace in a home built before 2010 in a hot market like Toronto, Hamilton, or the Okanagan, or in Seattle and Portland, where most of the housing stock was built without cooling and the heat domes since 2021 changed minds. Those owners are prime candidates for a heat pump that adds cooling and trims heating bills in a single install. The cooling_type_first field comes back on every row so you can scan it as you work the list. The live call below pulls that list for Toronto:

API request
TypeScript code
const houski_data = async (): Promise<PropertiesResponse> => {

    // You must copy the PropertiesResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/properties');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'toronto');
    url.searchParams.set('construction_year_lte', '2010');
    url.searchParams.set('country_abbreviation', 'ca');
    url.searchParams.set('heating_type_first_eq', 'Gas furnace');
    url.searchParams.set('province_abbreviation', 'on');
    url.searchParams.set('select', 'address,community,postal_code,construction_year,heating_type_first,cooling_type_first,latitude,longitude');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: PropertiesResponse = await houski_data();

// Log the response
console.log(data);
})();
API response
JSON
{
  "cache_hit": false,
  "cost_cents": 2.15999984741211,
  "data": [
    {
      "address": "2202 62 Forest Manor Road",
      "community": "Henry Farm",
      "construction_year": 1967,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.773887634277344,
      "longitude": -79.34544372558594,
      "postal_code": "M2J0B6",
      "property_id": "10000a939ca95e87"
    },
    {
      "address": "504 35 Walmer Road",
      "community": "Annex",
      "construction_year": 1960,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.6690788269043,
      "longitude": -79.40582275390625,
      "postal_code": "M5R2X3",
      "property_id": "100016a8f4f4f1a9"
    },
    {
      "address": "1108 2261 Lake Shore Boulevard W",
      "community": "Mimico",
      "construction_year": 1952,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.6201057434082,
      "longitude": -79.48355865478516,
      "postal_code": "M8V3X1",
      "property_id": "10002ea98a9d7121"
    },
    {
      "address": "546 Indian Grove",
      "community": "Junction Area",
      "construction_year": 1960,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.6655387878418,
      "longitude": -79.46244812011719,
      "postal_code": "M6P2J4",
      "property_id": "1000336e22bf06cc"
    },
    {
      "address": "53 Sellers Avenue",
      "community": "Corso Italia-Davenport",
      "construction_year": 1960,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.682369232177734,
      "longitude": -79.4459228515625,
      "postal_code": "M6E3T7",
      "property_id": "10005963503d7807"
    },
    {
      "address": "89 Deanscroft Square",
      "community": "West Hill",
      "construction_year": 1940,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 43.76536178588867,
      "longitude": -79.17636108398438,
      "postal_code": "M1E4W8",
      "property_id": "1000800c144981c8"
    }
  ],
  "error": "",
  "pagination": {
    "current_page": 1,
    "has_next_page": true,
    "has_previous_page": false,
    "page_total": 195030
  },
  "price_quote": false,
  "result_total": 1170180,
  "time_ms": 137,
  "ui_info": {
    "city": "Toronto",
    "city_id": "6cdbdee2492718ed",
    "city_link": "ca/on/toronto",
    "city_slug": "toronto",
    "country": "Canada",
    "country_abbreviation": "CA",
    "country_abbreviation_id": "9ace2b6431b7f1be",
    "country_abbreviation_link": "ca",
    "country_slug": "canada",
    "province": "Ontario",
    "province_abbreviation": "ON",
    "province_abbreviation_id": "146699ee774499d3",
    "province_abbreviation_link": "ca/on",
    "province_slug": "ontario"
  }
}

And for Seattle:

API request
TypeScript code
const houski_data = async (): Promise<PropertiesResponse> => {

    // You must copy the PropertiesResponse type declarations from the 
    // Houski API documentation to strongly type the response

    const url = new URL('http://127.0.0.1:8080/properties');
    url.searchParams.set('api_key', 'YOUR_API_KEY');
    url.searchParams.set('city', 'seattle');
    url.searchParams.set('construction_year_lte', '2010');
    url.searchParams.set('country_abbreviation', 'us');
    url.searchParams.set('heating_type_first_eq', 'Gas furnace');
    url.searchParams.set('province_abbreviation', 'wa');
    url.searchParams.set('select', 'address,community,postal_code,construction_year,heating_type_first,cooling_type_first,latitude,longitude');

    const response = await fetch(url);
    const data = await response.json();

    return data;
}

(async () => {
let data: PropertiesResponse = await houski_data();

// Log the response
console.log(data);
})();
API response
JSON
{
  "cache_hit": false,
  "cost_cents": 2.15999984741211,
  "data": [
    {
      "address": "3909 Bagley Avenue N",
      "community": "Wallingford",
      "construction_year": 1922,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 47.65465545654297,
      "longitude": -122.33294677734376,
      "postal_code": "98103",
      "property_id": "10002db4938ab07e"
    },
    {
      "address": "4107B 26 Avenue SW",
      "community": "North Delridge",
      "construction_year": 2006,
      "cooling_type_first": "None",
      "heating_type_first": "Gas furnace",
      "latitude": 47.566619873046875,
      "longitude": -122.3658447265625,
      "postal_code": "98106",
      "property_id": "10010e3297370ee9"
    },
    {
      "address": "5524 Winston Avenue S",
      "community": "Mid-Beacon Hill",
      "construction_year": 1992,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 47.551795959472656,
      "longitude": -122.29320526123048,
      "postal_code": "98108",
      "property_id": "100175b97640c0a4"
    },
    {
      "address": "700 W Prospect Street",
      "community": "West Queen Anne",
      "construction_year": 1925,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 47.62889099121094,
      "longitude": -122.36670684814452,
      "postal_code": "98119",
      "property_id": "1002e1fdb2befc10"
    },
    {
      "address": "2640 47 Avenue SW",
      "community": "North Admiral",
      "construction_year": 1907,
      "cooling_type_first": "None",
      "heating_type_first": "Gas furnace",
      "latitude": 47.58001708984375,
      "longitude": -122.39163970947266,
      "postal_code": "98116",
      "property_id": "1003d5a79ac21d22"
    },
    {
      "address": "9811 35 Avenue SW",
      "community": "Arbor Heights",
      "construction_year": 1953,
      "cooling_type_first": "Central",
      "heating_type_first": "Gas furnace",
      "latitude": 47.515254974365234,
      "longitude": -122.37689971923828,
      "postal_code": "98126",
      "property_id": "10047d25c8cac5"
    }
  ],
  "error": "",
  "pagination": {
    "current_page": 1,
    "has_next_page": true,
    "has_previous_page": false,
    "page_total": 19215
  },
  "price_quote": false,
  "result_total": 115290,
  "time_ms": 74,
  "ui_info": {
    "city": "Seattle",
    "city_id": "6a23eb9e5bf4545c",
    "city_link": "us/wa/seattle",
    "city_slug": "seattle",
    "country": "United States",
    "country_abbreviation": "US",
    "country_abbreviation_id": "c148472ce4bd39d",
    "country_abbreviation_link": "us",
    "country_slug": "united_states",
    "province": "Washington",
    "province_abbreviation": "WA",
    "province_abbreviation_id": "bd83526ad9c0e644",
    "province_abbreviation_link": "us/wa",
    "province_slug": "washington"
  }
}

Layering in the rebate angle

The federal Oil to Heat Pump Affordability program still pays up to $10,000 to eligible oil-heating households converting to a cold climate heat pump, with registrations open until June 30, 2026 per Natural Resources Canada, and provincial and utility incentives can stack on top of that. (The earlier Canada Greener Homes Grant and the interest-free Greener Homes Loan, which offered up to $5,000 and up to $40,000 respectively, both stopped accepting new applications before 2026, though approved files are still being paid out.) Your sales pitch is much stronger when you can put a real after-rebate number in front of a homeowner whose furnace is already 22 years old.

In the United States the pitch leans on the state rebate where the household qualifies and on the utility rebate everywhere else, and both are income-tested before tax.

Houski returns demographic_income_median_pre_tax at the neighbourhood level in both countries, so you can also sort your list by neighbourhoods where the rebate-financed monthly payment math will resonate.

What it costs versus a generic list broker

A typical real estate or homeowner list broker charges $0.25 to $1.00 per name with no filtering for system age or heating type. You end up mailing apartments, condos, and homes that already had a new furnace installed last year. Your effective cost per qualified lead can hit $20 or more.

A Houski API plan starts at a $99 per month minimum, and that floor comfortably covers a filtered pull like the one above. A list of 5,000 qualified furnace-age forced-air homes in your service area works out to fractions of a cent per name, every name pre-qualified on the criteria that matter for your business.

Where to start

If you want to sketch out a campaign before committing, the /api-documentation/properties docs show every filter and field available. The aggregate endpoint at /api-documentation/aggregate is handy for sizing a market before you spend a dollar on print, so you can answer "how many homes in my service area match this profile?" in a single query.

Spin up an API key on the quick-start guide and run your first filter today. Your next install season starts with the right list.