# MCS Certified Installers Scraper - UK Heat Pump & Solar Leads (`scrapersdelight/mcs-certified-installers-scraper`) Actor

From $13 per 1,000 installers, no start fee. The official MCS register of UK heat pump, solar PV and battery installers: email, phone, website, address, MCS cert number, Boiler Upgrade Scheme flag, technologies and regions covered. Filter by technology, region, BUS or miles from a postcode.

- **URL**: https://apify.com/scrapersdelight/mcs-certified-installers-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Business, Automation
- **Security:** Limited permissions
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$13.00 / 1,000 per mcs-certified installer returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## MCS Certified Installers Scraper - UK Heat Pump & Solar Installer Leads

Export the official **MCS (Microgeneration Certification Scheme) register** of UK renewables installers - the
heat-pump, solar PV, battery, biomass and wind installers a homeowner must use to get the **Boiler Upgrade Scheme**
grant (GBP 7,500 towards a heat pump) or be paid under the **Smart Export Guarantee**. MCS publishes every certified
installer's contact details so consumers can check eligibility; this actor turns that register into a clean,
deduplicated lead list.

**One row = one MCS-certified installer**, with the contact fields first: email, phone, website - then the MCS
certification number and body, whether they are registered for the Boiler Upgrade Scheme, the technologies they
are certified for, the regions they say they cover, their registered address and coordinates, and their MCS
profile URL.

**$13 per 1,000 installers ($0.013 each), no start fee.** You pay only for installers delivered to your dataset.

### Who buys this list

- **Heat pump, solar, inverter and battery manufacturers and distributors** recruiting installers into a network or
  trade-account programme - filter by technology, BUS-registered and region.
- **Green-finance lenders and BNPL providers** signing up installers as point-of-sale partners.
- **Energy suppliers** building approved-installer panels (heat pump, solar + battery, smart export).
- **Renewables lead-gen agencies, software vendors (quoting, design, CRM) and trade publishers** selling to installers.

### What you get - measured on the whole register

Measured on a live run of the full register on 2026-09-23 (5,614 installers, the whole population, not a sample):

| Field | Filled | Notes |
|---|---|---|
| `email` | **100.0%** | as published; MCS's own addresses (`@mcscertified.com` etc.) are never emitted |
| `phone` / `phoneE164` | **98.7%** | UK number canonicalised; 45% mobiles (`phoneType`) |
| `website` | **54.8%** | first real host from the published text; junk (emails, names, phone numbers typed into the website box) is dropped, the original kept in `websiteAsPublished` |
| all three (email + phone + website) | 54.5% | 3,061 installers |
| `certificationNumber`, `certificationBody` | 100% | e.g. `NAP-12995` / NAPIT, `ELC-54471` / NICEIC - unique per row |
| `boilerUpgradeScheme` | 100% | true on 1,663 installers |
| `technologies` | 100% | Solar PV 4,310 · Battery Storage 2,775 · Air Source Heat Pump 2,166 · Ground/Water Source 544 · Exhaust Air 183 · Solar Heating 160 · Biomass 57 · Solar Assisted 21 · Ground Assisted 14 · Small Wind 11 · Micro CHP 3 |
| `technologySubType` | 40.2% | `Air-To-Water` (heat-pump installers that state it) |
| `regions`, `nations`, `regionCount` | 95.0% | 5% of installers tick no region on MCS - shipped as `[]`, not guessed |
| `addressLine1`, `postcode`, `latitude`/`longitude`, `fullAddress` | 100% | |
| `addressLine2` / `addressLine3` / `county` | 85.3% / 72.9% / 88.7% | county printed as "n/a" on 634 records ships `null` |
| `profileUrl` | 100% | the installer's page on mcscertified.com |
| `distanceKm` / `distanceMiles` | with `nearPostcode` | |
| `country` | 0.04% | MCS prints "Unspecified" on 5,612 of 5,614 - shipped `null`; use `nations` / `postcode` |

### Input

