# MCS Certified Installers UK Scraper: Solar PV, Heat Pump & Etc. (`azanko/mcs-certified-installers`) Actor

Download and Get all 5,500+ MCS certified UK installers in ~10 seconds: email, phone, website, address, installer types, regions and Boiler Upgrade Scheme status. De-duplicated and refreshed daily.

- **URL**: https://apify.com/azanko/mcs-certified-installers.md
- **Developed by:** [Azan](https://apify.com/azanko) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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 UK: Solar PV, Heat Pump and Battery Installer Database

Get **every MCS certified renewable energy installer in the UK** as clean, ready-to-use data in seconds: company name, email, telephone, website, full address with coordinates, installer types (solar PV, heat pumps, battery storage, biomass, solar thermal and more), regions covered, certification numbers and bodies, and Boiler Upgrade Scheme status.

The data comes from the official [MCS "Find an Installer" directory](https://mcscertified.com/find-an-installer/), the UK's register of certified small-scale renewable installers. It is **refreshed automatically every day**.

- ⚡ **Instant results.** The full UK directory (5,500+ companies) comes back in about 10 seconds. Filtered searches are faster still.
- 🧹 **Clean, de-duplicated data.** One record per company, standard postcodes, tidy addresses, and `null` where MCS has no value.
- 🎯 **Precise filters.** Installer type, region (or all of England at once), nationwide coverage, postcode, county, keyword, certification body, Boiler Upgrade Scheme, website and phone.
- 🛡️ **Works even when MCS doesn't.** Your runs never depend on the MCS website being up, fast or unchanged.

***

### Why this Actor is faster and more reliable

Most scrapers for this directory are **live scrapers**: every time you press Start, they go to the MCS website and page through it, 30 installers at a time. The full directory is about 190 pages, so you wait while each one downloads, and your run depends on the website behaving.

**This Actor works differently.** We scrape the whole MCS directory once a day, clean and check the data, and store it in a database built into the Actor. When you press Start, the Actor filters that database and returns your results. It never has to talk to the MCS website.

| | **This Actor** | Typical live-scraping Actor |
|---|---|---|
| Full UK directory (5,500+ installers) | **About 10 seconds** | 30 seconds to several minutes, depending on concurrency |
| A filtered search, e.g. heat pump installers in Devon | **A few seconds**, same speed as any other query | Often still pages through most of the directory, or filters after downloading |
| If the MCS website is slow or down | **Unaffected.** You get the latest daily snapshot | Run slows down, partly fails or returns nothing |
| If MCS rate-limits or blocks traffic | **Unaffected** | Missing pages, errors, or you have to lower concurrency and wait longer |
| If MCS changes its website | **Unaffected.** Updates pause while we fix it and your runs keep working | Breaks until the developer fixes it |
| Duplicate companies | **Merged.** One record per company | One record per registration, so the same company can appear twice |
| Settings to tune | **None.** No concurrency, page limits or retries | Concurrency and page limits to trade speed against errors |
| Compute used per run | **Tiny.** No browser, no page downloads | Grows with every page fetched |
| Load on the MCS website | **One scrape a day, total** | One full scrape per customer run |

#### What that means for you

1. **You save time on every run.** Answers come back in seconds, so you can try filters freely and wire the Actor into apps and automations that need a quick response.
2. **Your pipelines don't break.** Scheduled runs, CRM syncs and Zapier or Make workflows get complete results every time, whatever state the MCS website is in.
3. **Fewer surprises in your data.** Every record has been through the same checks: merged duplicates, normalised postcodes and consistent fields. You don't have to clean up after a half-finished scrape.
4. **Results are consistent.** The same query gives the same answer all day, so exports and reports match up.
5. **You can use it as an API.** Because runs are this fast, the one-call `run-sync-get-dataset-items` endpoint works well for live lookups. See [API](#use-it-as-an-api).

#### The trade-off, honestly

A live scraper shows changes the moment MCS publishes them. This Actor shows them **after the next daily refresh**, so the data is at most about a day old. Every record carries `dataUpdatedAt` so you always know exactly when it was refreshed. The whole directory changes by only a handful of installers a day, so for lead generation, research and CRM work a daily snapshot gives the same answers, faster and more reliably.

***

### What's in the dataset

Approximate figures from a recent refresh. The live numbers change slightly every day.

| | Companies |
|---|---|
| **Total MCS certified installer companies** | **5,580+** (from 5,630+ MCS registrations) |
| With email | 100% |
| With telephone | 99% |
| With website | 55% |
| With map coordinates | 100% |
| Registered for the Boiler Upgrade Scheme | 1,670+ |
| Cover all 12 UK regions (nationwide) | 2,500+ |

| Installer type | Companies |
|---|---|
| Solar PV | 4,300+ |
| Battery Storage | 2,790+ |
| Air Source Heat Pump | 2,170+ |
| Ground/Water Source Heat Pump | 540+ |
| Exhaust Air Heat Pump | 180+ |
| Solar Heating (Solar Thermal) | 160+ |
| Biomass | 58 |
| Solar Assisted Heat Pump | 21 |
| Gas Absorption Heat Pump | 14 |
| Small Wind Turbine | 11 |
| Micro CHP | 3 |

### What you can do with it

- **Lead generation.** Build lists of solar, heat pump or battery installers by region, county or postcode for B2B outreach. Filter to "has a website" or "no website", for example to sell web services.
- **Selling to installers.** Wholesalers, equipment manufacturers, software, finance and insurance companies can reach every certified installer in their area.
- **Market research.** See how many installers cover each technology and region, and who is registered for the Boiler Upgrade Scheme.
- **Finding partners and subcontractors.** Find certified installers near a site or covering the whole country.
- **CRM enrichment and compliance checks.** Match your records against MCS certification numbers and bodies.
- **Directories and comparison sites.** Feed a daily-fresh, structured list of certified installers into your product.

### Filters

All filters are optional. Different filters combine with AND. Several values inside one filter combine with OR, for example "Solar PV **or** Battery Storage".

| Input | What it does |
|---|---|
| **Installer types** | Air Source Heat Pump, Battery Storage, Biomass, Exhaust Air Heat Pump, Ground/Water Source Heat Pump, Micro CHP, Small Wind Turbine, Solar Assisted Heat Pump, Solar Heating (Solar Thermal), Solar PV, Gas Absorption Heat Pump. |
| **Must install ALL selected types** | Turn on to find installers certified for every type you picked, e.g. Solar PV **and** Battery Storage. |
| **Regions covered** | **England** (all 9 English regions in one click), any single English region, Scotland, Wales or Northern Ireland. |
| **Nationwide only** | Only installers covering all 12 UK regions. |
| **Postcodes** | The installer's own postcode, by area (`BS`), district (`BS1`), sector (`BS1 6`) or full postcode (`BS1 6XN`). `B` matches Birmingham only, not `BS`, and `BS1` doesn't match `BS10`. |
| **Counties** | For example `Devon` or `Kent`. |
| **Keyword search** | Company name, certification number, email, website or address. |
| **Certification bodies** | NICEIC, NAPIT, APHC, OFTEC, The IAA, BAB, Simply Certification, HETAS. |
| **Boiler Upgrade Scheme only** | Only installers registered for the BUS grant. |
| **Website** | Any, has a website, or no website. |
| **Telephone** | Any, has a telephone, or no telephone. |
| **Max results** | Defaults to 100. Set it to `0` to get every match. |

Leave everything empty and set **Max results** to `0` to download the complete UK directory.

Unknown values (e.g. a technology that isn't in the list, or a negative max) are rejected by the input form before the run starts. A malformed postcode starts the run and fails it with an `Invalid input: …` message.

### Output

One record per installer company. Fields MCS doesn't publish are returned as `null` (or an empty list), never guessed.

```json
{
  "installerId": 751,
  "mcsInstallerIds": [751],
  "companyName": "4 Seasons Air Conditioning Ltd",
  "contactPerson": null,
  "email": "info@4seasonssolutions.co.uk",
  "emails": ["info@4seasonssolutions.co.uk"],
  "telephone": "08009556118",
  "telephones": ["08009556118"],
  "website": "www.4seasonssolutions.co.uk",
  "websites": ["www.4seasonssolutions.co.uk"],
  "addressLine1": "80 Langstone Drive",
  "addressLine2": null,
  "addressLine3": "Exmouth",
  "county": "Devon",
  "postcode": "EX8 4JD",
  "country": null,
  "fullAddress": "80 Langstone Drive, Exmouth, Devon, EX8 4JD",
  "latitude": 50.634,
  "longitude": -3.39761,
  "installerTypes": ["Air Source Heat Pump", "Battery Storage", "Solar PV"],
  "technologySubTypes": ["Air-To-Water"],
  "regionsCovered": ["South West"],
  "coversAllRegions": false,
  "certificationNumbers": ["EPP-32553"],
  "certificationBodies": ["NICEIC"],
  "boilerUpgradeScheme": true,
  "registrationCount": 1,
  "profileUrl": "https://mcscertified.com/find-an-installer/4-seasons-air-conditioning-ltd/",
  "logoUrl": null,
  "dataUpdatedAt": "2026-09-29T19:05:48+00:00"
}
```

| Field | Description |
|---|---|
| `installerId` | MCS installer id (the lowest one if the company has several registrations) |
| `mcsInstallerIds` | Every MCS installer id belonging to this company |
| `registrationCount` | How many MCS registrations were merged into this record |
| `companyName` | Registered company name |
| `contactPerson` | Always `null`: MCS does not publish contact names |
| `email`, `emails` | Main email, and every email across the company's registrations |
| `telephone`, `telephones` | Main telephone, and all of them |
| `website`, `websites` | Main website, and all of them (`null` / empty if none) |
| `addressLine1`–`3`, `county`, `postcode`, `fullAddress` | Business address. Postcodes use the standard format (`BS1 6XN`) |
| `country` | Usually `null`: MCS lists almost every installer as "Unspecified" |
| `latitude`, `longitude` | Map coordinates of the business address |
| `installerTypes` | Technologies the company is certified to install |
| `technologySubTypes` | e.g. `Air-To-Water`, `Air-To-Air` |
| `regionsCovered`, `coversAllRegions` | UK regions the company works in; `true` when it covers all 12 |
| `certificationNumbers`, `certificationBodies` | All MCS certification numbers and the bodies that issued them |
| `boilerUpgradeScheme` | `true` if registered for the Boiler Upgrade Scheme |
| `profileUrl` | The company's page in the MCS directory |
| `logoUrl` | Always `null` at the moment: MCS shows a placeholder image for every installer |
| `dataUpdatedAt` | When this data was last refreshed from MCS (UTC) |

#### How we clean the data

- **Duplicates merged.** Some companies hold several MCS registrations, for example one through NAPIT for solar and one through APHC for heat pumps. We merge these into one record per company, keeping every email, phone, website, certification number and body, so nothing is lost.
- **Postcodes standardised.** `bs16xn` becomes `BS1 6XN`, so postcode filters and your exports line up.
- **Addresses tidied.** Stray commas and empty parts are removed.
- **Real nulls.** Placeholders like "N/A" or "Unspecified" become `null`, so a missing value is always obviously missing.
- **Nothing invented.** Values are otherwise exactly as MCS publishes them, including any typos in the source data.
- **Checked before release.** If a daily refresh looks wrong (for example, far fewer installers than yesterday), it is rejected and the previous day's data stays live.

### Use it as an API

Run the Actor and get the results in one HTTP call:

```bash
curl -X POST "https://api.apify.com/v2/acts/<username>~mcs-certified-installers/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"technologies": ["ground_water_source", "ashp"], "regions": ["england"], "boilerUpgradeSchemeOnly": true, "maxItems": 0}'
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("<username>/mcs-certified-installers").call(run_input={
    "technologies": ["solar_pv", "battery"],
    "matchAllTechnologies": True,
    "postcodes": ["BS", "BA"],
    "websiteFilter": "with",
    "maxItems": 0,
})
installers = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(installers), "installers")
```

Results can also be exported from the dataset as JSON, CSV, Excel, XML or RSS, or sent to Google Sheets, Zapier, Make and other Apify integrations.

#### Input values for the API

- **`technologies`**: `ashp`, `battery`, `biomass`, `eahp`, `ground_water_source`, `micro_chp`, `wind_turbine`, `sahp`, `solar_thermal`, `solar_pv`, `gahp`
- **`regions`**: `england`, `eastern`, `east_midlands`, `london`, `north_east`, `north_west`, `south_east`, `south_west`, `west_midlands`, `yorkshire_humberside`, `scotland`, `wales`, `northern_ireland`
- **`certificationBodies`**: `NICEIC`, `NAPIT`, `APHC`, `OFTEC`, `The IAA`, `BAB`, `Simply Certification`, `HETAS`
- **`websiteFilter`, `telephoneFilter`**: `any`, `with`, `without`

### FAQ

**How fresh is the data?**
It's refreshed from the MCS directory automatically every day. Every record includes `dataUpdatedAt`, so you can see exactly when.

**Why are results so fast if you're not scraping?**
The scraping happens once a day on our side. Your run only searches the prepared database, which takes a fraction of a second, plus the few seconds Apify needs to start the Actor and save your results.

**Why does the MCS website show a slightly higher count?**
The website counts **registrations**, and we return **companies**. About 50 companies hold two registrations (usually with different certification bodies for different technologies). The website lists them twice; we list them once, with both ids in `mcsInstallerIds`. This affects every total, including nationwide, by a few dozen at most.

**Why is Ground/Water Source Heat Pump one option?**
That's how the MCS website presents it, and MCS records nearly all of these installers under one heading. Offering them separately would make one of the two look almost empty.

**Why is `contactPerson` always null?**
MCS doesn't publish the names of people at installer companies. The column is there so you can see it's genuinely unavailable, not missing by mistake.

**Is this data public?**
Yes. It comes from the public MCS installer directory, which is published so homeowners and businesses can find certified installers.

**Can I get installers near a specific address?**
Use the **Postcodes** filter with the area or district, e.g. `BS1` or `BS`. For distance searches, use the `latitude` and `longitude` in each record.

# Actor input Schema

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

Only return installers certified for these technologies. Leave empty for all.

## `matchAllTechnologies` (type: `boolean`):

Off: installers with any of the selected technologies. On: only installers certified for every one.

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

Only return installers that cover at least one of these regions. 'England' selects all 9 English regions at once. Leave empty for all.

## `nationwideOnly` (type: `boolean`):

Only installers that cover all 12 UK regions (the site's 'Nationwide' filter).

## `postcodes` (type: `array`):

Installer's own postcode. Use an area (e.g. 'BS'), a district ('BS1') or a full postcode ('BS1 4DJ').

## `counties` (type: `array`):

Installer's county, e.g. 'Devon' (case-insensitive exact match).

## `search` (type: `string`):

Matches company name, certification number, email, website or address.

## `certificationBodies` (type: `array`):

Only installers certified through one of these bodies. Leave empty for all.

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

Only installers registered for the BUS grant.

## `websiteFilter` (type: `string`):

Filter on whether the installer lists a website.

## `telephoneFilter` (type: `string`):

Filter on whether the installer lists a telephone number.

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

Maximum number of installers to return. 0 = no limit (all matches).

## Actor input object example

```json
{
  "technologies": [],
  "matchAllTechnologies": false,
  "regions": [],
  "nationwideOnly": false,
  "postcodes": [],
  "counties": [],
  "certificationBodies": [],
  "boilerUpgradeSchemeOnly": false,
  "websiteFilter": "any",
  "telephoneFilter": "any",
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("azanko/mcs-certified-installers").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 = { "maxItems": 100 }

# Run the Actor and wait for it to finish
run = client.actor("azanko/mcs-certified-installers").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 '{
  "maxItems": 100
}' |
apify call azanko/mcs-certified-installers --silent --output-dataset

```

## MCP server setup

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

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/rqfUPKVNTLXIMwOwI/builds/frnZPbSODBcza60x3/openapi.json
