Glassdoor Jobs Scraper avatar

Glassdoor Jobs Scraper

Pricing

from $0.03 / 1,000 jobs

Go to Apify Store
Glassdoor Jobs Scraper

Glassdoor Jobs Scraper

Scrape Glassdoor jobs in 21 countries by keyword, location, company or URL, beyond the ~900-job limit: full description, salary range, company rating, size, industry, CEO, skills. Export to JSON, CSV or Excel.

Pricing

from $0.03 / 1,000 jobs

Rating

0.0

(0)

Developer

Nice Dev

Nice Dev

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

15 hours ago

Last modified

Share

💼 What is Glassdoor Jobs Scraper?

Glassdoor Jobs Scraper extracts job postings from Glassdoor in 21 countries: title, full description, salary range, location with GPS, job type, skills, experience and the employer's profile (website, size, revenue, sector, CEO, ratings by theme), for any keyword, location, company or search URL. It works as a Glassdoor API alternative: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type a keyword (software engineer) and a location, or paste any Glassdoor search URL, click Start, and download the jobs in JSON, CSV or Excel. Pick several countries, keywords and locations in one run, filter on the job type, level, salary, rating, company size and date, or tick Only new jobs to monitor a market. No login, nothing to set up, and it is fast: about 30 jobs with their full details in 6 seconds.

📋 What data can you extract from Glassdoor?

One item per job, 122 fields:

CategoryWhat you get
🏷️ Jobtitle, Glassdoor link, job id, Glassdoor's standard title, occupation and job function — Lead Software Engineer
🏢 Companyname, Glassdoor pages (overview, reviews, salaries, jobs, benefits), website, logo, size, revenue, type, founding year, headquarters, sector and industry, CEO, stock symbol, competitors — Palo Alto Networks
⭐ Ratingsoverall rating and ratings by theme (work-life balance, pay, culture, career, management, diversity), CEO approval, would recommend, business outlook, awards, numbers of reviews, salaries and interviews — 3.8 out of 5
📍 Locationplace as shown, city, region, country, latitude and longitude, Glassdoor place id — New York, NY
💰 Salarylow, middle and high of the pay range, period, currency, whether the employer gave it or Glassdoor estimated it, and the text Glassdoor shows — $156,400 - $253,000 a year
🧭 Work typefull-time, part-time, contract…, remote / hybrid / on-site, skills, education, years of experience — Full-time
📝 Descriptionfull text, HTML or Markdown of the job, and the short excerpt of the search card
🕒 Datesday the job was posted, its age in days, expired or not — what the date filters read
🔗 Applythe apply link, Easy Apply or not, sponsored (paid) job or not, who posted it, where Glassdoor got it
📞 Contacts (option)e-mails and phone numbers the employer wrote in the job text, contact e-mails and social profiles (LinkedIn, X, Facebook, Instagram, YouTube, TikTok) of the employer's website
📊 Market pay (option)Glassdoor's market pay for the job's role and city: low, median, high, how many salaries it is based on
🏭 Company rows (option)one row per employer: profile, open jobs now, jobs of this run, change since the previous run

Every field, with an example, is listed in the Output section below.

Fields marked detail in the Output tab are filled when Full job details is on (default). Turn it off for a search-card-only scrape that is about twice as fast.

✅ Why use Glassdoor Jobs Scraper?

  • 🌍 21 Glassdoor countries in one run: several countries × several keywords × several locations, each search with its own cap.
  • 🧩 Rich rows: the full description, the exact posting day, the pay range, the GPS location, the skills and the employer's profile and ratings in every job.
  • 🎯 Filters applied by Glassdoor: job type, level, salary, rating, company size, sector, job function, date, radius — fewer pages to read, nothing to pay for the jobs left out.
  • 🔁 Nothing twice: a job found by several searches is saved — and charged — once.
  • 🔔 Monitoring built in: tick Only new jobs, schedule the Actor, and each run returns (and charges) only what it has never delivered before.
  • 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.

