Angi Home Services Scraper
Pricing
from $8.00 / 1,000 provider enricheds
Angi Home Services Scraper
Scrape Angi (Angie's List) home-service pros by city, ZIP, category URL, or profile — name, phone, rating, reviews, address, website. Cookieless; residential proxy required. MCP-ready.
Pricing
from $8.00 / 1,000 provider enricheds
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Scrape public Angi (Angie's List) home-service providers by category + city/state, ZIP, companylist URL, or profile URL. Each dataset row is one contractor with name, phone, rating, review count, address, website, categories, badges, and Angi profile URL from public guest pages — cookieless directory access. Run it from Apify Console, the Apify API, or Apify MCP with Apify RESIDENTIAL US proxy (required for Angi Cloudflare).
Built for B2B contractor shortlists, local-market research, and CRM enrichment when your workflow starts from Angi directories (plumbing, HVAC, electrical, roofing, and other published trades). Phone numbers are included when Angi publishes them on the guest profile; some merchants keep phone gated.
Best fit
Use this Actor when you need Angi directory providers for a trade in a US city, or you already have angi.com companylist/profile URLs and want a flat, billable provider dataset for MCP, CRM, or spreadsheet workflows.
When you need Google Maps NAP or Yelp business directories instead, continue with Local Business Lead Generator — Google Maps or Yelp Scraper All-in-One. Keep Angi URLs and trade+city directory jobs on this Actor.
Practical scenario
A home-services marketplace lead needs plumbers in Austin, TX for an outreach shortlist. They run the Console prefill (plumbing, austin, tx, maxResults: 3, enrichDetails: true). The dataset returns three Angi providers with rating, review count, profile URL, and enriched public fields when available. On a second run they set enrichDetails: false for a cheaper listing-card scan, then enrich only the shortlisted profiles with direct profile startUrls.
Quick start input
{"category": "plumbing","city": "austin","state": "tx","maxResults": 10,"enrichDetails": true}
Input reference
| Field | Type | What it controls |
|---|---|---|
category | string | Angi trade slug (prefill: plumbing) |
city | string | City slug or name (prefill: austin) |
state | string | Two-letter US state (prefill: tx) |
zipCodes | array | Optional US ZIPs resolved to city/state when category is set |
startUrls | array | Angi companylist or profile URLs |
maxResults | integer | Cap 1–2000 (default 100, prefill 3) |
enrichDetails | boolean | Profile enrich vs listing cards (default true) |
includeReviews | boolean | Attach bounded review previews (default false) |
maxReviewsPerProvider | integer | Review preview cap when includeReviews is true |
minRating | number | Keep providers at or above this star rating |
requirePhone / requireWebsite | boolean | Keep only rows with phone/website |
maxPagesPerListing | integer | Listing pagination bound |
proxyConfiguration | object | Use Apify RESIDENTIAL US |
Empty input with no category/city/state, ZIP+category, or Angi URLs finishes INVALID_INPUT with zero provider charges.
What data you receive
One dataset item is one Angi provider. Download the dataset as JSON, HTML, CSV, or Excel.
| Field | Meaning |
|---|---|
businessName | Public Angi display name |
angiUrl | Canonical profile URL |
phone | Public phone when Angi publishes it |
website | External website when published |
rating / grade / reviewCount | Public reputation signals |
categories / services | Trade categories |
street / city / state / postalCode | Address when published |
badges | Super Service Award, certified, and similar public badges |
reviews | Optional bounded review previews |
scrapedAt | ISO-8601 collection time |
{"businessName": "Example Plumbing Co","angiUrl": "https://www.angi.com/business/example-plumbing/12345","phone": "(512) 555-0100","website": "https://example-plumbing.example","rating": 4.8,"reviewCount": 42,"city": "Austin","state": "TX","categories": ["Plumbing"],"scrapedAt": "2026-09-17T12:00:00.000Z"}
OUTPUT and RUN_SUMMARY in the default key-value store hold outcome, itemsPushed, and chargedEventCounts.
Pricing
This Actor uses Pay per event plus platform usage. Event prices below are the launch defaults; treat the live Pricing tab on the Actor page as the current source of truth, because platform usage (compute and residential proxy) is billed to the caller in addition to named events.
| Event | Price |
|---|---|
apify-actor-start | $0.00005 |
provider-found (listing-only) | $0.005 per saved listing card |
provider-enriched (primary) | $0.008 per enriched provider |
Invalid input, empty matches, and total Cloudflare challenges skip the named provider events. Worked example: maxResults: 10 with enrich on ≈ $0.00005 start + 10 × $0.008 = about $0.08005 in named events, plus platform usage.
Best results
Start with category + city + state and maxResults at 3–20 while validating a new metro. Prefer city+state over ZIP-only or state-only hubs — Angi companylist city pages are the reliable route. Keep enrichDetails: true when you need phone, address, website, and badges; set it false for cheaper directory scans. Turn on requirePhone only when your CRM needs dialable rows (some guest profiles omit phone). Use direct profile startUrls for refresh jobs when you already have Angi links.
How it works
The Actor uses Cheerio over HTTP with Apify RESIDENTIAL US (Chrome TLS) to clear Angi Cloudflare, parses public JSON-LD ItemList / LocalBusiness payloads, optionally opens each profile for enrich, dedupes by Angi URL, and writes honest OUTPUT / RUN_SUMMARY outcomes (COMPLETE, PARTIAL, VALID_EMPTY, INVALID_INPUT, UPSTREAM_FAILED).
Use through the API
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('khadinakbar/angi-home-services-scraper').call({category: 'plumbing',city: 'austin',state: 'tx',maxResults: 10,enrichDetails: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Use with AI agents through Apify MCP
Find 10 Angi plumbers in Austin, TX. Return businessName, phone, rating, reviewCount, angiUrl, city, state, and scrapedAt. Read the dataset plus OUTPUT for outcome and provenance, then confirm cost on the Pricing tab.
Connect via https://mcp.apify.com. Tool name: apify--angi-home-services-scraper. Cost signal: about $0.008 per enriched provider (or $0.005 listing-only) plus platform usage. Confirm current event prices on the Actor Pricing tab before large runs. Scope stays public Angi guest directory fields; private sessions and lead-marketplace actions belong on other workflows.
Outcomes
| Outcome | Meaning |
|---|---|
COMPLETE | At least one provider saved. |
PARTIAL | Some providers saved; others empty or hit a charge/request stop. |
VALID_EMPTY | Input resolved with zero matching public providers. |
INVALID_INPUT | No usable category/city/state, ZIP+category, or Angi URLs. |
UPSTREAM_FAILED | Cloudflare or transport returned no useful pages. |
Legal & responsible use
Use this Actor for public Angi directory and profile data you are authorized to process under applicable laws and site terms. Respect privacy rules (including GDPR/CCPA where applicable) and marketing contact rules for outreach. Keep use cases to legitimate research, lead generation, and analysis. Angi and Angie's List are trademarks of Angi Inc. This independent Actor is not affiliated with, associated with, or endorsed by Angi Inc.
Builder's note
I found that bare HTTP against angi.com returns Cloudflare 403, while Cheerio + Apify RESIDENTIAL US clears the challenge with a lean HTTP path. Current listing and profile pages expose structured data as JSON-LD ItemList / LocalBusiness, so the parser follows that path after live probes. State-only companylist hubs and phone-gated guest profiles finish as honest VALID_EMPTY when filters leave zero rows, so billing stays tied to persisted providers.