# Expertise.com MSP Lead Scraper: Providers by City with Contacts (`getascraper/expertise-msp-leads-scraper`) Actor

Scrape public Expertise.com MSP city pages into lead records with provider IDs, phones, websites, addresses, ratings, reviews, and change history. Export JSON or CSV to Google Sheets, Airtable, HubSpot, or n8n without browser automation. $0.00175 per provider record.

- **URL**: https://apify.com/getascraper/expertise-msp-leads-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.31 / 1,000 msp records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## 🏢 Expertise.com MSP lead scraper: providers by city with contacts

<table width="100%">
<tr>
<td style="padding:24px 28px;background:#F0FDFA;border:1px solid #99F6E4;border-top:4px solid #0F766E;border-radius:12px">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">Build a focused MSP prospect list for any supported city.</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Collect public managed IT provider names, contact details, ratings, reviews, and change signals from Expertise.com city pages.</span>
</td>
</tr>
</table>

<table width="100%">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #99F6E4;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#115E59">📍 City targeting</span><br>
<span style="font-size:12px;color:#57534E">Compare up to 20 public MSP city pages in one run.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #99F6E4;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#115E59">☎️ Public contacts</span><br>
<span style="font-size:12px;color:#57534E">Keep public phones, websites, addresses, and optional site contacts together.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #99F6E4;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#115E59">⭐ Review signals</span><br>
<span style="font-size:12px;color:#57534E">Filter by Expertise.com rating, review count, and featured placement.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #99F6E4;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#115E59">🔄 Change tracking</span><br>
<span style="font-size:12px;color:#57534E">Reuse a state name to find new, changed, unchanged, and removed providers.</span>
</td>
</tr>
</table>

Use the output for territory planning, sales research, local-market studies, or scheduled MSP coverage checks. Every row stays tied to its public city source.

### 🎯 Why use it?

- **Sales teams:** start outreach with a city-specific list of providers that expose public contact channels.
- **IT agencies:** compare territories without merging providers from different city pages.
- **Market researchers:** study editorial placement, ratings, reviews, and public service coverage.
- **Operations teams:** schedule the same state and review only factual provider changes.

### 💰 Pricing

This Actor uses pay per result pricing. Each provider row is one result. Empty runs cost nothing, and there is no subscription requirement.

### ⭐ Enjoying Expertise.com MSP lead scraper: providers by city with contacts?

<table width="100%" style="display:table;width:100%">
<tr>
<td style="padding:20px 24px 14px;background:#F0FDFA;border:1px solid #99F6E4;border-left:5px solid #0F766E;border-radius:10px 10px 0 0">
<span style="font-size:20px;letter-spacing:4px;color:#0F766E">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">Save a sales research cycle with a cleaner MSP territory list.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps sales teams find a focused public-provider workflow.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#0F766E;border:1px solid #99F6E4;border-top:none;border-radius:0 0 10px 10px;text-align:center">
<a href="https://apify.com/getascraper/expertise-msp-leads-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### 🧭 How to use it

<table width="100%">
<tr>
<td style="padding:16px 14px;width:33%;background:#F0FDFA;border:1px solid #99F6E4;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#0F766E;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Choose city pages</span><br>
<span style="font-size:12px;color:#57534E">Add public Expertise.com MSP pages for one city or several territories.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#F0FDFA;border:1px solid #99F6E4;border-left:none;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#0F766E;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Set lead filters</span><br>
<span style="font-size:12px;color:#57534E">Keep providers by rating, reviews, featured status, phone, website, or description.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#F0FDFA;border:1px solid #99F6E4;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:12px;font-weight:800;color:#0F766E;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Schedule a comparison</span><br>
<span style="font-size:12px;color:#57534E">Reuse the same state name to see provider changes on the next run.</span>
</td>
</tr>
</table>

### 🧾 Input