| Input | What it does |
|---|---|
| `technologies` | MCS's own technology filter: `solar_pv`, `battery`, `ashp`, `gshp_wshp`, `eahp`, `sahp`, `all_heat_pumps`, `solar_thermal`, `biomass`, `wind_turbine`, `micro_chp`. Several = the union (MCS lists installers matching more of them first). |
| `requireAllTechnologies` | Intersection instead: e.g. `solar_pv` + `battery` = installers certified for both. |
| `regions` | Regions the installer says they cover: `england` (any English region), `scotland`, `wales`, `northern_ireland`, `nationwide` (all 12), or an English region (`london`, `south_west`, `yorkshire_humberside`...). |
| `boilerUpgradeSchemeOnly` | Only installers registered for the Boiler Upgrade Scheme. |
| `keyword` | MCS's own search box (company-name words). |
| `nearPostcode` + `radiusMiles` | Nearest-first from a UK postcode or district (located via postcodes.io), stopping at the radius. Fills `distanceKm` and `distanceMiles`. |
| `requirePhone`, `requireWebsite` | Skip rows without a valid phone / a website. Skipped rows are never charged. |
| `maxItems` | Stop after this many delivered installers. Default 25; `0` = everything that matches. |
| `concurrency` | Listing pages fetched in parallel (default 4). |
| `saveRawPages` | Keep the first 40 raw JSON pages in the key-value store for audit. |
| `proxyConfiguration` | Off by default - MCS answers Apify's network directly. |

Examples:

```json
{ "technologies": ["ashp"], "boilerUpgradeSchemeOnly": true, "maxItems": 0 }
```

All 1,615 BUS-registered air-source heat pump installers.

```json
{ "technologies": ["solar_pv", "battery"], "requireAllTechnologies": true, "nearPostcode": "BS1 4DJ", "radiusMiles": 10, "maxItems": 0 }
```

Solar + battery installers within 10 miles of central Bristol, nearest first (33 on 2026-09-23).

### Example row (real, from the verified run)

```json
{
  "installerId": "2898",
  "companyName": "Piping Hot Cookers Ltd",
  "email": "james.patmore@pipinghotcookers.com",
  "phone": "01327307130",
  "phoneE164": "+441327307130",
  "phoneType": "landline",
  "phoneAsPublished": "01327 307130",
  "website": "http://www.pipinghotstoves.com",
  "websiteDomain": "pipinghotstoves.com",
  "websiteAsPublished": "www.pipinghotstoves.com",
  "certificationNumber": "ELC-54471",
  "certificationBody": "NICEIC",
  "boilerUpgradeScheme": true,
  "technologies": ["Solar PV", "Battery Storage", "Air Source Heat Pump", "Ground/Water Source Heat Pump"],
  "technologySubType": "Air-To-Water",
  "heatPumpInstaller": true,
  "solarPvInstaller": true,
  "batteryInstaller": true,
  "regions": ["Eastern", "East Midlands", "London", "South East", "South West", "West Midlands", "Yorkshire & Humberside", "Wales"],
  "regionCount": 8,
  "nations": ["England", "Wales"],
  "coversAllRegions": false,
  "addressLine1": "Unit 23, Cottesbrooke Park",
  "addressLine2": "Heartlands Business Park",
  "addressLine3": "DAVENTRY",
  "county": "Northamptonshire",
  "postcode": "NN11 8YL",
  "postcodeDistrict": "NN11",
  "country": null,
  "fullAddress": "Unit 23, Cottesbrooke Park, Heartlands Business Park, DAVENTRY, Northamptonshire, NN11 8YL",
  "latitude": 52.2733,
  "longitude": -1.17558,
  "distanceKm": null,
  "distanceMiles": null,
  "profileSlug": "piping-hot-cookers-ltd",
  "profileUrl": "https://mcscertified.com/find-an-installer/piping-hot-cookers-ltd/",
  "scrapedAt": "2026-09-23T04:50:01.748Z"
}
```

