Multi Board Job Scraper — Indeed, LinkedIn & Employer Boards
Pricing
from $0.008 / job posting
Multi Board Job Scraper — Indeed, LinkedIn & Employer Boards
Search Indeed, LinkedIn and 56 employer career boards (Greenhouse, Lever, Ashby) in one run. Every posting is mapped onto one schema, deduplicated across boards and runs, with pay parsed into min/max/currency/period and seniority inferred from the title. No login, no browser.
Pricing
from $0.008 / job posting
Rating
0.0
(0)
Developer
Yuliia Kulakova
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
5 days ago
Last modified
Categories
Share

One job search across several boards at once, mapped onto a single schema and deduplicated — including the employer career boards most job scrapers skip. No login, no browser.
What it does
Most job scrapers cover one board. This one runs your search across several at once, maps every posting — whichever board it came from — onto one flat, consistent record, and drops duplicates both within a run (the same job cross-posted to two boards) and across scheduled runs, so a daily run can emit only what is new.
Everything is fetched over plain HTTP — no headless browser — so runs are fast and cheap.
Built for recruiters and sourcers, job-market and pay analytics, and anyone building or backfilling a jobs board.
Which boards you actually get
Verified on 2026-09-10. This table is the honest version — please read it before you buy.
| Board | Status |
|---|---|
| Indeed | ✅ Full search: query, location, country, radius, date filter |
| ✅ Full search, optional full description + board criteria per posting | |
| Greenhouse | ✅ Employer career boards — 32 curated companies, or pass your own |
| Lever | ✅ Employer career boards — 6 curated companies, or pass your own |
| Ashby | ✅ Employer career boards — 18 curated companies, with structured pay bands |
| Glassdoor | ⚠️ Works only without location — Glassdoor blocks its own location lookup (HTTP 403), so the board is skipped, with the reason in the log, whenever a location is set. Descriptions are short search-page snippets unless you turn on glassdoorFullDescription. |
| ZipRecruiter | ⚠️ United States and Canada only. Any other country is refused with a reason rather than answered with the wrong place. |
| Google Jobs | ❌ Does not currently work. Google guards its jobs widget; the board reports itself as blocked and is skipped. Never faked with placeholder data. |
The employer boards are the point. Greenhouse, Lever and Ashby are companies' own public career APIs — real employer-posted openings with clean structured fields and, on Ashby, real pay bands. Most multi-board scrapers don't touch them. The 56 curated boards were each checked to answer with live postings; you can also pass your own board tokens to target specific employers.
Key features
- Pick any subset of boards in one
boards[]input, in one run. - One normalized record for every board.
boardis kept on each row, so you always know where a posting came from. - Cross-board and cross-run dedup. Each posting gets a stable
dedupKeybuilt from company + title + city, after normalizing the things boards write differently:Acme Corp/Acme Inc/Acme,Sr./Senior,New York/New York, NY, United States. PointdeduplicateKeyStoreat a named key-value store to keep the keys between scheduled runs. - Salary you can actually filter on.
salary { min, max, currency, period, source }— the board's own figure when it publishes one, otherwise parsed from the posting text. In a description a number is only read as pay when a currency marker sits with it, so ordinary prose like "3-5 years of experience" or "a team of 50-200" never becomes a wage, and company money — "$70 billion in annual sales", "a $5.8B valuation" — is not mistaken for it. The period is read from right beside the amount, so an office-days sentence can't turn an annual figure into a weekly one. SetenforceAnnualSalaryto convert everything to an annual equivalent. - Seniority and job type on every board.
seniorityfrom the title, plusseniorityAllwith every level a title carries — "Senior Engineering Manager" is genuinely bothseniorandmanager, and a single field would have to drop one.jobTypefrom structured signals or the text. - Company extras where the board publishes them — rating, size, revenue, description, logo, industry. Filled only when the board actually returns them, never invented.
- Proxy fallback. Boards are fetched through the proxy group you configure; if that group keeps failing, the last retries switch to a datacenter session automatically and the switch is noted in the log. A group outage degrades a run instead of ending it.
RUN_SUMMARYin the key-value store: per-board counts, salary coverage, remote share, seniority and job-type breakdown, top companies, and every board that was skipped with the reason.
Input
Everything is optional except a query (or queries).
| Field | Type | Default | Description |
|---|---|---|---|
query | string | software engineer | Job title, keyword or skill, searched on every selected board. |
queries | array<string> | – | Several searches in one run, merged and deduped; each row is tagged matchedQuery. Max 5. |
location | string | remote | City, state, country or remote. Applies to Indeed and LinkedIn. Glassdoor cannot be filtered by location and is skipped when one is set. ATS boards are filtered in-process. |
boards | array<enum> | ["indeed","linkedin","glassdoor","greenhouse"] | indeed, linkedin, greenhouse, lever, ashby, glassdoor, ziprecruiter, google — see the table above for what each one can do. |
maxItemsPerBoard | integer | 25 | Postings per board, per query (0 = board maximum). |
remoteOnly | boolean | false | Keep only remote postings. |
jobType | enum | any | fulltime / parttime / contract / internship / temporary. |
maxDaysOld | integer | 0 | Only postings from the last N days (0 = any). |
country | string | us | Country for Indeed and Glassdoor (us, uk, canada, germany, india, …). ZipRecruiter accepts only us / canada. |
distance | integer | 50 | Search radius in miles for Indeed and LinkedIn (0–200). |
fetchDescription | boolean | true | Fetch the full LinkedIn description and board criteria per posting (one extra request each). |
glassdoorFullDescription | boolean | false | Fetch each Glassdoor posting's full description instead of the search-page snippet (one extra request each). |
descriptionFormat | enum | text | text / markdown / html. |
greenhouseCompanies | array<string> | curated 32 | Greenhouse board tokens — the slug in the careers URL, e.g. stripe. A company not hosted on Greenhouse simply returns nothing. |
leverCompanies | array<string> | curated 6 | Lever board tokens, e.g. palantir. |
ashbyCompanies | array<string> | curated 18 | Ashby board tokens, e.g. ramp. |
parseSalary | boolean | true | Parse pay from text when the board publishes no structured figure. |
enforceAnnualSalary | boolean | false | Convert every salary to its annual equivalent. |
computeAnalytics | boolean | true | Write the RUN_SUMMARY roll-up. |
deduplicate | boolean | true | Drop duplicates by dedupKey. |
deduplicateKeyStore | string | – | Named key-value store that keeps seen keys between runs. |
monitoringMode | boolean | false | Emit only postings not seen in a previous run (needs deduplicateKeyStore). |
maxConcurrency | integer | 5 | Concurrency for detail fetches and employer boards (1–20). |
maxChallengeRetries | integer | 3 | Retries with a fresh proxy session on 403/429/5xx/timeout. |
proxy | object | Residential US | Proxy for Indeed and LinkedIn. If this group keeps failing, later retries fall back to a datacenter session automatically. Glassdoor and ZipRecruiter need the Apify Unblocker group and use it internally. Employer boards need no proxy. |
Example input
{"query": "backend engineer","location": "remote","boards": ["indeed", "linkedin", "greenhouse", "ashby"],"maxItemsPerBoard": 25,"enforceAnnualSalary": true,"deduplicate": true}
Output
One flat record per posting. Below is a real record from a run against the ashby board, trimmed only by shortening the description.
{"board": "ashby","jobId": "ash-ramp-7bfa613e-151c-469b-9973-c89ee3d14838","title": "Backend Engineer, Ops Engineering","company": "Ramp","location": { "text": "New York, NY (HQ)", "city": "New York City", "state": "NY", "country": "US" },"remote": true,"salary": { "source": "structured", "min": 168000, "max": 284900, "currency": "USD", "period": "yearly" },"description": "About Ramp — Ramp is building the smart infrastructure for finance teams …","url": "https://jobs.ashbyhq.com/ramp/7bfa613e-151c-469b-9973-c89ee3d14838","applyUrl": "https://jobs.ashbyhq.com/ramp/7bfa613e-151c-469b-9973-c89ee3d14838/application","postedDate": "2026-03-04","seniority": "mid","seniorityAll": ["mid"],"jobType": "fulltime","department": "Engineering","emails": null,"dedupKey": "e1b782aa46f97b7d08c71542c7139f3580447532","matchedQuery": "backend engineer","scrapedAt": "2026-09-10T06:31:44.327Z"}
Field reference — board, jobId, title, company, location{text,city,state,country}, remote, salary{min,max,currency,period,source}, description, url, applyUrl, postedDate, seniority, seniorityAll[], jobType, department, industry, emails[], dedupKey, companyLogo, companyUrl, companyRating, companyReviewsCount, companyNumEmployees, companyRevenue, companyDescription, companyAddresses, jobFunction, jobLevel, listingType, matchedQuery, scrapedAt.
Country codes are normalized to ISO-2, so GB from one board and United Kingdom from another end up the same.
Pricing
You pay for postings, not for runtime. The full price list is two entries:
| Event | When it is charged |
|---|---|
job-listing | One posting written to your dataset. |
apify-actor-start | Once when a run starts (Apify charges one per GB of memory). |
Duplicates dropped by the deduplicator, postings removed by your filters, and boards that were skipped are not charged.
Cap a run's cost with maxItemsPerBoard.
Use cases
- Sourcing — one search across several boards, deduplicated, in a single dataset.
- Pay benchmarking —
salarywithenforceAnnualSalarygives comparable annual figures across boards and currencies. - Job-market tracking — schedule a daily run with
deduplicateKeyStoreandmonitoringModeto receive only new postings. - Filling a jobs board — employer ATS boards give clean, structured, employer-posted openings.
Limitations
- Glassdoor cannot be filtered by location. Glassdoor returns HTTP 403 for its own location lookup, so a location-specific Glassdoor search is not possible. Run without
locationto include Glassdoor, or use the other boards for location searches. The board is skipped with the reason in the log — never quietly answered with the wrong place. - Glassdoor descriptions are snippets by default (typically ~150 characters).
glassdoorFullDescriptionfetches the full text at one extra request per posting. - ZipRecruiter covers the United States and Canada only.
- Google Jobs does not currently work. It is left in the board list because the code is there and Google's guard may lift, but expect it to be skipped.
- Employer boards depend on which companies are in scope. The curated sets cover 56 boards; a company not hosted on that platform returns nothing. Pass your own tokens to target specific employers.
- A skipped board never fails the run. It is recorded in
RUN_SUMMARY.blockedand the run completes with what the other boards returned. The run fails loudly only when every board on every query was blocked, so an outage is never reported as an empty result. - Salary is
nullwhen nothing trustworthy was found. The parser would rather return nothing than turn a company's revenue into a wage.
FAQ
Do I need a login or cookies? No. Every board is read from its public, no-auth endpoint.
Which boards need a proxy? Indeed and LinkedIn use your proxy setting (residential recommended). Glassdoor and ZipRecruiter need the Apify Unblocker group. Employer boards need no proxy at all.
How does deduplication work? Each posting gets a dedupKey from company + title + city, normalized so the same job posted to two boards produces one key. Within a run duplicates are dropped; set deduplicateKeyStore to carry keys across scheduled runs and add monitoringMode to emit only new postings.
Can I search several roles at once? Yes — queries takes up to 5, results are merged and deduped, and each row carries the matchedQuery that found it.
How do I target specific companies? Pass their board tokens in greenhouseCompanies, leverCompanies or ashbyCompanies — the slug from the careers URL.
Why is salary sometimes empty? The posting published no pay and none could be read from its text with confidence.
Legal
Public data only — no login, no cookie wall bypassed, no personal accounts touched. Greenhouse, Lever and Ashby boards are the employers' own public career APIs. You remain responsible for complying with each board's terms and with applicable law; any personal data is limited to what employers publish in their own postings.