| Field                          | Type          | Required | Description                                                                                     |
| ------------------------------ | ------------- | -------- | ----------------------------------------------------------------------------------------------- |
| `startUrls`                    | array of URLs | Yes      | Public Expertise.com MSP city pages. Up to 20 city pages are accepted.                          |
| `minExpertiseRating`           | decimal       | No       | Keep providers at or above a rating from 0 to 5. Use 0 to keep all ratings.                     |
| `minReviewCount`               | integer       | No       | Keep providers with at least this many public aggregate reviews. Use 0 to disable the floor.    |
| `featuredOnly`                 | boolean       | No       | Keep only provider cards marked as featured by Expertise.com.                                   |
| `requirePhone`                 | boolean       | No       | Keep only providers with a public phone number.                                                 |
| `requireWebsite`               | boolean       | No       | Keep only providers with a public website link.                                                 |
| `requireDescription`           | boolean       | No       | Keep only cards with a public provider description.                                             |
| `proxyConfiguration`           | object        | No       | Use direct requests by default. An Apify Proxy can be selected for a specific reliability need. |
| `includeDescription`           | boolean       | No       | Include the public provider description when available.                                         |
| `includeReviewSources`         | boolean       | No       | Include source ratings and links such as Google, Yelp, or Facebook when available.              |
| `includeImages`                | boolean       | No       | Include image URLs exposed by the provider card.                                                |
| `includePublicWebsiteContacts` | boolean       | No       | Visit linked business websites for visible business emails and social links.                    |
| `maxWebsiteRequests`           | integer       | No       | Bound public website requests from 0 to 50 when contact enrichment is enabled.                  |
| `maxItems`                     | integer       | No       | Maximum provider rows after filtering and deduplication, from 1 to 500.                         |
| `outputMode`                   | enum          | No       | Choose `snapshot`, `snapshotAndChanges`, or `changesOnly`.                                      |
| `stateName`                    | text          | No       | Stable name used to compare the same city pages across scheduled runs.                          |

### 📊 Data table

| Field                     | Type             | Description                                                           |
| ------------------------- | ---------------- | --------------------------------------------------------------------- |
| `recordType`              | string           | Always `provider` for a business row.                                 |
| `vertical`                | string           | Source vertical, `managed-service-providers`.                         |
| `providerId`              | string           | Stable Expertise.com provider identifier.                             |
| `dedupeKey`               | string           | Provider and city key used for deduplication.                         |
| `providerName`            | string           | Public provider name.                                                 |
| `city`                    | string           | Public city associated with the source page.                          |
| `state`                   | string           | Public state abbreviation.                                            |
| `citySlug`                | string           | Canonical city slug from the source URL.                              |
| `sourceUrl`               | string           | Public city page that produced the row.                               |
| `sourceVerticalUrl`       | string           | Public managed service provider vertical URL.                         |
| `providerProfileUrl`      | string           | Public provider anchor URL on the city page.                          |
| `scrapedAt`               | date-time string | Time the row was collected.                                           |
| `changeType`              | string           | `new`, `changed`, `unchanged`, or `removed`.                          |
| `position`                | number           | Editorial provider position when exposed.                             |
| `isFeatured`              | boolean          | Whether the source marks the provider as featured.                    |
| `categoryName`            | string           | Public source category name.                                          |
| `description`             | string           | Public provider description when requested.                           |
| `phone`                   | string           | Public business phone number.                                         |
| `websiteUrl`              | string           | Public business website URL.                                          |
| `websiteDomain`           | string           | Domain from the public business website.                              |
| `streetAddress`           | string           | Public street address.                                                |
| `postalCode`              | string           | Public postal code.                                                   |
| `country`                 | string           | Public country code.                                                  |
| `logoUrl`                 | string           | Source-provided logo URL when requested.                              |
| `expertiseRating`         | number           | Public Expertise.com rating.                                          |
| `reviewCount`             | number           | Public aggregate review count.                                        |
| `reviewSources`           | array            | Public review-source ratings and links when requested.                |
| `sourceUpdatedAt`         | date-time string | Source update time when available.                                    |
| `directoryEmail`          | string           | Public email shown in the directory, when available.                  |
| `websiteEmails`           | array            | Public business emails found on an opted-in linked website.           |
| `emailSource`             | string           | Indicates whether an email came from the directory or linked website. |
| `publicSocialLinks`       | array            | Public social links found during opted-in enrichment.                 |
| `publicContactChannels`   | array            | Factual channels such as phone, website, email, or social link.       |
| `hasPublicPhone`          | boolean          | Whether a public phone is present.                                    |
| `hasWebsite`              | boolean          | Whether a public website is present.                                  |
| `hasPublicEmail`          | boolean          | Whether a public email is present.                                    |
| `leadCompletenessScore`   | number           | Deterministic score based on factual public field coverage.           |
| `changedFields`           | array            | Factual fields that changed since the previous complete run.          |
| `previousExpertiseRating` | number           | Previous rating when a rating change is detected.                     |
| `previousReviewCount`     | number           | Previous review count when a review change is detected.               |
| `previousPhone`           | string           | Previous public phone when it changed.                                |
| `previousWebsiteUrl`      | string           | Previous public website when it changed.                              |
| `changeDetectedAt`        | date-time string | Time a factual change was detected.                                   |
| `isActive`                | boolean          | Whether the provider is present in the current complete source.       |
| `removedAt`               | date-time string | Time a provider was confirmed absent after a complete run.            |

