# TrustMark Retrofit Installer Scraper: PAS 2030/2035 Leads (`scrapersdelight/trustmark-uk-tradespeople-scraper`) Actor

Export TrustMark's register of UK retrofit installers: PAS 2035 retrofit coordinators and assessors, PAS 2030 insulation and heating installers and MCS heat-pump/solar firms, with licence number, certification body, phone (99.7%), website and address. By trade and postcode. $4 per 1,000.

- **URL**: https://apify.com/scrapersdelight/trustmark-uk-tradespeople-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 per trustmark business 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

## 🏠 TrustMark Retrofit Installer Scraper: PAS 2030 / PAS 2035 leads

Export the UK's **TrustMark register** of home-improvement and retrofit
businesses: every **PAS 2035 Retrofit Coordinator and Retrofit Assessor**, every **PAS 2030 installer**
(insulation, heating and other retrofit measures), and every **MCS**
heat-pump, solar and battery installer registered with TrustMark. Each row is **one TrustMark Licence
Number** with its compliance standards, certification body, registration date, phone number,
website and address.

Search by **trade or compliance standard**, around **UK postcodes**, or pull the **whole register**
(14,218 licences) in one 93-second run.

### 🎯 Who uses this

- **Retrofit and insulation lead-generation agencies**: find PAS 2030 installers by measure (cavity
  wall, loft, EWI/IWI, heat pumps) and area to route jobs to.
- **Heat-pump, solar and insulation manufacturers (OEMs)**: map the certified installer base by
  standard, certification body and region for channel recruitment.
- **Energy suppliers' retrofit delivery teams and managing agents**: build and check installer
  supply chains against the register.
- **PAS 2035 Retrofit Coordinators**: source PAS 2030 installers near a project, and
  retrofit assessors to subcontract.
- **Local authorities and housing associations**: shortlist TrustMark-registered contractors
  for Warm Homes / SHDF-style programmes by district.

### 📦 What you get (measured fill, live run 2026-09-23)

Fill rates come from real runs of this Actor and are counted per delivered row (one row per licence).

| Field | Whole register (14,218 licences) | PAS 2030/2035 export (4,342 licences) |
|---|---|---|
| 🏷️ `tmln` TrustMark Licence Number | 100% | 100% |
| ✅ `complianceStandards` (PAS 2030:2019 / 2023, PAS2035, MIS… from TrustMark's trade table) | 54.8% | **100%** |
| ✅ `isPas2035` / `isPas2030` / `isMcs` flags | always set | always set |
| 🏛️ `schemeProviders` certification body (Elmhurst, ECMK, NAPIT, NICEIC…) | **100%** | **100%** |
| 📅 `registeredSince` | 100% | 100% |
| 📞 `phone` (+ `phoneE164`, all `phones`) | **99.8%** | **99.7%** |
| 🌐 `website` | 49.0% | 19.5% |
| ✉️ `email` (named contact, or an email typed in the website box) | 3.8% | 2.7% |
| 👤 `contactName` | 3.7% | 2.6% |
| 📍 address, postcode, district, region, country | 99.8-100% | 100% |
| 🗺️ `latitude` / `longitude` | 99.5% | 99.2% |
| 💷 `fundingSchemes` (government funding schemes the business declares) | 1.1% | 1.6% |
| 🖼️ `workExamples` (project evidence) | 4.6% | 0.9% |
| 📝 `about`, `logoUrl`, `socialLinks`, `otherDirectoryProfiles` | 7.3% / 9.9% / 4.8% / 1.3% | 3.7% / 5.5% / 2.3% / 0.3% |

**About email:** TrustMark publishes a named-contact email for only **about 4%** of
licences. The contact block it publishes for nearly every business is the **phone number (99.7%)**,
and that's the channel this dataset is built for. If you need email, run the websites (49% of
the register) through an email enricher.

Every row also carries: `tradingNames` (all names under the licence), `trades` + `tradeIds`,
`businessSchemes` (per scheme: certification body, registered-from date, Trading Standards flag, each
trade with its standard, and the selected subtrades), `coverageRegions` / `coverageDistricts` /
`coverageCountries`, `nationalCoverage`, `isClaimedByBusiness`, `branches` (for multi-branch
licences), `profileCount`, `profileIds`, `distanceMiles` + `searchLocation` (postcode searches) and a
`trustMarkUrl`.

**Composition of the PAS 2030/2035 export** (live run): certification bodies Elmhurst Energy 1,881 ·
ECMK 1,438 · The Installation Assurance Authority 301 · Simply Certification 262 · Quidos 249.
Standards PAS2035 3,462 · PAS 2030:2023 831 · PAS 2030:2019 383 · Licence Plus 133 · MIS3002 133.
Countries: England 3,620 · Scotland 338 · Wales 327 · Northern Ireland 13.