### Output fields

| Field | Description |
|---|---|
| `installerId` | MCS's own installer id - the dedupe key; each installer is delivered and charged once per run |
| `companyName` | Installer company name |
| `email` | Contact email as published (MCS platform addresses removed) |
| `phone`, `phoneE164`, `phoneType` | UK number (`01327307130`), E.164 (`+441327307130`), `landline` / `mobile` / `freephone` / `non-geographic` |
| `phoneAsPublished` | The phone text exactly as MCS shows it - kept even when it is not a valid number |
| `website`, `websiteDomain`, `websiteAsPublished` | Usable website URL, its bare domain, and the original text |
| `certificationNumber`, `certificationBody` | MCS certification number and the body that certified the installer (NICEIC, NAPIT, APHC, OFTEC, The IAA, BAB, HETAS, Simply Certification) |
| `boilerUpgradeScheme` | Registered for the Boiler Upgrade Scheme (true/false) |
| `technologies` | Certified technologies, labelled exactly as MCS labels them |
| `technologySubType` | Heat-pump sub-type as published (`Air-To-Water`) |
| `heatPumpInstaller`, `solarPvInstaller`, `batteryInstaller` | Quick booleans for the three biggest buyer segments |
| `regions`, `regionCount`, `nations`, `coversAllRegions` | Regions covered (MCS labels), how many, which UK nations, and whether all 12 |
| `addressLine1..3`, `county`, `postcode`, `postcodeDistrict`, `fullAddress` | Registered address |
| `country` | As published - almost always "Unspecified" on MCS, so `null` |
| `latitude`, `longitude` | Coordinates MCS stores for the installer |
| `distanceKm`, `distanceMiles` | Distance from `nearPostcode` (MCS returns kilometres; miles converted) |
| `profileSlug`, `profileUrl` | The installer's MCS profile page |
| `scrapedAt` | ISO timestamp of the run |

A `RUN_SUMMARY` record in the key-value store states how many installers MCS says match your filters, how many
unique ones came back, rows removed by each of your filters, retries, and `delivered == charged`.

### Why this one

- **Completeness is checked, not assumed.** Every uncapped run compares the unique installers it collected to the
  total MCS states for the same filters and fails loudly if short (the full register: 5,614 of 5,614). A failed
  page is retried on a fresh connection and gets a repair pass; a page that answers "0 results" inside the stated
  page range is treated as a failure, never as the end of the list.
- **Charged once per installer**, keyed on MCS's id, only for rows actually delivered. Rows your filters remove
  are never charged. No start fee.
- **Contacts cleaned without inventing anything:** phones in E.164 with a type, junk in the website box dropped,
  MCS's own helpdesk addresses stripped, placeholders ("n/a", "Unspecified") shipped as `null`. Nothing is
  "repaired" - a 12-digit phone is left `null` with the original in `phoneAsPublished`.
- **Postcode radius search** (nearest-first with miles), **AND-matching of technologies**, server-side region and
  BUS filters, `coversAllRegions` / `nations` / `regionCount` for territory planning.
- **Fast and light:** the full register in about 75 seconds, no browser, no proxy.

### Pricing

**$0.013 per installer delivered** (pay-per-event, `installer-scraped`). No start fee, no charge for filtered-out
rows. An empty input returns the default 25 installers = $0.325. The full register (5,614) costs about $73.

### Limits - read before buying

- **Regions are what the installer ticked**, not a measured service area; 5% tick none. `radiusMiles` measures from
  the installer's registered office.
- **Website is published by only 55% of installers.** Emails are on 100%; 45% of phones are mobiles.
- MCS ranks multi-technology results with installers matching more of your technologies first; order is otherwise
  by MCS id. Both orders were measured identical across repeated sweeps.

### Source

MCS Find an Installer - https://mcscertified.com/find-an-installer/ - read through the same JSON endpoint the page's
own search uses (`admin-ajax.php?action=filter_installers`, 30 installers per page). Data is as MCS publishes it at
run time.

