# Checkatrade Scraper | UK Trades & Lead Data (`b2b_leads/checkatrade-real-time-data-scraper`) Actor

Collect Checkatrade UK trade and lead data at scale. Search trades across any UK area, enrich every business with scores, reviews, services, vetting history and contact numbers. Clean JSON streamed to your dataset in real time. Ideal for lead-gen, CRM enrichment and local SEO.

- **URL**: https://apify.com/b2b\_leads/checkatrade-real-time-data-scraper.md
- **Developed by:** [Emmanuel](https://apify.com/b2b_leads) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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

## Checkatrade Real-Time Data

**Collect Checkatrade trade and lead data at scale.** Search multiple trades across multiple UK areas in one run, enrich every business with full profile detail — score, review signals, services, skills, vetting information, membership history and contact numbers — and get **clean, structured JSON** streamed to your Apify dataset in real time.

Built for UK lead-gen agencies, local SEO teams, trade suppliers, franchise developers, CRM and data teams who need **reliable UK tradespeople data** without slow, expensive tools.

***

### ⚠️ Paid only / free tier

**Free (Apify free-plan) accounts are limited: a free run exports a maximum of 2 results and then stops gracefully with an upgrade message.** Upgrade to a paid Apify plan for full, unlimited output. Paying users are never capped by this Actor. See the [FAQ](#faq) for details.

***

### Why this Actor

| | Checkatrade Real-Time Data | Typical tools |
|---|---------------------------|-----------------|
| Speed | Fast per-result collection | Often 5–15 s per business |
| Memory | **512 MB** default | 2–4 GB+ |
| Setup | Organised input UI, run immediately | Fragile and high-maintenance |
| **Cost** | Low compute, efficient UK residential routing | High |
| **Output** | Structured JSON, LLM-ready | Messy documents |
| **Predictable** | **Every business is exported** — enrichment never filters rows | Output count varies with data quality |
| **Multi-market** | Many trade + area pairs per run | Usually one query at a time |

**Predictable output = predictable pricing.** *Profile & lead details* enriches every row; businesses with a sparse profile are still exported (with empty fields). That keeps runtime per 1,000 businesses stable so you always know what a run costs.

***

### What you get — 30+ data points per business

Every record includes `featureType` and `scrapedAt` so you can filter, join, and pipe it into any workflow.

| Field | Description |
|-------|-------------|
| `name` | Business name |
| `profileUrl` | Checkatrade profile link |
| `memberId` | Profile key (stable key for dedup and joins) |
| `phone`, `phones[]` | Contact number(s), normalised to +44 form |
| `description` | Short trading description shown on the listing |
| `summary` | Profile summary line (trade, area, rating and review volume) |
| `primaryCategory` | Primary trade (e.g. Plumber, Electrician) |
| `skills[]` | Skills listed for the business |
| `services[]` | Services offered (profile detail) |
| `score`, `ratingScale` | Checkatrade score and the scale it is measured on (out of 10) |
| `reviewCount` | Number of reviews behind the score |
| `reviews[]` | Recent reviews: `author`, `rating`, `date`, `body` |
| `memberSince` | Membership start month and year |
| `vettingChecks` | Number of vetting checks the trade has passed |
| `guarantee` | Guarantee displayed on the profile |
| `areaServed`, `location`, `town` | Service area / location |
| `postcode` | Postcode area where published |
| `imageUrl`, `photos[]` | Logo and profile photos |
| `website`, `websiteDomain`, `websiteConfidence` | Verified business site with a confidence signal when contact discovery is on |
| `email`, `emails[]` | Contact email(s) from the business's own pages |
| `socials`, `facebookUrl`, `instagramUrl`, `linkedinUrl`, `twitterUrl` | Social profiles |
| `profileDetails` | `true` when profile enrichment ran for this row |
| `contactDiscovery` | `true` when website/contact discovery ran for this row |
| `searchTrade`, `searchLocation`, `searchTaskIndex`, `searchTaskLabel` | Traceability for multi-task runs |
| `scrapedAt` | ISO timestamp |

#### Search results (`featureType: "search"`)

One row per business from a trade + area search, with all fields above when available.

#### Scrape By URL (`featureType: "scrape_by_url"`)

Paste Checkatrade profile links to collect exactly those businesses — same output shape.

***

### Who it is for

- **Lead-gen and outbound agencies** — build UK trade prospect lists by trade and area, ready for calling and emailing
- **Local SEO and web studios** — find tradespeople with a thin or missing web presence (prime website and marketing leads)
- **Trade suppliers and merchants** — target builders, plumbers, electricians and roofers across hundreds of postcodes
- **Franchise developers** — map where a trade is concentrated before opening a new territory
- **CRM and RevOps teams** — enrich existing UK trade records with scores, services and contact numbers
- **Market researchers and AI builders** — structured JSON for market maps, scoring models and assistants

***

### Use cases

- **UK trade lead generation** — pull plumbers, electricians, builders and roofers with phone numbers and profile links for outbound campaigns
- **"No website" prospecting** — turn on contact discovery to single out well-reviewed trades with no verified site: ideal website and digital-marketing prospects
- **Multi-area coverage** — one run across dozens of trade + area pairs, including county and postcode-area targeting
- **Reputation snapshots** — capture score and review counts over time to spot rising and falling trades
- **Supplier and merchant prospecting** — build target lists of high-volume trades by postcode area
- **Territory planning** — measure how many trades serve each area before you invest
- **CRM enrichment** — backfill missing numbers, services and profile links on UK trade records
- **Zapier / Make / n8n automations** — real-time webhook pushes each lead into your stack as it is collected
- **AI and LLM pipelines** — JSON records for scoring, outreach drafting and market summaries

***

### Features

| Feature | Default | What it does |
|---------|---------|--------------|
| **Trade & area search** | ✅ on | Search by trade and UK area (town, county, or postcode area). Multiple trade + area pairs per run, each with its own cap. |
| **Profile & lead details** | ✅ on | Enriches each business in place with profile detail: description, number, area, skills, services, score, review signals, membership date, vetting checks, photos and recent reviews. |
| **Reviews per profile** | 3 | How many recent reviews to attach (0 disables review capture). |
| **Contact discovery** | ⬜ off | Adds the business's own website, contact emails, extra numbers and social profiles where they are publicly available and verified against the business name and area. |
| **Scrape By URL** | ⬜ off | Collect specific Checkatrade profile links instead of searching. |

#### Trade & area search — on by default

Run **several trade + area pairs in one run** — for example *Plumber in Bristol* and *Electrician in London* side by side. Each task has its own maximum. Common job titles are mapped to the right trade automatically: `plumbers` → Plumber, `gas engineer` → Central-Heating, `decorator` → Painter-Decorator, `loft conversion` → Loft-Conversions.

Areas accept a town, a county, or a postcode area: `Bristol`, `City Of Edinburgh`, `Leeds, UK`, `KT1`, `BS30`.

#### Profile & lead details — the enrichment engine

When on, every business is additionally enriched with:

- **Business detail** — trading description, summary, primary trade, skills and full services list
- **Contact number** — normalised to +44 form
- **Score and reviews** — Checkatrade score (out of 10), review volume, and recent reviews with author, date and rating
- **Trust signals** — membership start month, number of vetting checks passed, and any displayed guarantee
- **Media** — logo and profile photos

This adds a little extra time per business but **never removes a row**: every business goes to the dataset even if its profile is sparse. Turn it off for the fastest possible listing-only runs.

#### Contact discovery — opt-in

When on, each business is matched to its **own** website, which is verified against the business name and area before it is ever attached to a row (a confidence signal of `high` / `medium` / `low` is reported). Directory and social pages are never presented as the business's site. Emails, extra numbers and social profiles are then read from that site. Off by default because it adds extra time per business.

#### Scrape By URL

Paste profile links (one per line) to enrich a list you already have.

#### Webhooks

Real-time push of every record to your CRM, Slack, Zapier, Make, or custom URL — see [Webhook delivery](#webhook-delivery-optional).

***

### Input reference

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| **Trade & area search** | | | |
| `enableSearch` | boolean | `true` | Turn trade + area search on or off |
| `searchTasks` | object\[] | 2 example tasks | **Primary input:** `{ trade, location, maxResults? }` per row |
| `maxResultsPerTask` | integer | `10` | Default maximum businesses per task |
| `maxPagesPerTask` | integer | `5` | Maximum result pages per task (safety cap, 1–50) |
| **Profile & lead details** | | | |
| `enableProfileDetails` | boolean | `true` | Enrich every business with profile detail. **Never filters rows.** |
| `maxReviewsPerProfile` | integer | `3` | Reviews to include per business (0–20) |
| `enableContactDiscovery` | boolean | `false` | Add verified website, emails, numbers and socials |
| **Scrape By URL** | | | |
| `enableScrapeByUrl` | boolean | `false` | Collect specific profile links |
| `scrapeUrls` | string\[] | — | Profile link list |
| **Output & limits** | | | |
| `maxItems` | integer | `10000` | Global cap on total rows (set higher for large runs) |
| `concurrency` | integer | `4` | Parallel detail lookups (1–8) |
| `delayBetweenRequestsMs` | integer | `1200` | Polite pacing between collections (0–5000 ms) |
| `webhookUrl` | string | — | Optional real-time POST URL |
| `webhookFormat` | enum | `json` | `json` (full record) or `slack` (Slack message) |
| `proxyConfiguration` | object | residential, United Kingdom | Apify proxy settings |

Full schema: see `.actor/input_schema.json` or the **Input** tab on Apify Console.

#### Example — multi-area trade search

```json
{
  "enableSearch": true,
  "searchTasks": [
    { "trade": "Plumber", "location": "Bristol", "maxResults": 50 },
    { "trade": "Electrician", "location": "Leeds", "maxResults": 50 },
    { "trade": "Roofer", "location": "KT1", "maxResults": 25 }
  ],
  "enableProfileDetails": true,
  "maxItems": 150
}
```

#### Example — lead gen with contacts

```json
{
  "enableSearch": true,
  "searchTasks": [
    { "trade": "Builder", "location": "Kent", "maxResults": 100 }
  ],
  "enableProfileDetails": true,
  "enableContactDiscovery": true,
  "maxItems": 100
}
```

#### Example — enrich a profile list

```json
{
  "enableSearch": false,
  "enableScrapeByUrl": true,
  "scrapeUrls": [
    "https://www.checkatrade.com/trades/hqplumbing",
    "https://www.checkatrade.com/trades/ljeplumbingheating"
  ],
  "enableProfileDetails": true
}
```

***

### Output reference

Each dataset row is one business. Filter by `featureType`:

| `featureType` | Description |
|---------------|-------------|
| `search` | Business from trade + area search |
| `scrape_by_url` | Business from a profile link |

Field-by-field documentation: see the tables above and `.actor/dataset_schema.json`.

**Run summary:** every run also writes an `OUTPUT` record to the key-value store with totals, enabled features, spending-limit status, and the paywall object:

```json
{
  "totalPushed": 10,
  "tasksRequested": 1,
  "tasksCompleted": 1,
  "profileDetailsEnabled": true,
  "contactDiscoveryEnabled": false,
  "errors": [],
  "spendingLimitReached": false,
  "paywall": {
    "detected": true,
    "isPaying": true,
    "pricingTier": "GOLD",
    "limited": false,
    "blocked": false,
    "freeTierMaxItems": null
  }
}
```

Export formats: **JSON**, **CSV**, **Excel**, **RSS**, or via the dataset's own export links.

***

### Webhook delivery (optional)

Every record is **always saved to the Apify dataset** first. If you set `webhookUrl` in the **Output & limits** section, each new record is **also POSTed in real time** to your URL — useful for CRMs, Slack, Zapier, Make, or custom pipelines.

| Setting | Description |
|---------|-------------|
| `webhookUrl` | Your destination (https recommended). Leave empty to use the dataset only. |
| `webhookFormat` | `json` — the full record object. `slack` — compact Slack incoming-webhook message. |

Webhook delivery is **best-effort**: a failed delivery never stops the run or prevents dataset writes. Only the published record fields are sent — no internal or debug data is ever included.

**Payload (json format)** — the exact record object documented in [Output reference](#output-reference), including `profileDetails`, `score` and `reviews` when present.

**Payload (slack format)**:

```json
{
  "text": ":wrench: *HQ Plumbing*\n*Trade:* Plumber  •  *Score:* 9.93 /10 (191 reviews)\n*Phone:* +447453348767\n*Area:* Bristol\n<https://www.checkatrade.com/trades/hqplumbing|View profile>"
}
```

**Example — search with Slack alerts**

```json
{
  "enableSearch": true,
  "searchTasks": [{ "trade": "Plumber", "location": "Bristol", "maxResults": 10 }],
  "webhookUrl": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
  "webhookFormat": "slack"
}
```

**Example — lead gen with JSON webhook**

```json
{
  "enableSearch": true,
  "searchTasks": [{ "trade": "Electrician", "location": "Manchester", "maxResults": 25 }],
  "enableProfileDetails": true,
  "webhookUrl": "https://your-crm.example.com/leads",
  "webhookFormat": "json"
}
```

***

### Automation

Start a run from Apify Console, from a schedule, or from any tool that can make an outbound call, then export the dataset as JSON, CSV, or Excel. A typical run input:

```json
{ "enableSearch": true, "searchTasks": [{ "trade": "Plumber", "location": "Bristol", "maxResults": 25 }] }
```

Schedule it in Apify Console to keep a rolling UK trade lead list current without manual work.

***

### LLM & MCP integration

Output is **JSON Lines–friendly structured data** — ideal for ChatGPT, Claude, Gemini, LangChain, LlamaIndex, and custom agents.

#### Recommended workflow

1. Run the Actor with the tasks you need.
2. Export dataset items as JSON or CSV.
3. Pass records to your LLM with a system prompt, or index them into a vector store.

#### Example record for an LLM prompt

```json
{
  "name": "HQ Plumbing",
  "primaryCategory": "Plumber",
  "town": "Bristol",
  "phone": "+447453348767",
  "score": 9.93,
  "ratingScale": 10,
  "reviewCount": 191,
  "memberSince": "March 2023",
  "skills": ["Plumber", "Radiator Installation", "Bathroom & Kitchen Plumbing"],
  "searchTaskLabel": "Plumber | Bristol"
}
```

#### Apify MCP (Model Context Protocol)

Use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) so AI assistants can:

- **Run** this Actor with natural-language instructions ("find 20 highly rated plumbers in Bristol with phone numbers")
- **Read** dataset results directly in the chat
- **Chain** it with other Actors (enrich → score → CRM)

Typical MCP flow:

```
User: "Find 15 well-reviewed electricians in Leeds and draft short outreach intros"
→ MCP runs the Actor with searchTasks=[{ trade: "Electrician", location: "Leeds" }], enableProfileDetails=true
→ MCP reads the dataset items
→ The assistant summarises each business and drafts the messages
```

***

### Proxy & performance

- **Apify residential proxy (United Kingdom)** is **enabled by default** — no extra setup required. Change it in the **Connection** section of the input if you need a different route or custom proxy URLs.
- Default memory: **512 MB** — enough headroom for most runs.
- Results are **streamed to the dataset** as they are collected; long runs do not pile up data in memory.
- 4 parallel detail lookups by default; raise `concurrency` to 8 for the fastest runs.

***

### Reliability notes

- Runs use **UK-based rotating residential routing** by default — no user setup required.
- If the source answers with a temporary busy or verification page, the run switches route automatically and continues, logging a plain-language message. It never exposes technical details in logs or output.
- If a trade and area combination has no results, that task logs a warning and the run continues with the next one.

***

### Free tier (Apify free plan)

This Actor requires a paid Apify plan for full output.

| Your Apify plan | What happens |
|---|---|
| **Apify free plan** | Runs are capped: a maximum of **2 results** per run, then the run finishes gracefully with a message to upgrade. |
| **Any paid Apify plan** (Bronze → Diamond) | ✅ Full, uncapped output up to your `maxItems` — and your run's max-total-charge limit is always respected. |

When a free-tier run hits the cap, the Actor finishes **gracefully** with a clear status message ("Free tier limit reached — results were capped. Upgrade to a paid Apify plan for full, unlimited data."). Your collected sample stays in the dataset — nothing is lost and nothing looks like an error.

The paywall status is also written to the run summary as a transparent `paywall` object (`detected`, `isPaying`, `pricingTier`, `limited`, `blocked`) — see [Output reference](#output-reference).

***

### FAQ

**Is this really limited on the Apify free plan?**
Yes. Free-plan runs export a maximum of 2 results. This is a policy restriction, not a bug — upgrade to any paid Apify plan for full output.

**Does enrichment change how many results I get?**
No — and that's deliberate. *Profile & lead details* and *Contact discovery* enrich every business; they never remove rows. Businesses with a sparse profile are still exported (with those fields empty). This keeps your output count — and therefore your per-run cost — predictable.

**What do I type for the area?**
A town, a county, or a postcode area: `Bristol`, `Greater London`, `City Of Edinburgh`, `Kent`, `KT1`, `BS30`. Country suffixes such as `Leeds, UK` are accepted and cleaned up automatically.

**Which trades are supported?**
Any trade the directory covers — plumbers, electricians, builders, roofers, painters and decorators, handymen, gardeners, tilers, plasterers, joiners, glazing, fencing, removals, pest control, cleaning, heating and boilers, driveways, loft and garage conversions, solar, EV chargers, security, CCTV and many more. Common job titles and aliases are mapped to the closest trade automatically.

**How accurate is the website and email information?**
Websites are only attached after they are verified against the business name and area, with a reported confidence level (`high`, `medium`, `low`). Directory and social pages are never presented as the business's own site. Emails come from the verified business's own pages. When nothing reliable is found, those fields stay empty — the row is still exported.

**Do you support every UK area?**
Any town, county, or postcode area the directory covers. Very small areas may return few or no trades — the Actor warns you and continues.

**How fresh is the data?**
Each run collects live results at the moment it runs. Schedule the Actor to keep a list current.

**How fast is a run?**
Listing results arrive in seconds. With *Profile & lead details* on, add a little extra time per business; with *Contact discovery* on, add a little more. Raise `concurrency` for the fastest runs.

**Can I get an alert for every lead as it arrives?**
Yes — set `webhookUrl` (and `webhookFormat: slack` for Slack). Each record is POSTed to your URL in real time as it is exported.

**Does the run respect my max total charge?**
Yes. The Actor tracks your maximum charge for the run and stops collecting — gracefully, with a clear message — as soon as that limit is reached. You are never charged beyond what you allowed.

**Where is the run summary?**
In the run's key-value store under the `OUTPUT` record — totals, enabled features, spending-limit status, and the transparent `paywall` object. It is linked from the run's Output tab.

**Is this affiliated with Checkatrade?**
No. This Actor is an independent data tool. Use it responsibly and comply with applicable laws and the site's terms.

***

### Limitations & compliance

- Data availability depends on what each business's listing and public pages expose. Some trades publish fewer details than others.
- Not affiliated with Checkatrade. Use responsibly and comply with applicable laws and their Terms of Service.
- Always respect rate limits and local regulations when collecting business data.

***

### Contact & custom work

Need something beyond this Actor? I build **custom data pipelines** and **full-stack applications** for startups and enterprises.

- **Email:** <dubem115@gmail.com>
- **GitHub:** [github.com/DrunkCodes](https://github.com/DrunkCodes)

Reach out for:

- Custom Apify Actors (any site or data source)
- UK lead-gen data projects at scale
- LLM & MCP integrations with your data stack
- Web apps, dashboards, and automation tools

***

*Checkatrade Real-Time Data · by [DrunkCodes](https://github.com/DrunkCodes)*

# Actor input Schema

## `enableSearch` (type: `boolean`):

Search Checkatrade by trade and area (town, county, or postcode). Enabled by default.

## `searchTasks` (type: `array`):

Primary input. Add one row per search: a trade plus a UK area (town/county name or postcode).

## `maxResultsPerTask` (type: `integer`):

Default maximum businesses per search task. Override per task in the list above.

## `maxPagesPerTask` (type: `integer`):

How many result pages of the same search to collect (safety cap for very large runs).

## `enableProfileDetails` (type: `boolean`):

Enrich every business in place with its full profile: trading description, phone number, service area, skills and services, vetting information, membership date, and customer review signals. Every business is still exported even when a profile has little detail — this adds a little extra time per business.

## `maxReviewsPerProfile` (type: `integer`):

How many recent customer reviews to attach to each business when profile details are on (0 disables review capture).

## `enableContactDiscovery` (type: `boolean`):

Adds the business's own website, contact emails, extra phone numbers, and social profiles where they are publicly available and verified against the business name and area. Off by default because it adds extra time per business.

## `enableScrapeByUrl` (type: `boolean`):

Collect specific Checkatrade business profiles instead of searching.

## `scrapeUrls` (type: `array`):

Checkatrade business profile links to collect (one per line), e.g. https://www.checkatrade.com/trades/hqplumbing

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

Global cap on total dataset rows across all features. Set high for large runs (e.g. 10000+). Note: the run also respects your max total charge for this run.

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

How many detail lookups to run in parallel (1–8). Higher is faster; 4 is a good default.

## `delayBetweenRequestsMs` (type: `integer`):

Polite pacing between collections (0–5000 ms). Higher values are slower but gentler.

## `webhookUrl` (type: `string`):

Optional. Every record is always saved to the run's dataset — this webhook is an ADDITIONAL real-time push. When set, each new record is also POSTed to this URL (CRM, Slack incoming webhook, Zapier, Make, Google Sheets).

## `webhookFormat` (type: `string`):

json = full record object; slack = Slack-friendly message payload.

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

Apify residential proxy (United Kingdom) is enabled by default for reliable collection of this UK directory.

## Actor input object example

```json
{
  "enableSearch": true,
  "searchTasks": [
    {
      "trade": "Plumber",
      "location": "Bristol",
      "maxResults": 10
    },
    {
      "trade": "Electrician",
      "location": "London",
      "maxResults": 10
    }
  ],
  "maxResultsPerTask": 10,
  "maxPagesPerTask": 5,
  "enableProfileDetails": true,
  "maxReviewsPerProfile": 3,
  "enableContactDiscovery": false,
  "enableScrapeByUrl": false,
  "scrapeUrls": [],
  "maxItems": 10000,
  "concurrency": 4,
  "delayBetweenRequestsMs": 1200,
  "webhookUrl": "",
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# Actor output Schema

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

Complete dataset with every business row from all enabled features in this run.

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

Businesses from trade + area search.

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

Per-run metadata: totals, enabled features, spending-limit status, and the paywall object (detected, isPaying, pricingTier, limited, blocked).

# 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 = {
    "enableSearch": true,
    "searchTasks": [
        {
            "trade": "Plumber",
            "location": "Bristol",
            "maxResults": 10
        },
        {
            "trade": "Electrician",
            "location": "London",
            "maxResults": 10
        }
    ],
    "maxResultsPerTask": 10,
    "maxPagesPerTask": 5,
    "enableProfileDetails": true,
    "maxReviewsPerProfile": 3,
    "enableContactDiscovery": false,
    "maxItems": 10000,
    "concurrency": 4,
    "delayBetweenRequestsMs": 1200,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/checkatrade-real-time-data-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 = {
    "enableSearch": True,
    "searchTasks": [
        {
            "trade": "Plumber",
            "location": "Bristol",
            "maxResults": 10,
        },
        {
            "trade": "Electrician",
            "location": "London",
            "maxResults": 10,
        },
    ],
    "maxResultsPerTask": 10,
    "maxPagesPerTask": 5,
    "enableProfileDetails": True,
    "maxReviewsPerProfile": 3,
    "enableContactDiscovery": False,
    "maxItems": 10000,
    "concurrency": 4,
    "delayBetweenRequestsMs": 1200,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/checkatrade-real-time-data-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 '{
  "enableSearch": true,
  "searchTasks": [
    {
      "trade": "Plumber",
      "location": "Bristol",
      "maxResults": 10
    },
    {
      "trade": "Electrician",
      "location": "London",
      "maxResults": 10
    }
  ],
  "maxResultsPerTask": 10,
  "maxPagesPerTask": 5,
  "enableProfileDetails": true,
  "maxReviewsPerProfile": 3,
  "enableContactDiscovery": false,
  "maxItems": 10000,
  "concurrency": 4,
  "delayBetweenRequestsMs": 1200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call b2b_leads/checkatrade-real-time-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_leads/checkatrade-real-time-data-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/lc6XurafbSxkiHNi0/builds/puCSO0zPvd4g6I4b7/openapi.json