### ⭐ What makes it different

- **Compliance first.** `complianceStandards` and the `isPas2035` / `isPas2030` / `isMcs` flags come
  straight from TrustMark's own trade table (each trade id carries its standard). We never infer them.
- **One row per licence, never billed twice.** 312 licences carry several profiles (up to 187 for
  a national retailer's branches), and 131 of them trade under more than one name. Every in-scope
  profile is merged into one row with all trading names, branches, phones and schemes. You pay
  once per licence.
- **Every row really carries the trade you asked for.** TrustMark's own search index lags its
  records. We measured it returning a firm with no Solar PV trade for a Solar search, and missing a
  firm that does have it. This Actor checks each record and drops the mismatches without charging
  you. A nationwide export reads the register itself and filters on the records, so it also
  catches recent registrations the index hasn't picked up yet.
- **Complete, or it says so.** Each search is fetched as one consistent response. The Actor checks
  that it received exactly as many profiles as TrustMark says exist, rejects truncated or HTML
  answers, and retries on a fresh connection. If the check can't be met, the run fails loudly
  instead of shipping a short list.
- **Clean contact fields.** TrustMark's website box holds `n/a`, `no website`, email addresses and
  broken hosts. We drop the junk, move emails to `emails`, and never "repair" a value.

### 🔧 Input

| Input | What it does | Default |
|---|---|---|
| `trades` | TrustMark trades (retrofit measures listed first). Each name covers every certification route TrustMark lists for it. OR-ed. | `["Retrofit Coordinator"]` |
| `complianceStandards` | `PAS 2035`, `PAS 2030`, `MCS`, `Licence Plus`, `CPS`, `INS-001`, `Industry Standard`. OR-ed with `trades`. | none |
| `allTrades` | Whole register, every trade. | `false` |
| `postcodes` | Full postcodes (`SW1A 1AA`), outward codes (`M1`) or `lat,lng`. Empty = whole UK. | empty (whole UK) |
| `radiusMiles` | Radius per postcode. Empty = TrustMark's default, measured at **30 miles**. | TrustMark default |
| `searchBy` | `located` (where the business is) or `serviceArea` (where it works). | `located` |
| `includeNationalBusinesses` | Include UK-wide businesses (141 on the register). | `true` |
| `businessName` | TrustMark's own name search. | none |
| `requireEmail` / `requireWebsite` | Deliver and charge only rows that have one. | `false` |
| `maxResults` | Max licences to deliver and charge. `0` = no limit. | `50` |
| `proxyConfiguration` | Leave at "No proxy" (see below). | no proxy |

**Examples**

```json
{ "trades": ["Retrofit Coordinator"], "postcodes": ["SW1A 1AA"], "maxResults": 20 }
```

```json
{ "complianceStandards": ["PAS 2035", "PAS 2030"], "maxResults": 0 }
```

```json
{ "trades": ["Air Source Heat Pump", "Cavity Wall Insulation"], "postcodes": ["M1", "LS1 4AP", "BS8 1TH"], "radiusMiles": 20, "requireWebsite": true, "maxResults": 200 }
```

```json
{ "allTrades": true, "maxResults": 0 }
```

### 📄 Output example

A real row from the live PAS 2030/2035 export (the `subtrades` list is shortened here):

```json
{
  "tmln": "1744057",
  "companyName": "S & A Heating Limited",
  "tradingNames": ["S & A Heating Limited"],
  "complianceStandards": ["CPS", "PAS 2030:2019", "PAS 2030:2023"],
  "isPas2035": false,
  "isPas2030": true,
  "isMcs": false,
  "schemeProviders": ["NAPIT"],
  "tradingStandardsApproved": false,
  "registeredSince": "2020-01-04",
  "fundingSchemes": [
    { "name": "Warm Home Discount Scheme (WHD)", "type": "Grant", "endDate": "2026-03-31", "activeOnTrustMark": false }
  ],
  "workExamplesCount": 0,
  "phone": "01803323950",
  "phoneE164": "+441803323950",
  "website": "https://www.saheating.co.uk",
  "email": "saheating@yahoo.co.uk",
  "contactName": "James Frost",
  "trades": ["Gas Engineer", "Gas Boiler", "Heating Controls"],
  "businessSchemes": [{
    "schemeProvider": "NAPIT", "registeredFrom": "2020-01-04", "isTradingStandardsApproved": false,
    "trades": [
      { "id": 109, "name": "Gas Boiler", "standard": "PAS 2030:2019" },
      { "id": 242, "name": "Gas Boiler", "standard": "PAS 2030:2023" },
      { "id": 244, "name": "Heating Controls", "standard": "PAS 2030:2023" }
    ],
    "subtrades": ["Gas Boiler: Installation", "Heating Controls: Installation- Smart Thermostats", "…"]
  }],
  "address1": "7 Chatto Way",
  "town": "Torquay",
  "postcode": "TQ1 4UE",
  "district": "Torbay",
  "region": "South West",
  "country": "England",
  "latitude": 50.477166,
  "longitude": -3.535582,
  "coverageDistricts": ["Cornwall", "East Devon", "Exeter", "Plymouth", "Torbay", "…"],
  "otherDirectoryProfiles": { "whichTrustedTraders": "https://trustedtraders.which.co.uk/businesses/s-and-a-heating-ltd/" },
  "logoUrl": "https://www.trustmark.org.uk/media/ghpfk4fw/s-a-1.png",
  "isClaimedByBusiness": true,
  "profileCount": 1,
  "trustMarkUrl": "https://www.trustmark.org.uk/homeowner/find-a-tradesperson?tmln=1744057"
}
```

The **Run summary** (`RUN_SUMMARY` in the key-value store) lists, for each search: TrustMark's own
match count, the profiles actually carrying your trade, unique licences, per-field fill, and
everything **not** charged, kept apart: postcodes not found, rows your filters removed, rows over
the cap, profiles merged into one licence, and profiles TrustMark's index returned without your
trade.

### 💰 Pricing

**$4 per 1,000 businesses** ($0.004 per TrustMark licence delivered). Pay-per-event, no start fee.

| Job | Rows | Cost |
|---|---|---|
| Demo (`Retrofit Coordinator` around one postcode) | 20 | $0.08 |
| Default run (`{}`) | 50 | $0.20 |
| Every PAS 2030 + PAS 2035 business in the UK | 4,342 | $17.37 |
| The whole register | 14,218 | $56.87 |

You're charged only for delivered, deduplicated licences. You're never charged for a duplicate, a
filtered-out row, a postcode that wasn't found, a search that couldn't be reached, or a profile
TrustMark's index returned without your trade. If you set a maximum charge on the run, the Actor
stops there and every row you receive has been charged exactly once.

### ⚙️ How it works

The Actor calls the same JSON API that TrustMark's Find-a-Tradesperson page calls
(`cms.trustmark.org.uk/api/businessProfiles`). The offline test suite proves its records are
byte-identical to the ones the page renders. Postcodes are geocoded with the open ONS-based
postcodes.io service.

- **Speed (live runs, 512 MB):** demo 3.8 s · 50 rows 4.0 s · 200 rows around 3 postcodes 4.8 s ·
  PAS 2030/2035 export 52.8 s · whole register 92.7 s.
- **Transport:** requests go direct from Apify's servers (measured: the whole 20.5 MB register in
  one request, one attempt). Any request that fails twice is retried through Apify RESIDENTIAL
  proxy (UK) automatically, on a fresh session. You don't need to configure a proxy.

