Indeed Jobs Scraper With Employer Email Leads
Pricing
from $2.99 / 1,000 results
Indeed Jobs Scraper With Employer Email Leads
Indeed Jobs Scraper with Employer Email Leads extracts job listings, company details, job titles, locations, salaries, descriptions, and publicly available employer contact emails. Build targeted hiring-company lead lists for recruitment, sales, and business development.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Indeed Jobs Scraper — Employer Leads, Emails and Phone Numbers
This Actor scrapes Indeed job listings and turns each hiring employer into a single lead row — company name, job title, salary, location, the employer's own website, its Facebook/X/Instagram profile as recorded by Indeed, and any public email or phone address found on that company's own site. It's built for recruiters, B2B sales teams and staffing agencies that prospect from hiring signals instead of static company lists. Contact hit rates are measured and reported honestly every run, not promised.
What is Indeed Jobs Scraper With Employer Email Leads?
It's an Apify Actor that queries Indeed's mobile-app GraphQL endpoint (apis.indeed.com/graphql — the same one Indeed's iOS app calls) for job listings, then optionally crawls the employer's own website to find a public email and phone number. No Playwright and no HTML parsing on the Indeed side — just authenticated GraphQL requests. No Indeed account, login, or API key is required to run it; the Actor authenticates with a public, non-secret iOS-app key.
Key features:
- 🔎 Two ways to find employers — search by keyword, location, radius and country (63 Indeed domains supported), or paste Indeed search /
/cmp/company page URLs directly - 🏢 One row per employer, not per duplicate listing —
uniqueCompaniesOnlycollapses repeat postings from the same company into a single row carryinglistingsForThisEmployerand the employer's other open roles - 📧 Employer contact lookup — visits the employer's own site (homepage plus up to 9 more best-scoring contact/about/imprint pages) and extracts public
mailto:addresses andtel:numbers, filtered against a denylist of tracker/ATS/placeholder domains and validated with real phone-numbering-plan logic - 🔗 Social profiles from two sources — Facebook/X/Instagram read straight out of Indeed's own employer record (no extra request), plus LinkedIn/Twitter/Facebook/Instagram/YouTube found during the website crawl
- 🎚️ Real filters — freshness (last 24 hours to 30 days), job type, remote/hybrid, US seniority level, and sort by relevance or date
- 📤 Structured JSON output via the Apify dataset, exportable to CSV, Excel, JSON, JSONL, XML or an RSS feed
What data can I extract with Indeed Jobs Scraper?
Every field below is written by the Actor's row-builder (_transform_to_required_structure plus _build_output_row in src/main.py), not just the 13 columns shown in the default dataset table view.
Lead fields (flat, always present on every row)
| Field | Example Value | Use Case |
|---|---|---|
jobId | "a1b2c3d4e5f6g7h8" | Unique Indeed job key, dedup key |
title | "Sales Representative" | Role that triggered the lead |
companyName | "Acme Retail Group" | Employer name |
locationShort | "New York, NY" | Quick geo filter |
postedText | "3 days ago" | Recency at scrape time |
salaryText | "$55,000 - $70,000 a year" | Compensation signal |
jobUrl | "https://www.indeed.com/viewjob?jk=a1b2c3d4e5f6g7h8" | Link back to the listing |
employerName | "Acme Retail Group" | CRM company field |
employerWebsite | "https://acmeretailgroup.com" | Outbound target / enrichment key |
employerEmail | "careers@acmeretailgroup.com" | Best public email found |
employerPhone | "+12125551234" | Best public phone found, E.164 |
employerContactStatus | "ok" | Why the lookup succeeded/failed |
hasEmployerEmail | true | Quick filter flag |
hasEmployerPhone | false | Quick filter flag |
hasEmployerContact | true | Email or phone present |
listingsForThisEmployer | 3 | Open-role count behind this row |
isEmployerRollup | true | Whether this row is a rollup or a single listing |
employer.* — employer identity, from Indeed's own record
| Field | Example Value | Use Case |
|---|---|---|
employer.key | "c9d8e7f6" | Indeed's internal employer ID (used to group listings) |
employer.name | "Acme Retail Group" | — |
employer.identityUsed | "employerKey" | Which identity strategy grouped this employer (employerKey, employerName, or jobKey) |
employer.websiteUrl | "acmeretailgroup.com" | Raw value as Indeed lists it, before normalization |
employer.indeedCompanyPageUrl | "https://www.indeed.com/cmp/Acme-Retail-Group" | Indeed's own employer profile page |
employer.industry | "Retail" | — |
employer.numEmployees | "501 to 1,000 employees" | Company-size band |
employer.revenue | "$100M to $500M (USD)" | — |
employer.socialProfiles.facebook/twitter/instagram | "https://facebook.com/acmeretail" | From Indeed's dossier, no extra request |
employer.socialProfilesSource | "indeed_employer_dossier" | null when Indeed had none on file |
employerContacts.* — the website contact lookup result
| Field | Example Value | Use Case |
|---|---|---|
employerContacts.websiteUrl | "https://acmeretailgroup.com" | Normalized site that was crawled |
employerContacts.status | "ok" | ok, blocked, js_required, unreachable:*, no_website_on_indeed, lookup_disabled |
employerContacts.emails[] | ["careers@acmeretailgroup.com"] | All emails surviving the junk filter |
employerContacts.emailsOnCompanyDomain[] | ["careers@acmeretailgroup.com"] | Emails on the employer's own registrable domain |
employerContacts.primaryEmail | "careers@acmeretailgroup.com" | Best single email (on-domain preferred) — same value as employerEmail |
employerContacts.emailsDroppedAsJunk | 2 | Addresses rejected as trackers/placeholders |
employerContacts.phones[] | ["+12125551234"] | Validated (libphonenumber) numbers |
employerContacts.phonesUncertain[] | [] | Numbers found but not validated as real |
employerContacts.primaryPhone | "+12125551234" | Best single phone — same value as employerPhone |
employerContacts.socialProfiles.linkedin/twitter/facebook/instagram/youtube[] | ["https://linkedin.com/company/acme-retail"] | Profiles found on the crawled pages |
employerContacts.sourceUrl | "https://acmeretailgroup.com" | First page any contact was found on |
employerContacts.emailSourceUrl / .phoneSourceUrl | "https://acmeretailgroup.com/contact" | Provenance per contact type |
employerContacts.contactPageUrl | "https://acmeretailgroup.com/contact" | Highest-scoring contact page checked |
employerContacts.pagesChecked[] / .pagesCheckedCount | 2 | Audit trail of what was actually fetched |
employerContacts.hasEmail / .hasPhone / .hasAnyContact | true | Boolean summary flags |
otherListingsForThisEmployer[] — up to 25 of the employer's other open roles when uniqueCompaniesOnly is on: jobId, title, locationShort, postedText, salaryText, jobUrl.
job.* — the underlying Indeed listing (unchanged from a plain job scraper)
| Field | Example Value | Use Case |
|---|---|---|
job.descriptionText / job.descriptionHtml | "We are seeking a…" | Full posting text |
job.isRemote / job.remoteLocation | false | Remote flag |
job.jobType[] | ["Full-time"] | From Indeed's attribute keys |
job.attributes[] | ["401(k)", "Health insurance"] | Raw Indeed attribute labels |
job.benefits[] | ["Health insurance", "Paid time off"] | Keyword-matched subset of attributes |
job.salary.min/max/type/currency/weeklyMin/weeklyMax | 55000 / 70000 / "yearly" | Parsed compensation |
job.dates.postedText/datePublished/pubDateEpoch | "2026-08-13" | Freshness fields |
job.hiring.*, job.status.expired/newJob | false | See note below — always false/null, not live-derived on this endpoint |
company.* — Indeed's employer profile fields: name, industry, revenue, numEmployees, description, addresses[], rating.score/rating.count (always null — Indeed's mobile endpoint returns no rating on this query), ceo.name/ceo.photoUrl, branding.logoUrl/branding.headerUrl, links.corporateWebsite/.facebook/.instagram/.twitter/.indeedCompanyPage, emails[] (mirrors employerContacts.emails).
location.*: countryCode, country, state, stateName, city, postalCode, streetAddress, formattedShort, formattedLong, latitude/longitude (always null — not requested from the GraphQL API on this query).
apply.*: jobUrl, applyUrl, originalApplyUrl, thirdPartyApplyUrl, indeedApplyEnabled.
sourceMeta.* (source, scrapingInfo.page/.index) and _raw (the complete unshaped record, kept for debugging/advanced use).
Note on placeholder fields:
job.status.expired,job.status.newJob,job.hiring.urgentlyHiring,job.hiring.highVolumeHiring,job.hiring.isRepost,job.hiring.organicApplyStarts/.numOfCandidates,company.rating.*,company.foundedYear, andlocation.latitude/longitudeare alwaysfalse/nullin the current output — Indeed's mobile GraphQL endpoint does not return live values for these on the query this Actor sends. They're kept in the schema for compatibility with a plain job-listing scraper's output shape, not because they carry live data.
📧 Employer contact & social data
employerContacts is the section that turns a job posting into a sales lead: primaryEmail/primaryPhone for outreach, emailsOnCompanyDomain to separate a real company mailbox from a third-party form-vendor address, and status + pagesChecked so a "no contact found" row is distinguishable from a lookup that never ran. A typical use: filter rows to hasAnyContact: true and push employerName, employerEmail, employerPhone straight into a CRM import.
🎯 Targeting and segmentation fields
location.city/.state/.postalCode narrow a lead list to a territory; job.dates.datePublished and fromDays isolate employers hiring right now versus weeks ago; employer.industry, employer.numEmployees and employer.revenue let you segment a lead list by company size or vertical before you ever open a CRM.
Why not build this yourself?
Building an "Indeed jobs plus employer contact leads" pipeline from scratch means solving several separate scraping problems before the first usable lead row exists.
- Indeed has no documented public search API for this — job data comes back from its mobile-app GraphQL endpoint, authenticated with the same
indeed-api-key/user-agent pair Indeed's own iOS app uses (reverse-engineered and published by the open-source JobSpy project). That key is a single point of failure: if Indeed rotates it, every integration built on it starts returning 401/403 at the same moment, and there's no vendor support line to call. - Indeed shows the same employer under many separate listings. Collapsing those into one row per employer — with the employer's other open roles attached, and billed exactly once — is bookkeeping most scrapers don't do.
- Indeed's own data never includes an employer email or phone number. Getting one means a second, independent scrape of the employer's own website, with its own blocking behavior: Cloudflare-protected surfaces here were measured to key off TLS fingerprint rather than IP, so common Chrome/Edge client fingerprints returned a 28 KB challenge page in testing, while a specific pool of Safari/Firefox fingerprints did not.
- Separating a real employer contact from junk needs an actively maintained denylist, not a single regex — a naive
mailto:sweep on live sites returns error-tracker DSNs, Wix/Squarespace plumbing addresses, ATS-vendor mailboxes (icims.com,greenhouse.io,workday.com…), and image filenames likelogo@2x.pngthat happen to match an email pattern.
If you already have engineering time to reverse-engineer and maintain a mobile-API integration, build a Cloudflare-resistant crawler, and keep a junk-email filter current, doing this yourself is possible. For everyone else, this Actor runs that pipeline without the ongoing maintenance.
How to use data extracted from Indeed?
💼 B2B sales and SDR teams
Set hiringSearchTerm to a role that signals budget or growth (e.g. a specific skill or seniority you sell into), narrow with location/radius and fromDays to the freshest signal, then filter the resulting rows to hasEmployerContact: true. employerName, employerEmail, employerPhone and employer.industry map straight into an outreach list — listingsForThisEmployer doubles as a quick "how urgently are they hiring" score.
🧑💼 Staffing and recruitment agencies
Run the same search on a schedule against a client's target industry or geography, and diff successive runs on jobId/employer.key to see which employers are hiring consistently versus a one-off posting. job.dates.datePublished and postedText give a freshness read without opening Indeed manually.
📊 Market research and labour intelligence
Aggregate employer.industry, employer.numEmployees, location.city/.state and job.salary.min/.max across a run to map hiring density and pay bands by vertical or metro — for example, comparing median job.salary.min across location.city values for the same hiringSearchTerm.
🤖 AI agents and automated pipelines
Wrap the Actor as a tool that answers "who is hiring for X near Y right now, and how do I reach them" mid-conversation, or feed employerContacts and job fields into an enrichment pipeline that appends firmographic or intent data before a lead reaches a rep.
🔼 Input sample
Fill in Option 1 (search terms) or Option 2 (urls) — Option 2 wins if both are filled. No input parameter is required; every field has a working default.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
hiringSearchTerm | No | string | What the employer is hiring for — job title, skill or keyword. Default "Sales". | "Warehouse Associate" |
location | No | string | Restrict the employer list to one hiring area. Leave empty for the whole country. Default "". | "Chicago, IL" |
radius | No | string (enum) | Widen or tighten the hiring area. Values: "", "0", "5", "10", "15", "25", "35", "50", "100". Default "". | "25" |
countryCode | No | string (enum) | Which Indeed domain to search (63 country codes, e.g. us, uk, ca, de). Default "us". | "ca" |
maxLeadRows | No | integer | Number of distinct employers wanted (rollup ON) or listings wanted (rollup OFF). Min 1, max 10000. Default 10. | 50 |
uniqueCompaniesOnly | No | boolean | ON: one row per employer, charged once. OFF: one row per listing. Default true. | true |
findEmployerContacts | No | boolean | Visit the employer's own site for public contact details. Default true. | true |
maxContactPagesPerCompany | No | integer | Pages checked per employer site (homepage + best-scoring pages). Min 1, max 10. Default 3. | 3 |
onlyEmployersWithContact | No | boolean | Keep only employer rows where a contact was found. Default false. | false |
contactRequestTimeoutSeconds | No | integer | Timeout per employer-website request, in seconds. Min 5, max 60. Default 20. | 20 |
defaultPhoneRegion | No | string | Two-letter country code for numbers written without a +prefix. Default "" (inferred from the site's domain). | "US" |
fromDays | No | string (enum) | Freshness of the hiring signal. Values: "0" (no filter), "1", "3", "7", "14", "30". Default "0". | "7" |
jobType | No | string (enum) | Values: "", fulltime, parttime, contract, temporary, internship, volunteer, permanent, seasonal, freelance. Default "". | "fulltime" |
remote | No | string (enum) | Values: "", remote, hybrid. Default "". | "" |
level | No | string (enum) | US only. Values: "", entry_level, mid_level, senior_level. Default "". | "" |
sort | No | string (enum) | Values: "", relevance, date. Default "relevance". | "date" |
urls | No | array of string | Indeed search or /cmp/ employer URLs. Runs instead of Option 1 when filled. | ["https://www.indeed.com/jobs?q=sales&l=New+York%2C+NY"] |
maxRowsPerUrl | No | integer | Per-URL row cap when more than one URL is pasted (ignored with a single URL). Min 1, max 1000. | 20 |
enableUniqueJobs | No | boolean | Deduplicate listings across pages/URLs before rolling up employers. Default true. | true |
includeSimilarJobs | No | boolean | No-op on this endpoint — kept so older saved inputs still load. Default true. | true |
query | No | string | Compatibility field — overrides hiringSearchTerm when filled. | (leave empty) |
maxRows | No | integer | Compatibility field — overrides maxLeadRows when filled. Min 1, max 10000. | (leave empty) |
proxyConfiguration | No | object | Apify proxy config. No proxy is used by default; the Actor falls back to datacenter, then residential, on a block. | {"useApifyProxy": false} |
{"hiringSearchTerm": "Sales","location": "New York, NY","radius": "25","countryCode": "us","maxLeadRows": 25,"uniqueCompaniesOnly": true,"findEmployerContacts": true,"maxContactPagesPerCompany": 3,"onlyEmployersWithContact": false,"contactRequestTimeoutSeconds": 20,"fromDays": "7","jobType": "fulltime","sort": "date"}
Common pitfall: query and maxRows are compatibility fields kept for saved inputs from a plain job-listing scraper. If either is filled in — even accidentally left over from a copied input — it silently overrides hiringSearchTerm or maxLeadRows respectively. Leave both empty unless you're intentionally re-running an old saved input.
🔽 Output sample
Each run writes one JSON record per employer (or per listing, with rollup off) to the Apify dataset — typed, consistently shaped, and exportable as JSON, JSONL, CSV, Excel, XML or RSS. Runs that find no search input or get blocked by Indeed on every proxy tier write a single unbilled accounting record (_type: "run_accounting") instead of a lead row.
{"jobId": "a1b2c3d4e5f6g7h8","title": "Sales Representative","companyName": "Acme Retail Group","locationShort": "New York, NY","postedText": "3 days ago","salaryText": "$55,000 - $70,000 a year","jobUrl": "https://www.indeed.com/viewjob?jk=a1b2c3d4e5f6g7h8","employerName": "Acme Retail Group","employerWebsite": "https://acmeretailgroup.com","employerEmail": "careers@acmeretailgroup.com","employerPhone": "+12125551234","employerContactStatus": "ok","hasEmployerEmail": true,"hasEmployerPhone": true,"hasEmployerContact": true,"listingsForThisEmployer": 3,"isEmployerRollup": true,"employer": {"key": "c9d8e7f6","name": "Acme Retail Group","identityUsed": "employerKey","websiteUrl": "acmeretailgroup.com","indeedCompanyPageUrl": "https://www.indeed.com/cmp/Acme-Retail-Group","industry": "Retail","numEmployees": "501 to 1,000 employees","revenue": "$100M to $500M (USD)","socialProfiles": {"facebook": "https://facebook.com/acmeretail","twitter": "https://x.com/acmeretail","instagram": null},"socialProfilesSource": "indeed_employer_dossier"},"employerContacts": {"websiteUrl": "https://acmeretailgroup.com","status": "ok","emails": ["careers@acmeretailgroup.com"],"emailsOnCompanyDomain": ["careers@acmeretailgroup.com"],"primaryEmail": "careers@acmeretailgroup.com","emailsDroppedAsJunk": 2,"phones": ["+12125551234"],"phonesUncertain": [],"primaryPhone": "+12125551234","socialProfiles": {"linkedin": ["https://linkedin.com/company/acme-retail"],"twitter": [],"facebook": [],"instagram": [],"youtube": []},"sourceUrl": "https://acmeretailgroup.com","emailSourceUrl": "https://acmeretailgroup.com/contact","phoneSourceUrl": "https://acmeretailgroup.com/contact","contactPageUrl": "https://acmeretailgroup.com/contact","pagesChecked": ["https://acmeretailgroup.com", "https://acmeretailgroup.com/contact"],"pagesCheckedCount": 2,"hasEmail": true,"hasPhone": true,"hasAnyContact": true},"otherListingsForThisEmployer": [{"jobId": "z9y8x7w6","title": "Store Manager","locationShort": "Brooklyn, NY","postedText": "1 week ago","salaryText": "$65,000 a year","jobUrl": "https://www.indeed.com/viewjob?jk=z9y8x7w6"}],"job": {"id": "a1b2c3d4e5f6g7h8","title": "Sales Representative","descriptionText": "We are seeking a motivated Sales Representative...","isRemote": false,"jobType": ["Full-time"],"attributes": ["401(k)", "Health insurance", "Paid time off"],"benefits": ["Health insurance", "Paid time off"],"salary": {"text": "$55,000 - $70,000 a year","currency": "USD","type": "yearly","min": 55000,"max": 70000},"dates": {"postedText": "3 days ago","datePublished": "2026-08-13"},"status": { "expired": false, "newJob": false }},"company": {"name": "Acme Retail Group","industry": "Retail","numEmployees": "501 to 1,000 employees","emails": ["careers@acmeretailgroup.com"]},"location": {"countryCode": "US","country": "United States","state": "NY","stateName": "New York","city": "New York","formattedShort": "New York, NY"}}
How do you filter and target specific employer leads?
Precision targeting here works on three axes. Discovery: hiringSearchTerm + location/radius searches Indeed the way a recruiter would; urls lets you paste an exact Indeed search or /cmp/ employer page instead — URL query parameters (q, l, radius, fromage, jt, sort) override the top-level settings for that URL only, which matters when you're running several saved Indeed searches at once. Scope precision: location + radius narrow the hiring area; countryCode picks the Indeed domain (and therefore the country the employer list is drawn from); fromDays isolates employers hiring in a recent window — note this is mutually exclusive with jobType/remote server-side, so when fromDays is set those two become client-side post-filters instead. Volume and quality: maxLeadRows sets how many distinct employers (or listings) you want; onlyEmployersWithContact trims the list to rows with a verified public email or phone, at the cost of removing roughly 7 of every 10 rows at the measured hit rate; uniqueCompaniesOnly is the switch between an employer-level lead list and a raw listing feed.
Three real input examples:
{ "hiringSearchTerm": "warehouse", "location": "Dallas, TX", "radius": "25", "fromDays": "3", "maxLeadRows": 100 }
{ "hiringSearchTerm": "software engineer", "jobType": "fulltime", "remote": "remote", "level": "senior_level", "maxLeadRows": 40 }
{ "urls": ["https://www.indeed.com/jobs?q=nurse&l=Austin%2C+TX&radius=15&sort=date"], "onlyEmployersWithContact": true, "maxLeadRows": 30 }
▶️ Want to try other scrapers?
There's no second Indeed scraper on this account today — this Actor is the account's only Indeed integration. If your lead-generation workflow spans other directories, these SimpleAPI scrapers cover comparable ground:
| Scraper | What it extracts |
|---|---|
| Google Maps Reviews Scraper (Bad Review Finder) | Local business listings and their negative-review signal, for outreach targeting |
| Amazon DE Sellers Leads Scraper | Marketplace seller leads with product price and rating data |
| Shopify Merchant Scraper (Niche and Keyword Store Search) | Independent Shopify store leads by niche/keyword |
| Alibaba Listings Scraper and Supplier Profiles | Verified-supplier leads with MOQ and product data |
How to extract Indeed data programmatically
Every run is a standard Apify Actor call: one API request with your APIFY_API_TOKEN, a JSON input body, and a dataset of structured JSON rows back.
🐍 Python example
from apify_client import ApifyClientclient = ApifyClient("<APIFY_API_TOKEN>")run = client.actor("<username>/indeed-jobs-scraper-with-employer-email-leads").call(run_input={"hiringSearchTerm": "sales","location": "New York, NY","maxLeadRows": 50,"onlyEmployersWithContact": True,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["employerName"], row["employerEmail"], row["employerPhone"])
🔌 MCP for AI agents
This Actor is reachable through Apify's hosted Actors MCP Server at https://mcp.apify.com (checked 2026-08-16), which exposes any Apify Actor — including this one — as a callable tool over OAuth or a bearer APIFY_API_TOKEN, for MCP clients such as Claude.ai, Claude Code and VS Code. An agent can call it with a hiringSearchTerm and location to pull live employer contact leads mid-conversation, without a separate integration.
📊 Export to spreadsheets or CRM
Export the dataset as CSV or Excel directly from the Apify Console or API, mapping employerName → a company column, employerEmail/employerPhone → contact columns, title/salaryText/postedText → opportunity-context columns, and jobUrl/employer.indeedCompanyPageUrl → source-link columns.
Is it legal to scrape Indeed?
Scraping publicly visible job listings is generally legal — this Actor reads listing and employer data Indeed already serves to any visitor, the same way a browser would, and job postings, salaries and company profiles are business data, not personal data. Indeed's own terms of service should still be checked before large-scale or commercial use.
The employer contact data is a different case: most captured addresses are role-based business mailboxes (careers@, sales@, info@), but a contact page or "our team" page can expose a named individual's email or phone. Where a captured address is tied to an identifiable person rather than a generic company mailbox, GDPR (EU/UK) and CCPA (California) obligations around lawful basis, storage and deletion apply to that record just as they would to any other personal data you collect. Consult legal counsel for commercial applications involving bulk storage of personal data.
❓ FAQ
Does the Actor flag expired or removed job listings?
Not reliably — job.status.expired and job.status.newJob are always false on the current output, because Indeed's mobile GraphQL endpoint doesn't return a live status for these on the fields this Actor requests. Use job.dates.datePublished/postedText to judge freshness instead, and re-run the search periodically — a listing that has actually been pulled from Indeed simply won't reappear in a fresh crawl.
Can I get salary ranges and social profiles along with the contact leads?
Yes. job.salary (text, min, max, currency, type) comes from Indeed's own compensation block on every listing. employer.socialProfiles (Facebook/X/Instagram) comes from the same GraphQL request, at no extra cost. employerContacts.socialProfiles (LinkedIn/Twitter/Facebook/Instagram/YouTube) comes from the employer-website crawl and is only populated when findEmployerContacts finds a matching link on a checked page.
How accurate is the employer contact data?
It's exactly what's publicly published on the employer's own site at the time of the run — nothing is guessed or pattern-generated (no first.last@company.com inference). On this platform, a measured 24-employer sample (Sales / New York, NY / 25 mi) returned a public email or phone for 33% of employers (25% email, 8% phone); across every contact-enabled run measured, the aggregate is 24 of 82 employers (29%), and one nationwide default-input run returned 0 of 10. The rate swings hard by query and location — treat 25–33% as a good result and 0% as a real possibility. Recommend running standard email verification before any bulk outreach.
How many rows can I get per run?
maxLeadRows accepts 1 to 10000 (default 10). With uniqueCompaniesOnly on, the Actor pages through up to 6× the requested row count (minimum 100 listings) looking for that many distinct employers before stopping, so a very high maxLeadRows on a narrow query can return fewer employers than requested once Indeed's own result set is exhausted. maxRowsPerUrl (1–1000) caps rows per individual URL when more than one URL is pasted; with a single URL it's ignored.
What's the difference between "One row per employer" on and off?
ON (uniqueCompaniesOnly: true, the default): every hiring employer appears exactly once and is charged once, with listingsForThisEmployer and its other open roles attached. OFF: one row per job listing, exactly like a plain job scraper, charged per listing. Measured on this platform across two runs, 150 live listings collapsed to 104 and 97 distinct employers (−31% and −35%), with the busiest single employer holding 12 of those listings.
What's the difference between searching by keyword and pasting Indeed URLs?
hiringSearchTerm + location/radius/filters (Option 1) builds the search for you. urls (Option 2) runs instead of Option 1 when filled, and each URL is its own search — Indeed URL parameters (q, l, radius, fromage, jt, sort) override the top-level input for that specific URL. Use Option 2 when you already have exact saved Indeed searches or specific /cmp/ employer pages to work from.
Does this Actor work with Claude, ChatGPT, and AI agent frameworks?
Yes, via Apify's Actors MCP Server (https://mcp.apify.com), which exposes this Actor as a callable tool to MCP clients including Claude.ai, Claude Code, and VS Code. It's also callable as a plain HTTP endpoint by any agent framework using the Apify API.
How does this Actor compare to a typical Indeed job scraper?
A plain Indeed scraper returns one row per listing with no employer enrichment — this Actor adds employer rollup (uniqueCompaniesOnly), Indeed's own social-profile data, and an independent website crawl for public email/phone, while still emitting every field a plain job-listing scraper would (the base job/company/location/apply structure is unchanged and additive).
Can I use this Actor without an Indeed account or API key?
Yes. No Indeed login, cookie, or API key is required — the Actor authenticates against Indeed's mobile-app GraphQL endpoint with a public, non-secret key. You only need an Apify account to run the Actor itself.
What happens if Indeed blocks the request or rotates its API key?
On a 401/403/429 from Indeed, the Actor automatically escalates its proxy tier (direct → datacenter → residential, 3 retries per tier) and retries. If Indeed rotates the underlying mobile-app API key itself, every request will return a hard 401/403 that the proxy ladder cannot fix — this is a real limitation of building on a reverse-engineered endpoint rather than a documented API. Employer-website lookups escalate through the same tiered fallback independently when a specific site blocks the crawl.
Conclusion
Indeed Jobs Scraper With Employer Email Leads turns Indeed's hiring activity into an employer lead list — one row per company, not per duplicate posting — with the salary, location and role data a plain job scraper gives you, plus a real, measured public email and phone lookup on top. It's built for sales teams, recruiters and researchers who need contactable hiring employers, not just job postings, and it reports its own contact-hit rate every run instead of promising one. Start it from the Apify Console or API with a hiring search term and location, or paste Indeed URLs directly, to get your first batch of employer leads.