#### Example output

```json
{
    "recordType": "provider",
    "vertical": "managed-service-providers",
    "providerId": "796730",
    "dedupeKey": "796730:nyc",
    "providerName": "TEKConn Services Inc.",
    "city": "New York",
    "state": "NY",
    "citySlug": "nyc",
    "sourceUrl": "https://www.expertise.com/business/managed-service-providers/new-york/nyc",
    "providerProfileUrl": "https://www.expertise.com/business/managed-service-providers/new-york/nyc#tekconnservicesinc",
    "position": 1,
    "isFeatured": true,
    "categoryName": "Managed IT Service Providers",
    "phone": "2124614310",
    "websiteUrl": "https://www.tekconn.com/contact-us/",
    "websiteDomain": "www.tekconn.com",
    "streetAddress": "237 W 35th St Ste 805",
    "postalCode": "10001",
    "country": "US",
    "expertiseRating": 4.75,
    "reviewCount": 30,
    "sourceUpdatedAt": "2026-09-17T13:31:32.000Z",
    "hasPublicPhone": true,
    "hasWebsite": true,
    "hasPublicEmail": false,
    "leadCompletenessScore": 71,
    "publicContactChannels": ["phone", "website"],
    "changeType": "new",
    "isActive": true
}
```

### 🔄 Monitoring

- **Snapshot:** return current provider rows with their factual change state.
- **Snapshot and changes:** return current rows and confirmed removals after a complete run.
- **Changes only:** return only `new`, `changed`, and `removed` rows.

The first complete run marks current providers as `new`. An identical later run marks them as `unchanged`. A factual source update marks a provider as `changed`. A capped or partially failed run never infers removals.

### 🛡️ Public data and limits

This Actor reads public Expertise.com business listings in the managed IT service provider vertical. It does not request credentials, private provider pages, private-person records, or restricted lead forms.

Website contact enrichment is optional and limited to publicly linked business websites. The Actor does not infer emails from domains or names. Missing source fields are omitted instead of replaced with placeholders.

The source can change its public page layout. A source problem is isolated to the affected city page and recorded in the run summary when possible.

### 🗂️ Dataset views

1. **🏢 MSP leads:** provider names, locations, public contacts, ratings, and source links.
2. **📈 Lead quality and contacts:** contact coverage and deterministic completeness scores.
3. **🔄 Provider changes:** new, changed, unchanged, and removed provider records.

### 🧪 Example input

```json
{
    "startUrls": [
        "https://www.expertise.com/business/managed-service-providers/new-york/nyc",
        "https://www.expertise.com/business/managed-service-providers/california/los-angeles"
    ],
    "requireWebsite": true,
    "includeReviewSources": true,
    "maxItems": 20,
    "outputMode": "snapshotAndChanges",
    "stateName": "msp-territories"
}
```

### ❓ FAQ

##### Can a city request be blocked?

The Actor uses conservative public-page requests, bounded retries, and isolated source handling. An Apify Proxy can be selected when a workflow needs an alternate route, but no source access method is guaranteed.

##### Does it collect private phone numbers?

No. It returns only business contact values publicly shown by Expertise.com or an opted-in linked business website.

##### How fresh is the data?

Each run reads the current public city pages. Reuse a state name on a schedule to compare the latest provider facts with the previous complete run.

##### Can I scrape other Expertise.com categories?

No. This Actor is limited to the managed IT service provider vertical so filters, fields, and change records stay predictable.

### 🔗 Other actors