### ⚠️ Data limits

- **Email is rare (about 4%).** Most businesses publish a phone number, not an email.
- **Work examples are rare (4.6% overall, 0.9% of PAS installers).** Where they exist they are real
  project evidence with dates, descriptions and photos, but most PAS 2030 businesses don't publish any.
- **Funding schemes are self-declared and mostly historic.** Only 1.1% of licences list any, and
  TrustMark's own records mark **every** scheme as ended or inactive (latest end date
  2026-03-31). We ship each scheme with TrustMark's own `endDate` and `activeOnTrustMark` flag,
  so treat it as "has delivered under", not "is currently delivering".
- **Postcode searches depend on TrustMark's search index.** It lags the records by well under 1%
  (measured on Solar PV: 11 false matches and 15 missed of about 1,970). We drop the false matches.
  To also catch the missed ones, run a nationwide search with `maxResults: 0`, which filters the
  records themselves.
- **Capped runs merge only the profiles they fetched.** A licence's other branches outside your
  search or cap aren't pulled in. A whole-register export merges every profile.
- **Order.** Postcode searches come back nearest first. Nationwide capped searches follow
  TrustMark's own order (profiles the business has claimed come first). That order differs between
  TrustMark's servers, so two capped runs can return different firms. For a complete, stable list,
  use `maxResults: 0`.
- `distanceMiles` is straight-line from the postcode's centre.

### ❓ FAQ

**Where does the data come from?** TrustMark's public Find-a-Tradesperson search, fetched from the
same API the page uses, live on every run.

**What is a TMLN?** The TrustMark Licence Number, the business's licence on the scheme. One row per
TMLN.

**How do I get PAS 2030 installers?** Use `complianceStandards: ["PAS 2030"]`: those are the
businesses registered for PAS 2030:2019 or PAS 2030:2023 trades. `fundingSchemes` additionally shows
the few that declare government funding-scheme work.

**How do I get retrofit coordinators and assessors?** `complianceStandards: ["PAS 2035"]`, or
`trades: ["Retrofit Coordinator", "Retrofit Assessor"]`.