🚀 How to scrape Glassdoor

  1. Create a free Apify account.
  2. Open Glassdoor Jobs Scraper, type a Search keyword (e.g. software engineer) and a Location (e.g. New York, NY), and pick the Country site.
  3. Or paste your own Glassdoor URLs into Start URLs: any search results page (keyword, place and filters set on the site are kept), the job page of a company, or single jobs; or give Job IDs.
  4. Set Max jobs (100 by default, 0 = no limit) — and Max jobs per search when you run several searches — then click Start.
  5. Download the dataset in JSON, CSV, Excel or via API.

💰 How much does it cost to scrape Glassdoor?

This Actor uses pay per event pricing: a price per 1,000 jobs saved plus a small fee per run start — the amounts are on the Pricing tab of this page. Filters Glassdoor does not offer are applied by the Actor on every job it reads: a job you keep costs its normal price, a job a filter drops costs a filter fee (filter-check) never higher than a job — filtering never costs more than taking everything. Filters applied by Glassdoor itself (job type, level, salary, rating, company size, sector, job function, date, radius) cost nothing for the jobs left out. The options marked extra charge in the form (contacts, employer e-mail, company rows, market pay) are off by default and charged only for what they find. Platform usage (compute, proxy) is included in the price.

⚙️ Input

{
"query": "software engineer",
"location": "New York, NY",
"country": "US",
"maxItems": 200
}

Several countries and keywords, only recent full-time jobs paying at least 40,000 a year, only the ones not delivered before:

{
"searchQueries": ["nurse", "teacher"],
"countries": ["GB", "IE"],
"jobTypes": ["fulltime"],
"minSalary": 40000,
"datePosted": "7d",
"maxItemsPerQuery": 50,
"onlyNew": true,
"stateKey": "nurses-uk"
}

Or with your own URLs and job ids:

