# EnergySage Scraper: Solar Installers, Reviews & Solar Costs (`oswaldocarabano/energysage-solar-installers-scraper`) Actor

Scrape EnergySage: a US solar installers list with rating, tier, phone, email, website, services, licenses and certifications; customer reviews with sub-ratings; and solar cost per watt, system price and payback for 50 states and 4,882 cities. No login, no API key.

- **URL**: https://apify.com/oswaldocarabano/energysage-solar-installers-scraper.md
- **Developed by:** [Oswaldo Carabano](https://apify.com/oswaldocarabano) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 installers

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

## EnergySage Scraper: Solar Installers List, Reviews & Solar Costs

**Build a US solar installers list from EnergySage, the largest US solar
marketplace.** Every EnergySage-listed solar company with its rating, tier,
phone, email, website, licenses and certifications; the customer reviews behind
each rating; and the local solar cost per watt, system price and payback that
EnergySage publishes for every state and 4,882 cities.

**No login. No cookies. No browser. No API key.** From $0.00045 per installer.

Use it as an **EnergySage API** for solar installer leads, a solar company
database by state (California, Texas, Florida, New York…), solar company
reviews, or solar cost per watt by state and city.

***

### What you can use this for

| If you are… | You want |
|---|---|
| Selling to **solar installers** (software, financing, equipment, leads) | the installer list with business phone (99.0 %), email (96.5 %) and website (99.5 %) |
| Mapping the **US residential solar market** | installers per state and city, EnergySage tier, years in business, states served |
| Doing **competitive research** on installers | the full review history with four sub-ratings and the installer's replies |
| Modelling **solar prices and payback** | cost per watt, average system size and price, payback years and 25-year savings per state and city |
| Qualifying partners | licenses, insurance, NABCEP and manufacturer certifications, workmanship warranty |

***

### Three outputs, one per run

Pick one with `outputType`. Each run returns one kind of row, so the table in
the Output tab is always clean.

| `outputType` | One row is | Measured on 23 Sep 2026 |
|---|---|---|
| `installers` (default) | a solar installer company | 200 installers on EnergySage's state and city pages; 6,822 supplier profiles in the full directory |
| `locations` | a state or city page with its local solar cost data | 50 state pages + 4,882 city pages (Alaska has none) |
| `reviews` | one customer review | 12 per request; the largest installer has over 500 |

***

### What actually arrives in a row

Every percentage below was measured against the live site on 23 Sep 2026 and
carries its sample size. **Fields we did not measure are not promised.**

#### Installers — always there (n = 200, every installer on the location pages)

`installer_id` · `name` · `slug` · `profile_url` · `logo_url` · `tier_code` and
`tier` (Elite+, Elite, Advanced, Approved) · `hq_city` · `hq_state` · the
location page it was found on and its rank there — **100 %**.

Also: `description` 97.5 % · `why_work_with_us` 98.5 % · `year_established`
96.5 % · `hq_street` 98.5 % · `hq_postal_code` 99.5 % · `rating` and
`review_count` 93.5 % (new installers have no reviews yet).

#### Installers — with the full profile (`scrapeDetails: true`, n = 200)

| Field | Filled |
|---|---:|
| `phone` | 99.0 % |
| `email` | 96.5 % |
| `website` | 99.5 % |
| `badge`, `screened_verified`, `states_served` | 100 % |
| `services` (Installation, Financing, Roofing, Electrical Contracting…) | 99.0 % |
| `reasons_to_work_with` | 99.0 % |
| `workmanship_warranty` | 96.0 % |
| `rating_response`, `rating_quality`, `rating_value`, `rating_service` | 93.5 % |
| `licenses` (with license numbers when published) | 92.0 % |
| `industry_certifications` | 90.0 % |
| `languages` | 86.0 % |
| `certifications` (NABCEP and others) | 83.5 % |
| `manufacturer_certifications` (e.g. Enphase Platinum Installer) | 83.0 % |
| `insurance` | 78.0 % |
| `product_manufacturers` (with their EnergySage IDs) | 65.0 % |
| `financing_partners` | 65.0 % |
| `other_locations` (branch offices) | 42.0 % |
| `associated_installers` | 23.5 % |

A profile row carries a median of **42 of 45** profile fields populated.

#### Locations (n = 150 state and city pages)

**100 %:** `cost_per_watt` · `median_cost_per_watt` · `average_system_size_kw` ·
`average_price` · `below_average_price` · `above_average_price` ·
`percent_need_met` · `installer_count` · `review_count` · `overall_rating` ·
`registered_properties` · `net_metering_state` · `latitude` · `longitude` ·
`last_updated` · the same figures for a national-average-size system and the
national benchmark · the ranked `installers` of the page.

`payback_years` and `lifetime_savings_net` 96.0 %. `top_cities` (the city links
of a state page) on state pages only.

#### Reviews (n = 360 reviews of 15 installers)

`review_id` · `installer_id` · `title` · `text` · `rating_overall` · `date` ·
`reviewer_name` (the public alias shown on EnergySage) — **100 %**.
Sub-ratings `rating_value` 98.1 % · `rating_responsiveness` 97.8 % ·
`rating_quality` 97.5 % · `rating_service` 97.2 %. `verified_shopper` is true
on 65.0 %. The installer's reply (`installer_response`, its author and date)
is present on 18.6 %.

#### What we do NOT promise

- **Prices per watt of a single installer.** EnergySage publishes cost data per
  location, not per company. We deliver it per location.
- **The whole directory is not 6,822 installers.** Most profiles are
  manufacturers, lenders or inactive: 13 of 33 sampled directory profiles offer
  installation. `onlyInstallers` keeps just those.

***

### Input

| Field | Default | What it does |
|---|---|---|
| `outputType` | `installers` | `installers`, `locations` or `reviews` |
| `states` | empty (= CA, TX, FL when nothing else is set) | US state codes or names |
| `cities` | — | `"Berkeley, CA"` or an EnergySage city URL |
| `installerUrls` | — | profile URLs or IDs, for installers or reviews |
| `scrapeDetails` | `false` | add the full profile to each installer |
| `source` | `locations` | `directory` walks all 6,822 supplier profiles |
| `includeCityPages` | `true` | locations: also every city of the chosen states |
| `maxReviewsPerInstaller` | 24 | reviews per installer, 0 = all |
| `maxResults` | 50 | hard cap on rows |

A run with the default input returns 47 installers (California, Texas and
Florida) in about 5 seconds on the Apify platform (measured 30 Sep 2026).
With the full profile, 20 installers take about 35 seconds.

***

### How fast is it

Location pages are served from a cache and are read in parallel. Installer
profiles and reviews come from EnergySage's own server, which slows down clients
that open them in parallel: we measured rate limiting at 4 parallel requests and
none at one request every 1.5 seconds. So profiles and reviews are read one at a
time, about 40 per minute, and the log says so at the start. If EnergySage ever
asks us to slow down, the whole run pauses, tells you in the status message, and
resumes — nothing is lost and nothing extra is charged.

***

### Pricing

| Event | Price |
|---|---:|
| Actor start | $0.00001 |
| **Installer** | **$0.00045** |
| Full installer profile (added to an installer row) | $0.0004 |
| Location | $0.004 |
| Review | $0.0003 |

An installer with its full profile costs $0.00085, so 1,000 solar companies
with phone, email and website cost $0.85. You are never charged for an
error row or for a duplicate within a run. If you set a maximum charge for the
run, the actor stops cleanly when it is reached and says so.

***

### Privacy

- **Installers are businesses.** Their phone, email and website are the
  business contact details they publish on EnergySage to win customers.
- **Reviews are written by consumers.** You get the public alias they sign with,
  exactly as EnergySage shows it, never their internal user ID. Any phone
  number or email a reviewer typed inside the review text is replaced with
  `[phone removed]` or `[email removed]`.

**Data removal:** write to **privacy@actorstack.dev**.

***

### Frequently asked questions

**What data can I scrape from EnergySage?**
Installer companies (name, tier, rating, review count, year established,
headquarters, description, and with the full profile phone, email, website,
services, licenses, insurance, certifications, warranty and states served),
customer reviews with four sub-ratings, and local solar cost data per state and
city.

**Can I get solar installer phone numbers and emails?**
Yes. With `scrapeDetails: true`, phone came back on 99.0 % and email on 96.5 %
of the 200 installers listed on EnergySage's location pages (23 Sep 2026).

**How many solar installers are on EnergySage?**
200 unique installers appear on the 50 state pages and 4,882 city pages. The
supplier directory holds 6,822 profiles, including manufacturers, lenders and
inactive companies; use `source: directory` to walk it.

**What does solar cost in my state?**
Run `outputType: locations` with your state: you get cost per watt, average
system size and price, payback years and lifetime savings, for the state and,
with `includeCityPages`, every city EnergySage covers there.

**Does it need an EnergySage account or API key?**
No. No account, no cookie, no browser and no API key. EnergySage has no public
API; this actor is the practical EnergySage API: call it from the Apify API,
schedule it, or export CSV, Excel or JSON.

**Can I get a list of solar companies in California, Texas or Florida?**
Yes. Put the state in `states` (for example `CA`). The state page lists every
EnergySage installer active in that state; add `scrapeDetails: true` for
phone, email and website. Use `cities` (`"Austin, TX"`) for a single city.

**Is this a solar installation leads list?**
It is a list of solar installer companies (B2B): the businesses that install
solar, with their public business contacts. It is not a list of homeowners
looking for solar.

**How fresh is the data?**
Every run reads EnergySage live. Nothing is served from a stale copy.

**Why is a run slower with full profiles or reviews?**
EnergySage slows down clients that open profiles in parallel, so profiles and
reviews are read one at a time, about 40 per minute. Location pages are fast.

***

### Disclaimer

This actor extracts **publicly available** data — no login, no account. You are
responsible for how you use the data, including compliance with applicable
privacy and marketing laws. It is not affiliated with or endorsed by EnergySage.

# Actor input Schema

## `outputType` (type: `string`):

One row type per run. Installers: every EnergySage-listed solar installer of the chosen states or cities, with rating, review count, EnergySage tier, year established and headquarters (add the full profile below for phone, email, website, services, licenses, certifications and more). Locations: local solar cost data for each state and city page (cost per watt, average system size and price, payback years, lifetime savings) plus the ranked installers of that location. Reviews: customer reviews of the installers, with the four sub-ratings and the installer's reply.

## `states` (type: `array`):

US state codes or names, e.g. CA, TX, New York. Each state page lists ALL EnergySage installers active in that state (measured: 50 state pages, 200 unique installers nationwide on 23 Sep 2026). Leave states, cities and installer URLs all empty to get California, Texas and Florida. Alaska has no EnergySage page.

## `cities` (type: `array`):

Optional. "City, ST" (e.g. "Berkeley, CA") or an EnergySage solar-companies city URL. 4,882 city pages exist. For installers, a city returns the installers that serve it (a subset of its state); for locations, the city's own solar cost data.

## `includeCityPages` (type: `boolean`):

Locations output only: also read every city page of each chosen state (California alone has 566). Off returns just the state pages. Installers do not need it: the state page already lists every installer of the state.

## `installerUrls` (type: `array`):

Optional. EnergySage installer profile URLs (https://www.energysage.com/supplier/23948/next-solar/) or bare IDs. Installers output: returns the full profile of each. Reviews output: returns their reviews.

## `scrapeDetails` (type: `boolean`):

Installers output only: open each installer's profile page and add phone (99.0 % filled), email (96.5 %), website (99.5 %), badge, services, product manufacturers, financing partners, licenses, insurance, certifications, workmanship warranty, the four sub-ratings, other locations and states served (fill rates measured on all 200 installers). One extra request per installer, read at about one every 1.5 seconds, and billed as a separate event.

## `source` (type: `string`):

Where the installer list comes from. Location pages (default): the 200 installers EnergySage ranks on its state and city pages, with tier, rating and review count — fast. Full directory: every supplier profile in EnergySage's directory (6,822 profiles, of which about 39 % offer installation), read one profile at a time at about 40 per minute; always includes the full profile. Use the state filter to keep profiles serving those states.

## `onlyInstallers` (type: `boolean`):

Full directory source only: keep just the profiles that list "Installation" among their services (measured 13 of 33 sampled directory profiles). Turn off to also get manufacturers, lenders and other suppliers.

## `maxReviewsPerInstaller` (type: `integer`):

Reviews output only. EnergySage serves reviews 12 at a time; 0 means all of them (the largest installer has over 500).

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

Hard cap on delivered rows of the chosen type. Rows are charged one by one as they are delivered, never error rows or duplicates.

## `maxConcurrency` (type: `integer`):

How many location pages are read at once (they are served from a cache and were measured clean at 2 per second). Profiles and reviews are always read one at a time, because EnergySage slows down clients that open them in parallel.

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

Not needed: EnergySage answered every measured request directly. Only used as a fallback if the site starts refusing requests.

## Actor input object example

```json
{
  "outputType": "installers",
  "cities": [],
  "includeCityPages": true,
  "installerUrls": [],
  "scrapeDetails": true,
  "source": "locations",
  "onlyInstallers": true,
  "maxReviewsPerInstaller": 24,
  "maxResults": 20,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

The rows of this run: installers, locations (local solar cost data) or reviews.

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

Counts of delivered and charged rows, request statistics and whether the run stopped early.

## `errors` (type: `string`):

Items that could not be delivered and why (never charged). Always present, empty when nothing went wrong.

# 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 = {
    "outputType": "installers",
    "scrapeDetails": true,
    "maxResults": 20
};

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

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = {
    "outputType": "installers",
    "scrapeDetails": True,
    "maxResults": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "outputType": "installers",
  "scrapeDetails": true,
  "maxResults": 20
}' |
apify call oswaldocarabano/energysage-solar-installers-scraper --silent --output-dataset

```

## MCP server setup

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

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

## OpenAPI specification

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