# Actor input Schema

## `technologies` (type: `array`):

Keep installers MCS-certified for ANY of these (the register's own server-side filter - pick several and you get the union; turn on requireAllTechnologies for the intersection). Empty = every technology. 'All heat pumps' = air, ground/water, exhaust-air and solar-assisted, exactly as the MCS form groups them.

## `requireAllTechnologies` (type: `boolean`):

Off (default): an installer certified for any selected technology is returned. On: only installers certified for every selected technology - e.g. Solar PV + Battery Storage for installers who fit both. Rows removed by this are never delivered and never charged.

## `regions` (type: `array`):

Keep installers that say they cover ANY of these areas (MCS's own filter). 'England' = any English region; 'Nationwide' = installers covering all 12 regions. Empty = the whole UK.

## `boilerUpgradeSchemeOnly` (type: `boolean`):

Only installers MCS marks as registered for the Boiler Upgrade Scheme (the GBP 7,500 heat-pump grant) - 1,663 of 5,614 on 2026-09-23. Applied server-side by MCS.

## `keyword` (type: `string`):

Optional text for MCS's own search box (company name words, e.g. "solar" or "Octopus"). Leave empty for no keyword.

## `nearPostcode` (type: `string`):

Optional. A full UK postcode ("BS1 4DJ") or a district ("BS1"), located with the free postcodes.io service. Results then come nearest-first with distanceKm and distanceMiles filled. An unknown postcode stops the run before anything is charged.

## `radiusMiles` (type: `integer`):

With nearPostcode: stop at installers whose office is farther than this many miles away. 0 = no radius (nearest-first over the whole register). Measures from the installer's registered address, not the area they say they cover - use regions for coverage.

## `requirePhone` (type: `boolean`):

Skip installers whose published phone is empty or not a UK number (1.2% of the register). Skipped rows are never charged.

## `requireWebsite` (type: `boolean`):

Skip installers with no usable website (about 45% publish none). Skipped rows are never charged.

## `maxItems` (type: `integer`):

Stop after this many delivered installers (you pay per delivered installer). 0 = no cap: the whole matching register - 5,614 installers for no filters on 2026-09-23.

## `concurrency` (type: `integer`):

Listing pages (30 installers each) fetched in parallel. 4 walks the full register in about 30 seconds.

## `saveRawPages` (type: `boolean`):

Store the first 40 JSON pages MCS returned in the key-value store as RAW\_\* records, for auditing.

## `proxyConfiguration` (type: `object`):

Off by default - MCS answers Apify's network directly. If Cloudflare ever starts challenging, switch on Apify Proxy with the RESIDENTIAL group (the run summary counts challenges).

## Actor input object example

```json
{
  "technologies": [
    "ashp"
  ],
  "requireAllTechnologies": false,
  "boilerUpgradeSchemeOnly": false,
  "radiusMiles": 0,
  "requirePhone": false,
  "requireWebsite": false,
  "maxItems": 10,
  "concurrency": 4,
  "saveRawPages": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per MCS-certified installer, keyed on MCS's own installer id and deduplicated: company, email, phone (as published and E.164), website, MCS certification number and body, Boiler Upgrade Scheme flag, certified technologies, regions covered, address, coordinates, distance from your postcode and the MCS profile URL.

## `runSummary` (type: `string`):

RUN_SUMMARY: the total MCS states for your filters, pages fetched, unique installers seen vs stated (the completeness check), rows removed by each row filter, transport counters and the billing reconciliation (delivered == charged).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "technologies": [
        "ashp"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/mcs-certified-installers-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "technologies": ["ashp"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/mcs-certified-installers-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "technologies": [
    "ashp"
  ],
  "maxItems": 10
}' |
apify call scrapersdelight/mcs-certified-installers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/mcs-certified-installers-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/lCxyaTBjQPYCWRdSG/builds/BD7Zs7cDJx6jfbyo7/openapi.json