{
"startUrls": [
{ "url": "https://www.glassdoor.com/Job/new-york-ny-software-engineer-jobs-SRCH_IL.0,11_IC1132348_KO12,29.htm" },
{ "url": "https://www.glassdoor.com/job-listing/j.htm?jl=1009876543210" }
],
"jobIds": ["1009876543211"],
"maxItems": 500
}
FieldNotes
query, searchQueriesKeyword as typed on Glassdoor (software engineer, nurse); searchQueries adds more keywords (one search each). Empty = every job of the location. Ignored when startUrls is set.
location, locationsCity, state, region or country (New York, NY, London, Bavaria); a place Glassdoor does not know stops the run with its candidates, never a search everywhere (not checked on the American site with remoteOnly, which does not use the location). locations adds more places. Every keyword is searched in every location (max 500 searches per run). Empty = the whole country site.
country, countriesThe Glassdoor country site to search (US, GB, FR, DE, JP… 21 countries); countries lists more: with country left on US, only the countries of the list are searched (put US in the list to include it), another country is added to them. Every keyword × location is searched on each (max 500 searches per run). A country chosen with no keyword and no location is refused: give at least one of them.
startUrlsGlassdoor URLs of any country site: search results pages, as the site writes them with the keyword in the path or as parameters (https://www.glassdoor.com/Job/jobs.htm?sc.keyword=engineer&locT=C&locId=1132348) — keyword, place and filters kept, pagination automatic —, the jobs page of a company (https://www.glassdoor.com/Jobs/Google-Jobs-E9079.htm) or single jobs (https://www.glassdoor.com/job-listing/j.htm?jl=1009876543210). Any other address is refused.
companiesAll the open jobs of these employers: company names (Google), Glassdoor company pages (https://www.glassdoor.com/Overview/Working-at-Google-EI_IE9079.11,17.htm, the Jobs and Reviews pages too) or employer ids (9079). A name is matched to the exact Glassdoor employer, never to a look-alike: when none matches, the log lists the candidates and that company is skipped (never a search without the employer). Searched on each country site of the run; combined with the keywords and locations when they are filled; ignored when startUrls is set.
jobIdsJob ids to read directly (1009876543210) or job links with jl=, on top of the keyword and location searches (empty them to read only these jobs). Expired jobs are returned too, flagged as expired. Up to 10,000.
maxItems, maxItemsPerQueryStop after this many jobs for the whole run, and for each search (0 = unlimited).
splitLargeSearchesGlassdoor shows about 900 jobs per search, whatever total it announces. When a search has more, the Actor splits it with Glassdoor's own filters (city, sector, job function, company size, job type, seniority, employer) and reads each part: nearly all of a large search instead of the first 900. A job found in two parts is delivered once. The log and the COVERAGE record of the key-value store give, per search, the jobs announced against the jobs read, the parts it was cut into, and what is not covered with the reason. Off = the first 900 only. When a search is split, its own first ~900 jobs are read too (Glassdoor lists jobs that no part holds): the rank column is the position of a job the search itself found, and empty for a job a part found (a position inside a part says nothing of the search).
extractDetails, descriptionFormatFull job details: description, exact posting day, GPS, apply link, skills, education, experience and the employer's profile (default on, same price). descriptionFormat keeps text_html, all (text, HTML and Markdown), text, html, markdown (Markdown only) or none.
extractContacts, companyEmails, companySummary, salaryBenchmarkExtra-charge options, all off by default (the events are on the Pricing tab). E-mails and phone numbers the employer wrote in the job text (the emails and phones columns; a job without any is not charged); the contact e-mails of the employer's own website (and the social profiles it links to, in the same visit), once per company; one extra row per employer of the jobs delivered, written at the end of the run and not counted in Max jobs; Glassdoor's market pay for the job's role and city, read once per role and place. All four need extractDetails. Charged only where something is found: a job with at least one e-mail from its text, one e-mail from its employer's website or a market pay, and each company row written.
datePostedOnly jobs posted in this period: 24h, 3d, 7d, 14d, 30d, any.
jobTypesKeep jobs of ANY of these types: fulltime, parttime, contract, temporary, permanent.
experienceLevelsKeep jobs of ANY of these levels, as tagged by Glassdoor: internship, entry, midsenior, director, executive.
remoteOnlyOnly the jobs Glassdoor tags as work from home / remote. On the American site Glassdoor has no such filter: the search is sent to its "Remote" place (the whole country) and the location you type is not used there (the log says so). A pasted search page keeps its own place, and only its jobs tagged remote are kept. Outside American keyword searches the tag is on the full job details: extractDetails must stay on.
applyMethodany, easyApply (apply on Glassdoor) or external (the employer's or ATS page).
minSalary, maxSalaryYearly pay bounds in the currency of the country site, Glassdoor's estimates included (0 = none).
minRatingOnly jobs of employers rated at least this on Glassdoor (out of 5, 4); unrated employers are dropped too (0 = none).
employerSizesKeep jobs of employers of ANY of these sizes, in the five classes Glassdoor filters by (number of employees): 1 (1-200), 2 (201-500), 3 (501-1,000), 4 (1,001-5,000), 5 (5,001+).
industriesSectors of the employer: Glassdoor sector names (Information Technology, Healthcare) or their ids (10013).
jobFunctionsKeep jobs of ANY of these Glassdoor job functions (the 23 ids from 1001 to 1023, listed in the form with their names).
radiusDistance around the location (25; default = Glassdoor's, miles on the US site, kilometres on most others).
sortByrelevance or date (newest first).
urlParamsAny other Glassdoor search filter as name=value (cityId=1132348), sent with every search.
postedAfter, postedBeforeDay the job was posted: 2026-09-01 (the whole day is included), or a period before now (7 days, 2 weeks, 1 month, 24 hours).
excludeKeywords, matchTitleDrop the jobs whose title contains one of these words (case and accents ignored); matchTitle keeps only the jobs whose title holds the search keyword: off, loose (every word) or exact.
excludeCompanies, excludeSponsored, excludeStaffingAgencies, onlyWithSalary, onlyEmployerSalaryDrop the jobs of employers whose name contains one of these words (Randstad), the jobs Glassdoor shows as paid ads, the jobs of staffing and recruiting agencies (employer in Glassdoor's Human Resources & Staffing sector, needs extractDetails), the jobs that show no pay, the jobs whose pay is only Glassdoor's estimate.
latitude, longitude, radiusKmKeep only the jobs within this distance in kilometres of a point (40.7, -74), as the crow flies (each job carries its distance); needs extractDetails (the GPS of the job). A job with no GPS position (a remote job) is dropped. Not the Glassdoor radius, which is applied by the site around the location.
resumeKeywords, minMatchScoreSkills of a profile (Python, AWS): each job gets a match score from 0 to 100 (the share of your skills found as whole words in its title, skills and description), the skills found and the missing ones; minMatchScore drops the jobs below it.
onlyNew, stateKey, resetStateMonitoring: only the jobs never delivered under this memory key (nyc-engineers); resetState forgets the memory.
excludeJobIdsJob ids you already have (1009876543210): never saved nor charged.
AdvancedproxyConfiguration (leave the default: the proxy is included in the price), maxConcurrency, maxRequestsPerMinute, minRequestIntervalMs, maxRequestRetries, debugLog.

📦 Output

A real item (local run of 07/10), shortened: the long texts are cut, the empty fields left out.

{
"recordType": "job",
"id": "1010221611074",
"url": "https://www.glassdoor.com/job-listing/sr-forward-deployed-engineer-customer-engineering-prisma-airs-palo-alto-networks-JV_IC1132348_KO0,61_KE62,80.htm?jl=1010221611074",
"title": "Sr. Forward Deployed Engineer (Customer Engineering, Prisma AIRS)",
"normalizedTitle": "programmer analyst",
"occupation": "programmer analyst",
"occupationId": 102479,
"jobFunction": "Engineering",
"jobFunctionId": "1007",
"companyName": "Palo Alto Networks",
"companyShortName": "Palo Alto Networks",
"companyId": "115142",
"companyUrl": "https://www.glassdoor.com/Overview/Working-at-Palo-Alto-Networks-EI_IE115142.11,29.htm",
"companyReviewsUrl": "https://www.glassdoor.com/Reviews/Palo-Alto-Networks-Reviews-E115142.htm",
"companySalariesUrl": "https://www.glassdoor.com/Salary/Palo-Alto-Networks-Salaries-E115142.htm",
"companyJobsUrl": "https://www.glassdoor.com/Jobs/Palo-Alto-Networks-Jobs-E115142.htm",
"companyBenefitsUrl": "https://www.glassdoor.com/Benefits/Palo-Alto-Networks-Benefits-E115142.htm",
"companyLogo": "https://media.glassdoor.com/sql/115142/palo-alto-networks-squareLogo-1678388914975.png",
"companyWebsite": "https://jobs.paloaltonetworks.com",
"companySize": "10000+ Employees",
"companySizeCategory": "GIANT",
"companyRevenue": "$5 to $10 billion (USD)",
"companyType": "Company - Public",
"companyFounded": 2005,
"companyHeadquarters": "Santa Clara, CA",
"companyIndustry": "Enterprise Software & Network Solutions",
"companyIndustryId": 200061,
"companySector": "Information Technology",
"companySectorId": 10013,
"companyCeo": "Nikesh Arora",
"companyCeoTitle": "Chief Executive Officer",
"companyStock": "PANW",
"companyCeoPhoto": "https://media.glassdoor.com/people/sql/115142/palo-alto-networks-ceo1530556138341.png",
"companyActiveStatus": "ACTIVE",
"companyRating": 3.8,
"companyRatingWorkLifeBalance": 3.4,
"companyRatingCompensationBenefits": 4.1,
"companyRatingCulture": 3.6,
"companyRatingCareerOpportunities": 3.7,
"companyRatingSeniorManagement": 3.4,
"companyRatingDiversityInclusion": 3.9,
"companyCeoApproval": 0.83,
"companyCeoApprovalCount": 1596,
"companyRecommendToFriend": 0.69,
"companyBusinessOutlook": 0.78,
"companyAwards": [
{
"name": "Best Places to Work",
"year": 2026
},
{
"name": "Best Places to Work Tech & AI",
"year": 2026
}
],
"companyDescription": "Careers at the forefront of cybersecurity: Our vision is a world where each day is safer and more secure than…",
"companyMission": "Being the cybersecurity partner of choice, protecting our digital way of life.",
"companyReviewCount": 3306,
"companySalaryCount": 9872,
"companyInterviewCount": 1071,
"companyBenefitCount": 1704,
"companyPhotoCount": 94,
"companyJobCount": 1308,
"companyCompetitors": [
"Check Point Software Technologies",
"Fortinet",
"CrowdStrike"
],
"jobRating": 3.8,
"location": "New York, NY",
"city": "New York",
"region": "New York State",
"country": "United States",
"countryCode": "US",
"latitude": 40.71417,
"longitude": -74.00639,
"locationId": "1132348",
"locationType": "city",
"jobTypes": [
"Full-time"
],
"skills": [
"Azure",
"Go",
"Software troubleshooting",
"Enterprise software"
],
"education": [
"Master's degree",
"Bachelor's degree"
],
"yearsOfExperience": 7,
"attributes": [
{
"key": "22JPW",
"label": "AI models"
},
{
"key": "2GB9E",
"label": "Containerization systems"
},
{
"key": "2NVYY",
"label": "Performance monitoring"
}
],
"salaryMin": 156400,
"salaryMedian": 204700,
"salaryMax": 253000,
"salaryPeriod": "year",
"salaryCurrency": "USD",
"salarySource": "employer",
"salaryText": "$156,400 - $253,000 a year",
"descriptionText": "Santa Clara, California, United States of America New York, New York, United States of America Plano, Texas, United States of America Product Engineering Ref…",
"descriptionHtml": "<div><div>Santa Clara, California, United States of America\n<br>\nNew York, New York, United States of America\n<br>\nPlano…",
"descriptionSnippet": "Education & Experience: Bachelor's or Master's degree in Computer Science, AI, Machine Learning, or a related field (or equivalent practical experience), or 7+…",
"publishedAt": "2026-10-05",
"ageInDays": 63,
"isExpired": false,
"isEasyApply": false,
"isSponsored": false,
"advertiserType": "GENERAL",
"applyUrl": "https://www.glassdoor.com/partner/jobListing.htm?pos=101&jobListingId=1010221611074&…",
"sourceName": "Indeed Job Search Platform",
"emails": [],
"phones": [],
"companyEmails": [],
"companySocialLinks": [],
"matchedKeywords": [],
"missingKeywords": [],
"searchQuery": "software engineer",
"searchLocation": "New York, NY",
"searchUrl": "https://www.glassdoor.com/Job/new-york-ny-software-engineer-jobs-SRCH_IL.0,11_IC1132348_KO12,29.htm",
"rank": 29,
"detailStatus": "complete",
"scrapedAt": "2026-10-07T13:56:29.563Z"
}

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. A field Glassdoor does not give for a job is null (or an empty list), never missing.

All 122 fields

FieldsWhat you get
recordType, id, urljob (or company for a company row), the Glassdoor job id (the jl= value), the Glassdoor link of the job on its country site
title, normalizedTitle, occupation, occupationId, jobFunction, jobFunctionIdthe title as posted, Glassdoor's standard title and occupation, its job function: Lead Software Engineer, software engineer, Engineering
companyName, companyShortName, companyId, companyLogo, companyWebsite, companyActiveStatusthe employer as the job shows it (the name of the ad and no id when the employer has no Glassdoor profile), its Glassdoor id, logo and own website, and the ACTIVE or INACTIVE flag Glassdoor gives its profile, as it is (INACTIVE also appears on employers that are hiring)
companyUrl, companyReviewsUrl, companySalariesUrl, companyJobsUrl, companyBenefitsUrlthe Glassdoor pages of the employer: overview, reviews, salaries, jobs, benefits
companySize, companySizeCategory, companyRevenue, companyType, companyFounded, companyHeadquartersthe profile: 201 to 500 Employees, MEDIUM, $25 to $100 million (USD), Company - Private, 1985, Iselin, NJ
companyIndustry, companyIndustryId, companySector, companySectorIdGlassdoor's industry and sector of the employer and their ids (10013 is the sector filter)
companyCeo, companyCeoTitle, companyCeoPhoto, companyStock, companyDescription, companyMission, companyCompetitorsthe CEO, the stock symbol, the description and mission of the profile, the competitors it lists
companyRating, companyRatingWorkLifeBalance, companyRatingCompensationBenefits, companyRatingCulture, companyRatingCareerOpportunities, companyRatingSeniorManagement, companyRatingDiversityInclusion, jobRatingGlassdoor's ratings out of 5, overall and by theme, and the rating shown on the job itself
companyCeoApproval, companyCeoApprovalCount, companyRecommendToFriend, companyBusinessOutlook, companyAwardsCEO approval, would recommend and business outlook (0 to 1), the number of CEO ratings, the awards with their year
companyReviewCount, companySalaryCount, companyInterviewCount, companyBenefitCount, companyPhotoCount, companyJobCounthow many reviews, salaries, interviews, benefit reviews and photos the employer has on Glassdoor, and its open jobs worldwide; companyReviewCount is the figure of Glassdoor's API, a few percent above the number shown on the employer's Glassdoor page
location, city, region, postalCode, streetAddress, country, countryCodeNew York, NY, New York, New York State, the postal code and street address when Glassdoor gives them, United States, the country site the job was found on (US)
latitude, longitude, distanceKm, locationId, locationTypethe coordinates (empty when Glassdoor only places the job in its country, as for a remote job), the distance from the point of the input, Glassdoor's place id and kind (city, state, country)
isRemote, remoteType, jobTypes, skills, education, yearsOfExperience, attributesremote or not, remote, hybrid or onsite, Full-time, the skills, the education and the years of experience Glassdoor tagged, and every tag as {key, label}
salaryMin, salaryMedian, salaryMax, salaryPeriod, salaryCurrency, salarySource, salaryTextthe pay range (10th, 50th and 90th percentile when Glassdoor estimates it), year, USD, employer or estimate, $156,400 - $253,000 a year (an hourly pay keeps its cents: $37.86 - $54.00 an hour)
marketPayMin, marketPayMedian, marketPayMax, marketPayCurrency, marketPaySamples, marketPayP25, marketPayP75, marketBasePayMedian, marketAdditionalPayMedian, marketPayConfidence, marketPayRole, marketPayPlacethe market pay of the role and city, yearly, with the number of salaries behind it, its confidence and what it is computed for (extra-charge option)
descriptionText, descriptionHtml, descriptionMarkdown, descriptionSnippetthe full description as text, HTML and Markdown, and the excerpt of the search card
publishedAt, ageInDays, isExpiredthe day the job was posted (2026-10-05), its age shown by Glassdoor, whether it is expired
isEasyApply, isSponsored, advertiserType, applyUrl, sourceNameapply on Glassdoor or not, paid ad or not, who posted it (GENERAL = the employer), the apply link, where Glassdoor got the job
emails, phones, companyEmails, companySocialLinksthe e-mails and phone numbers written in the description, the contact e-mails of the employer's website and the social profiles it links to (extra-charge options)
matchScore, matchedKeywords, missingKeywordsthe share of your skills found in the job (0 to 100), the skills found, the skills missing
openJobs, jobsInRun, openJobsChangecompany rows only: open jobs on the country site, jobs of the run, change since the previous run with the same Memory key (empty the first time)
searchQuery, searchLocation, searchUrl, rank, detailStatus, scrapedAtthe keyword, location and Glassdoor search that found the job, its position in it, complete, partial or none (how much of the details was read), the ISO time of the extraction

💡 Tips

How to get more results

Glassdoor shows about 900 jobs per search whatever total it announces. Leave Get past Glassdoor's search limit (splitLargeSearches) on: a larger search is cut with Glassdoor's own filters and each part is read. Set maxItems to 0 for no cap. For monitoring, schedule the Actor daily, sort by date and tick onlyNew.

How to reduce costs

The price is per job, so the levers are maxItems, maxItemsPerQuery, the filters Glassdoor applies itself (nothing is charged for the jobs left out), the post-filters (a job dropped costs only the filter fee) and onlyNew for recurring runs (you never pay twice for the same job). Turning extractDetails off makes runs about twice as fast and does not change the price.

Several searches in one run

Fill searchQueries, locations and / or countries: the Actor runs one search per country × keyword × location (3 keywords × 4 cities = 12 searches, up to 500 per run). The single query and location fields still work and are added to the lists. A job found by several searches is saved — and charged — once. Set maxItemsPerQuery to give every search its own cap: without it the first searches can use up the whole maxItems budget. You can also paste several search URLs into startUrls: each one is a search of its own, with the same cap. A filter with several values (jobTypes, employerSizes, jobFunctions) that Glassdoor takes one at a time runs one search per value, without duplicates.

Monitoring: only the new jobs

Tick Only new jobs (onlyNew) and schedule the Actor. The first run returns everything; each later run skips the jobs already delivered: they are not saved, not charged, and their details are not even read. The memory lives in a named key-value store of your account (glassdoor-jobs-scraper-seen, up to 150,000 jobs per key) and is only updated with jobs that really reached the dataset, so a failed run never hides anything. Give each schedule its own stateKey (two schedules sharing a key would hide each other's jobs), and tick resetState once to start over. Searches are then sorted by newest, and a search stops once it meets a long run of jobs you already have (paid ads pinned at the top are not counted). With a cap, the jobs a previous run left out because of it count as jobs you already have (see Known limitations).

Filter by posting date

postedAfter and postedBefore take a date (2026-09-01, the whole day is included) or a period before now (7 days, 2 weeks, 1 month; via the API also 24 hours or a full ISO date-time). The filter reads publishedAt, the day Glassdoor posted the job — or posted it again: such a job passes 7 days with an ageInDays of 90, while datePosted (Glassdoor's own filter) counts from its first posting; when the details are off, Glassdoor's age in whole days stands for it. Filtered-out jobs are not saved and do not count in maxItems (each job dropped costs the filter fee, see Pricing); the run summary tells how many were filtered. datePosted asks Glassdoor itself and costs nothing for the jobs left out.

Which Glassdoor country site

Each country site has its own jobs, currency and language of the labels. A job is read on the site of its country: its link, countryCode and pay currency are those of that site. A run with no source at all (no keyword, location, start URL, job id or company) reads a small example instead — "software engineer" in New York, NY, 20 jobs at most — and the log says so. A country site chosen with no keyword and no location is refused, and so is Only new jobs without a source.

🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run. It returns one item per Glassdoor job. Actor id: nice_dev/glassdoor-jobs-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/glassdoor-jobs-scraper.

Smallest input, for a cheap first call:

{
"query": "software engineer",
"location": "New York, NY",
"maxItems": 10
}

Key output fields: title, companyName, location, salaryMin, salaryMax, salaryPeriod, publishedAt, companyRating and descriptionText (with extractDetails).

Cost: the per-job price plus the per-run-start fee, see the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.

❓ FAQ

The Actor only reads what Glassdoor shows publicly to any anonymous visitor. It logs in to nothing. Results can contain personal data (the name of a CEO, a recruiter's e-mail written in a job text), which is protected by GDPR: do not store it without a legitimate reason. You are responsible for using the data in compliance with Glassdoor's Terms of Use and applicable law. This Actor is not affiliated with Glassdoor.

Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting. Your own proxies (proxyUrls) are used as given. A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

Apify free plan: the included proxy is for paying Apify plans only. On the free plan, add your own proxy URLs in Proxy configuration; without them the run stops at once with a message saying so.

Where do the employer e-mail addresses come from?

With the employer e-mail option on, the Actor reads the pages each employer publishes on its own website (the one Glassdoor shows: home page, contact page, legal notice) and returns the business contact addresses shown there, and the social profiles it links to — what any visitor sees. It does not log in, guess addresses, read contact forms or bypass any protection. Some of these addresses are personal data under GDPR (for example firstname.lastname@company.com): you are responsible for having a lawful basis before using them, for informing the people concerned and for honouring opt-outs. Rules for B2B e-mail prospecting differ by country (opt-out in some, prior consent in others).

Is the data safe to open in Excel or to show on a web page?

Titles and descriptions are the employers' own words, copied as they are. A text can begin with -, +, = or @ (a phone number, a title such as -20% bonus): Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. descriptionHtml is the employer's HTML as Glassdoor gives it and the Actor does not sanitize it: on a web page, escape every field like any text written by a stranger.

Known limitations

  • Glassdoor serves about 900 jobs per search. With splitLargeSearches off, that is all a search gives.
  • Filters that are not in the input can still be used by pasting a filtered search URL into startUrls, or urlParams.
  • salaryMin and salaryMax are Glassdoor's estimate unless salarySource says employer.
  • onlyNew remembers job ids, not their content: a job whose pay changed is not returned again.
  • onlyNew with a cap (maxItems or maxItemsPerQuery): the next runs return the jobs published since the previous run. A job the cap left out that was published before the day of the previous run is not returned; one published that day or later is. On a search above ~900 jobs only the first run cuts the search into parts; the next runs read it as one list, newest first, among the ~900 newest Glassdoor shows. Without a cap, nothing is skipped: every job you do not have yet is returned.
  • The market pay (marketPay*) is Glassdoor's figure for the job's normalized title in its city, or in its country when the city has none; every figure is yearly (an hourly or monthly figure is turned into a year). A job whose role and place Glassdoor has no salary for has none, and is not charged.
  • The employer e-mails are the ones its website publishes: a site that is a link shortener is followed to the company site, a social network page or a site that shows no address gives none (the job is not charged), and the employer's website is read once per run.
  • The company rows come after the jobs, at the end of the run: a run that is aborted does not write them. openJobsChange compares with the previous run of the same Memory key; the first run has none.
  • Two runs sharing the same stateKey at the same time may both return the same new job.
  • Glassdoor sorts a search by its own idea of the date: a job published again can show an old age and a recent publishedAt.

A run that reaches its timeout stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with onlyNew, remembered, and the run ends Succeeded with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

A run the platform stops without warning (out of memory)

  • Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the jobs already saved are skipped: none is delivered or charged twice, and maxItems still counts them.
  • With onlyNew, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the jobs it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the jobs of its last 2 seconds once more.

Something doesn't work?

The last line of the log counts the jobs saved, filtered out and no longer on Glassdoor (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed jobs are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause (a search URL that does not exist says so, instead of "run it again").

If Glassdoor changes its pages, you are told instead of paying for blank rows. A results page that counts jobs but gives none the Actor can read is an error (listed in FAILED_REQUESTS), never a quiet "No jobs found". If the first 20 jobs read all lack their title, posting day or — with extractDetails — description, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first jobs are charged. A job that postedAfter / postedBefore drops because it has no date at all counts among those 20. A run of fewer jobs (a scheduled onlyNew run that finds a few new ones, a small Max jobs) is checked at its end, from 5 jobs: its jobs are already saved, and the run fails with the missing field instead of ending green.

🛟 Support

Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which URLs failed and why.