- [BUSINESS.bg scraper: Bulgarian company leads, фирмени контакти](https://apify.com/getascraper/business-bg-company-leads-scraper) ↗ - collect public Bulgarian company leads and contact fields.
- [Fonecta scraper for Finnish leads: yrityshaku data in JSON](https://apify.com/getascraper/fonecta-business-leads-scraper) ↗ - build Finnish business lead lists from public directory results.
- [Bizi.si Slovenia Scraper: Slovenska podjetja for Business Leads](https://apify.com/getascraper/bizi-si-business-scraper) ↗ - collect public Slovenian company records for sales research.
- [US licensed contractor directory](https://apify.com/getascraper/us-licensed-contractor-directory) ↗ - find public US contractor records for compliance and prospecting.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/expertise-msp-leads-scraper/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Public Expertise.com managed IT provider city pages only. Add up to 20 city pages for a multi-city lead list.

## `minExpertiseRating` (type: `number`):

Keep providers whose public Expertise.com rating meets this optional 0 to 5 floor. Use 0 to disable the floor.

## `minReviewCount` (type: `integer`):

Keep providers with at least this many public aggregate reviews when the source reports a count. Use 0 to disable the floor.

## `featuredOnly` (type: `boolean`):

Keep only cards marked as featured by Expertise.com.

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

Keep only provider cards that expose a public phone number.

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

Keep only providers with a public website link supplied by Expertise.com.

## `requireDescription` (type: `boolean`):

Keep only cards with a public provider description.

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

Direct HTTP is the default. Select Apify Proxy only when your workflow needs an alternate route.

## `includeDescription` (type: `boolean`):

Keep the public Why choose this provider description in each row.

## `includeReviewSources` (type: `boolean`):

Keep the public Google, Yelp, Facebook, or other review-source ratings and links when present.

## `includeImages` (type: `boolean`):

Keep image URLs exposed by the provider card. No image URL is constructed when the source omits it.

## `includePublicWebsiteContacts` (type: `boolean`):

Visit linked business websites to collect visible business emails and social links. No contacts are inferred.

## `maxWebsiteRequests` (type: `integer`):

Bound public business website requests when contact enrichment is enabled.

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

Maximum provider rows emitted after filtering, deduplication, and optional enrichment.

## `outputMode` (type: `string`):

Snapshot emits current rows, snapshot and changes also emits removals after complete runs, and changes only omits unchanged rows.

## `stateName` (type: `string`):

Stable name used to compare this set of city pages across scheduled runs.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.expertise.com/business/managed-service-providers/new-york/nyc"
  ],
  "minExpertiseRating": 0,
  "minReviewCount": 0,
  "featuredOnly": false,
  "requirePhone": false,
  "requireWebsite": false,
  "requireDescription": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "includeDescription": false,
  "includeReviewSources": false,
  "includeImages": false,
  "includePublicWebsiteContacts": false,
  "maxWebsiteRequests": 20,
  "maxItems": 20,
  "outputMode": "snapshotAndChanges",
  "stateName": "default"
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "startUrls": [
        "https://www.expertise.com/business/managed-service-providers/new-york/nyc"
    ],
    "minExpertiseRating": 0,
    "minReviewCount": 0,
    "featuredOnly": false,
    "requirePhone": false,
    "requireWebsite": false,
    "requireDescription": false,
    "proxyConfiguration": {
        "useApifyProxy": false
    },
    "includeDescription": false,
    "includeReviewSources": false,
    "includeImages": false,
    "includePublicWebsiteContacts": false,
    "maxWebsiteRequests": 20,
    "maxItems": 20,
    "outputMode": "snapshotAndChanges",
    "stateName": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/expertise-msp-leads-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 = {
    "startUrls": ["https://www.expertise.com/business/managed-service-providers/new-york/nyc"],
    "minExpertiseRating": 0,
    "minReviewCount": 0,
    "featuredOnly": False,
    "requirePhone": False,
    "requireWebsite": False,
    "requireDescription": False,
    "proxyConfiguration": { "useApifyProxy": False },
    "includeDescription": False,
    "includeReviewSources": False,
    "includeImages": False,
    "includePublicWebsiteContacts": False,
    "maxWebsiteRequests": 20,
    "maxItems": 20,
    "outputMode": "snapshotAndChanges",
    "stateName": "default",
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/expertise-msp-leads-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 '{
  "startUrls": [
    "https://www.expertise.com/business/managed-service-providers/new-york/nyc"
  ],
  "minExpertiseRating": 0,
  "minReviewCount": 0,
  "featuredOnly": false,
  "requirePhone": false,
  "requireWebsite": false,
  "requireDescription": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "includeDescription": false,
  "includeReviewSources": false,
  "includeImages": false,
  "includePublicWebsiteContacts": false,
  "maxWebsiteRequests": 20,
  "maxItems": 20,
  "outputMode": "snapshotAndChanges",
  "stateName": "default"
}' |
apify call getascraper/expertise-msp-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/expertise-msp-leads-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/B6Tf2CdXeg7Vcub80/builds/07g3a0HiuzWWYBV2p/openapi.json