**What about MCS heat-pump installers?** `complianceStandards: ["MCS"]` (MIS 3001-3012), or pick the
trade, for example `Air Source Heat Pump`.

**Why are there fewer rows than TrustMark's search count?** TrustMark counts profiles, and we deliver
licences. On the whole register, 14,953 profiles are 14,218 licences. The Run summary shows both
numbers.

**Can I search several areas at once?** Yes. Each postcode is its own search, and a business found by
two of them is delivered and charged once.

**Why no email for most rows?** TrustMark publishes a named-contact email for about 4% of licences.
Pair `website` (49%) with an email enricher.

**Is the phone number the business's own?** It's the number the business published on its TrustMark
profile. Named contacts' own phones are included in `phones`.

**How fresh is it?** Live on every run. `registeredSince` and each scheme's `registeredFrom` date
come from TrustMark.

**Do I need a proxy?** No. The Actor escalates to Apify RESIDENTIAL proxy by itself if a request is
refused.

**Can I schedule it?** Yes. Schedule a nationwide `maxResults: 0` export and diff on `tmln` to see new
registrations.

# Actor input Schema

## `trades` (type: `array`):

TrustMark trades to search. Each name expands to EVERY TrustMark trade id carrying it (e.g. 'Loft Insulation' covers its PAS 2030:2019, PAS 2030:2023 and Licence Plus routes). Retrofit measures are listed first. Leave empty and set 'Compliance standards' instead to search by standard. Several trades are OR-ed.

## `complianceStandards` (type: `array`):

Search by the installation standard a trade is certified to, read from TrustMark's own trade table: 'PAS 2035' = Retrofit Assessors and Retrofit Coordinators; 'PAS 2030' = PAS 2030:2019 and PAS 2030:2023 installers (insulation, heating and other retrofit measures); 'MCS' = MCS installation standards (MIS 3001-3012: heat pumps, solar PV, battery, biomass). Combined with 'Trades' as an OR.

## `allTrades` (type: `boolean`):

Ignore 'Trades' and 'Compliance standards' and search every TrustMark-registered business (about 14,200 licences nationwide). Combine with Max results = 0 for a full register export.

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

Search around each location: a full UK postcode (SW1A 1AA), an outward code (M1, BS8) or 'latitude,longitude'. Each location is its own search; results are merged and deduplicated by TrustMark Licence Number. Leave empty to search the whole UK.

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

Search radius around each postcode. Leave empty for TrustMark's own default, measured at 30 miles.

## `searchBy` (type: `string`):

'Where the business is located' (TrustMark's default) or 'Where the business provides its services' (its declared coverage area).

## `includeNationalBusinesses` (type: `boolean`):

Include businesses registered as covering the whole UK (TrustMark's default). Untick to keep only local firms.

## `businessName` (type: `string`):

Optional: only businesses whose name matches this phrase (TrustMark's own name search).

## `requireEmail` (type: `boolean`):

Deliver (and charge for) only businesses that publish a named-contact email. Measured: about 4% of the register does, so expect far fewer rows.

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

Deliver (and charge for) only businesses with a valid website. Measured: about 49% of the register.

## `maxResults` (type: `integer`):

Maximum businesses (unique TrustMark Licence Numbers) to deliver and charge for. 0 = no limit.

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

Leave this at 'No proxy': TrustMark's API answers Apify's own servers directly (measured: the whole 14,953-profile register in one 59-second run), and any request that fails twice is retried automatically through Apify RESIDENTIAL proxy (UK). Set a proxy here only if you want every request to use it.

## Actor input object example

```json
{
  "trades": [
    "Retrofit Coordinator"
  ],
  "allTrades": false,
  "postcodes": [
    "SW1A 1AA"
  ],
  "searchBy": "located",
  "includeNationalBusinesses": true,
  "requireEmail": false,
  "requireWebsite": false,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `records` (type: `string`):

One item per unique TrustMark Licence Number: compliance standards, certification body, contact block and address.

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

Coverage accounting: each search's source total vs rows fetched, unique licences, per-field fill, and what was not charged (unknown postcode, filtered out, over the cap, merged duplicates).

# 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 = {
    "trades": [
        "Retrofit Coordinator"
    ],
    "postcodes": [
        "SW1A 1AA"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/trustmark-uk-tradespeople-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 = {
    "trades": ["Retrofit Coordinator"],
    "postcodes": ["SW1A 1AA"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/trustmark-uk-tradespeople-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 '{
  "trades": [
    "Retrofit Coordinator"
  ],
  "postcodes": [
    "SW1A 1AA"
  ],
  "maxResults": 20
}' |
apify call scrapersdelight/trustmark-uk-tradespeople-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/trustmark-uk-tradespeople-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/s3CEwVYYJyHdPxTNp/builds/Kfo5n0HiDNhj040UL/openapi.json
