ATS Jobs Scraper - Workday, Greenhouse, Lever, Ashby & More
Pricing
from $0.60 / 1,000 job postings
ATS Jobs Scraper - Workday, Greenhouse, Lever, Ashby & More
[💵 $1.00 / 1K] Scrape open jobs across 7 ATS platforms - Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Personio - in one unified schema. Auto-detects each company's ATS. Monitoring mode returns only new jobs since your last run.
Pricing
from $0.60 / 1,000 job postings
Rating
0.0
(0)
Developer
WebData Labs
Maintained by CommunityActor stats
1
Bookmarked
17
Total users
12
Monthly active users
3 days ago
Last modified
Categories
Share
ATS Jobs Scraper - Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Personio
Scrape open jobs from company ATS job boards in one run, one unified schema - not a re-sold job aggregator feed. Give it company names, board slugs, or career-page URLs; it detects which applicant tracking system each company uses and returns clean, normalized job rows. Turn on monitoring mode to get only the jobs posted since your last run.
Most ATS scrapers cover a single platform and hand back that platform's raw shape. This Actor reads the official public job-board APIs of Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, and Personio, auto-detects the ATS per company, and normalizes everything into one consistent schema with remote flags, departments, locations, and posting dates - ready for recruiting, sourcing, job-board aggregation, or B2B sales-signal workflows.
✅ What you get / ❌ what this isn't
| This Actor gives you | This Actor is not |
|---|---|
| Open jobs from 7 ATS platforms in one unified schema | Not a job board with login-gated or paid postings |
| Automatic ATS detection per company (or force it with a prefix) | Not a company-discovery tool (you provide the companies) |
| Company names, board slugs, and career-page URLs in one input list | Not a resume, candidate, or applicant scraper |
| Monitoring mode: only new jobs since your last run, per company | Not a stale aggregator index refreshed once a week |
| Per-company roll-up: which ATS, total roles, new roles, remote count, top departments | Not affiliated with any of the ATS vendors |
| 99% run success rate, read from official public ATS endpoints | Not a guarantee a company uses one of these 7 systems |
🔎 Why use this Actor
- One integration instead of seven. Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Recruitee, and Personio each expose a different JSON shape, different field names, and different date formats. You get one row shape across all of them.
- Automatic ATS detection. Pass
stripeand the Actor finds the board itself. Passlever:palantirwhen you want to skip detection and go straight to the source. - Monitoring mode nobody else in this niche has.
onlyNewJobsremembers what it has already returned per company and pushes just the delta, so a daily hiring watch costs a fraction of a cent per company. - Enrichment, not a raw dump. Every job carries a normalized remote flag, department, location, and posting date; every company carries a roll-up row (total roles, remote count, top departments, newest posting) you can read without touching the job rows.
- Nothing technical to configure. No proxy setting, no concurrency dial, no retry count. Transport is our problem, and it is tuned to stay inside the ATS providers' rate limits, which is exactly why the success rate is what it is.
- Input that accepts what you already have. Company names from a spreadsheet, board slugs from a scraper, career-page URLs from a CRM, mixed in one list in any order.
🗂️ Which ATS platforms are covered?
Every platform below is read from its own official public job-board endpoint. If you are searching for a scraper for one of these by name, this is it.
- Greenhouse jobs scraper -
job-boards.greenhouse.io/<company>,boards.greenhouse.io/<company> - Lever jobs scraper -
jobs.lever.co/<company> - Ashby jobs scraper -
jobs.ashbyhq.com/<company> - Workday jobs scraper -
<company>.wd1.myworkdayjobs.com, plus thewd2,wd3,wd5,wd10, andwd12tenant hosts - SmartRecruiters jobs scraper -
careers.smartrecruiters.com/<Company>,jobs.smartrecruiters.com/<Company> - Recruitee jobs scraper -
<company>.recruitee.com - Personio jobs scraper -
<company>.jobs.personio.de,<company>.jobs.personio.com
Together those seven cover most startup, scale-up, and enterprise hiring in the US and Europe: Greenhouse, Lever, and Ashby carry the venture-backed tech tier, Workday carries the Fortune 500, SmartRecruiters carries large European and global employers, and Recruitee and Personio carry the European mid-market.
Not supported yet, so you do not spend a run finding out
We would rather name these than hide behind "and more". The following applicant tracking systems are not covered today, either because their job feed needs a per-customer API key or because we have not validated their public endpoint yet: Workable, BambooHR, JazzHR, Teamtailor, Jobvite, iCIMS, Taleo, Breezy HR, Comeet, Pinpoint, Homerun, Rippling, Factorial, Join, and Zoho Recruit.
A company on one of those comes back as found: false with a note, rather than as a silent empty result. Open an issue with the platform you need and it goes on the list, ordered by how many people ask. For companies running a careers page not backed by any ATS, use Company Career Page Jobs API.
👥 Who it's for
Recruiters, sourcers, job-board builders, and B2B sales teams who need open roles from a specific list of employers rather than a keyword search across a public aggregator.
- Recruiters and sourcers tracking open roles across a target-company list.
- Job-board and aggregator builders who need normalized rows, not seven parsers.
- B2B sales and RevOps teams using hiring as an intent signal ("they are hiring 4 SDRs" is a buying signal).
- Talent-market researchers tracking hiring volume, remote share, and department mix over time.
- Data and AI teams building a jobs dataset for analysis or retrieval.
Concrete jobs to be done: build a weekly list of companies that just opened a role you place for; watch 50 competitors and get pinged when they start hiring in a new city; feed a normalized jobs table into a warehouse; enrich a hiring-company list with contact emails and hand it to sales.
📚 Example tasks
Ten ready-to-copy configurations, each running on the four input fields this Actor has today.
- Scrape all open jobs at a list of companies
- Daily new-jobs monitoring for a company watchlist
- Weekly hiring digest for a competitor set
- Track hiring at Y Combinator companies
- Full job descriptions for an ATS company list
- Quick headcount scan, 5 newest jobs per company
- Mixed input: company names and career-page URLs in one run
- Enrich hiring companies with contact emails
- Scrape Greenhouse jobs for a company
- Monitor a startup's open roles
⚙️ How to scrape ATS jobs
- Open the Actor on Apify and click Try for free.
- Fill the Companies field. Anything in this list works: a company name (
Y Combinator), a board slug (stripe), a forced ATS (lever:palantir), or a full career-page URL (https://adobe.wd5.myworkdayjobs.com/external_experienced). Mix them freely. - Optionally set Max jobs per company (default 200) to cap large employers.
- Optionally turn on Include job descriptions if you need the full ad body.
- Optionally turn on Only new jobs for scheduled monitoring, described in the next section.
- Click Start.
- Open the Job postings dataset view for the rows, or Company summaries for the per-company roll-up.
- Export to JSON, CSV, Excel, HTML, RSS, or XML, or pull the dataset through the Apify API.
There is no proxy setting, retry count, or concurrency dial to get wrong. Those are handled internally and deliberately not exposed.
🔁 Daily hiring monitoring - only jobs you have not seen before
This is the feature no other ATS scraper in the Apify Store has, and it is the reason most people keep this one on a schedule.
Set onlyNewJobs: true and schedule the Actor from Apify Console (Schedules, daily or weekly). What happens:
- The first run returns every current posting per company and writes a memory of the job IDs it has seen. It is a normal full run and is priced as one.
- Every run after that compares the board against that memory and pushes only postings that were not there before. A stable company on a daily schedule usually returns zero new rows, which costs almost nothing.
- Company summary rows stay complete even when the job rows are a delta:
totalJobs(what is open right now),newJobs(what this run found), andpreviouslySeenJobs(what was suppressed). You never lose the full picture by receiving the delta.
The memory lives in a named key-value store on your Apify account, ats-jobs-scraper-delta-state, one record per company. Delete the store, or a single record in it, to reset and treat the next run as a first run.
Why it matters to your bill: a daily watch over 50 companies without monitoring mode pushes tens of thousands of duplicate rows a month and you pay for every one. With onlyNewJobs you pay for the roughly 1 to 3% that are genuinely new. That is the difference between a scheduled job you keep and one you cancel after the first invoice.
Pair it with an Apify integration (Slack, email, webhook, Make, Zapier) and every new role at a watched company lands where your team already works.
📥 Input
{"companies": ["stripe","Y Combinator","recruitee:bunq","smartrecruiters:boschgroup","https://jobs.lever.co/palantir","https://adobe.wd5.myworkdayjobs.com/external_experienced"],"maxJobsPerCompany": 200,"onlyNewJobs": false,"includeDescription": false}
| Field | Type | Default | Description |
|---|---|---|---|
companies | array of strings | ["stripe"] | Company names, board slugs, ATS-prefixed slugs, or career-page URLs, mixed freely in one list. Duplicates are removed; up to 1000 companies per run. |
onlyNewJobs | boolean | false | Monitoring mode. Returns only postings not seen in previous runs on your account, per company. |
maxJobsPerCompany | integer | 200 | Cap on job rows collected per company, 1 to 2000. |
includeDescription | boolean | false | Adds descriptionHtml, the full HTML ad body, to each job row. Off by default to keep runs small and cheap. |
Accepted input aliases
Copied a JSON input from another ATS Actor's docs? Paste it as it is. companyUrls, startUrls, and queries are accepted as aliases of companies and merged into the same list, so competitor input does not fail validation here. startUrls also accepts the standard [{ "url": "..." }] shape.
{"startUrls": [{ "url": "https://job-boards.greenhouse.io/stripe" }],"companyUrls": ["https://jobs.ashbyhq.com/ramp"],"queries": ["Bosch Group"]}
How a company value is resolved
- A board slug (
stripe,ramp) is probed against Greenhouse, Lever, Ashby, Recruitee, Personio, SmartRecruiters, and finally Workday, and the first unambiguous board that answers wins. - A company name (
Y Combinator,Bosch Group Inc) is tried literally first, then normalized (lowercased, corporate suffix dropped, spaces removed) and tried again. Board slugs are case-sensitive in both directions, which is why the literal form is never skipped. - A prefixed value (
greenhouse:,lever:,ashby:,smartrecruiters:,recruitee:,personio:,workday:) skips detection entirely. Use it when you already know the ATS: it is faster and removes any chance of a wrong match. - A full URL is parsed for the board slug, including
myworkdayjobs.comcareer URLs, from which the tenant host, site name, and locale are all read. - Workday is the final auto-detection fallback because host and site discovery can cost up to fifteen probe requests per slug variant. Use
workday:adobeor, better, the careers URL when you know it: both are faster and more reliable.
📤 Output
Each run writes job rows and company summary rows to the dataset (plus an error row when a single company fails), and a run summary to the key-value store. The dataset ships with ready-made views: Job postings, Company summaries, and Errors.
{"recordType": "job","scrapedAt": "2026-07-30T18:04:11.882Z","company": "ramp","ats": "ashby","jobId": "4b4f9e11-0a4c-4b31-9a3f-0e0c6bb1a2f4","title": "Director, Performance Marketing","department": "Marketing","team": "Growth","location": "New York, NY (HQ)","isRemote": true,"workplaceType": "Remote","employmentType": "FullTime","url": "https://jobs.ashbyhq.com/ramp/4b4f9e11-0a4c-4b31-9a3f-0e0c6bb1a2f4","applyUrl": "https://jobs.ashbyhq.com/ramp/4b4f9e11-0a4c-4b31-9a3f-0e0c6bb1a2f4/application","postedAt": "2026-06-11T17:21:26.410+00:00","updatedAt": null}
Job row fields (recordType: "job")
| Field | Type | Description |
|---|---|---|
recordType | string | Always job for a posting row. |
scrapedAt | string | ISO timestamp of when the row was collected. |
company | string | The resolved board slug the posting was read from. |
ats | string | greenhouse, lever, ashby, workday, smartrecruiters, recruitee, or personio. |
jobId | string | The ATS's own posting identifier. Stable, and what monitoring mode deduplicates on. |
title | string | Job title as published. |
department | string | Department or category when the ATS provides one. |
team | string | Sub-team, function, or sub-company when provided. |
location | string | Primary location string, normalized across sources. |
isRemote | boolean | Remote flag, taken from the ATS's own field where it exists and inferred from the location string where it does not. |
workplaceType | string | remote, hybrid, or on_site where the ATS exposes it. |
employmentType | string | Full-time, part-time, contract, internship and so on, where published. |
url | string | Public posting URL. |
applyUrl | string | Direct application URL where the ATS separates it from the posting URL. |
postedAt | string | Posting date, normalized to ISO 8601. |
updatedAt | string | Last-updated date where the ATS exposes one. |
postedOnRaw | string | Workday only: its relative posting age (for example "Posted 3 Days Ago"), since its list endpoint publishes no absolute date. |
descriptionHtml | string | Full HTML ad body. Present only when includeDescription is on. |
Company summary fields (recordType: "company_summary")
| Field | Type | Description |
|---|---|---|
company | string | Resolved board slug. |
ats | string | Which ATS answered, or null when none did. |
found | boolean | Whether a supported board was located for this input. |
totalJobs | integer | Open roles seen on the board this run, before any delta filtering. |
hasMoreJobs | boolean | True when the board holds more roles than maxJobsPerCompany allowed. |
remoteJobs | integer | How many of those roles are remote. |
uniqueDepartments | integer | Distinct departments across the open roles. |
uniqueLocations | integer | Distinct locations across the open roles. |
topDepartments | array | Five most common departments, most frequent first. |
topLocations | array | Five most common locations, most frequent first. |
newestPostingDate | string | Most recent posting date on the board. |
newJobs | integer | Monitoring mode only: postings pushed this run. |
previouslySeenJobs | integer | Monitoring mode only: postings suppressed as already seen. |
firstDeltaRun | boolean | Monitoring mode only: true on the run that initialized the memory. |
note | string | Present when found is false, explaining what to check. |
Error rows and the run summary
A company that fails outright produces one recordType: "error" row (companyInput, errorType, errorMessage) and the run continues. One bad slug never fails the run or costs you the rest of the list. The key-value store record OUTPUT holds the run summary: companiesProcessed, companiesFound, companiesNotFound, companiesFailed, totalJobs, newJobs in monitoring mode, and the skipped list if you sent more than 1000 companies.
💵 How much does it cost to scrape ATS jobs?
The price is $1.00 per 1,000 job postings, tier-discounted on higher Apify plans, with no Actor start fee. One job posting is one charged result; company summary rows are part of the same output.
Worked examples:
- 20 companies, roughly 40 open roles each = about 800 rows = $0.80.
- A 50-company watchlist on a daily schedule with
onlyNewJobs: the first run bills the full boards (say 2,000 rows, $2.00), then each following day bills only what is new. At a typical 1 to 3% daily churn that is 20 to 60 rows, or $0.02 to $0.06 per day. - A one-off headcount scan, 5 newest jobs across 200 companies = 1,000 rows = $1.00.
The two levers that move your bill are maxJobsPerCompany (a hard cap on rows per company) and onlyNewJobs (stops you paying twice for the same posting). Descriptions do not change the price, only the size of each row.
🔁 Run it on the Apify platform
Schedule it daily or weekly from Apify Console, call it from the API or any Apify SDK, and push results into Google Sheets, Slack, a webhook, Make, Zapier, or your warehouse through Apify integrations. Results persist as a dataset you can re-export any time as JSON, CSV, Excel, HTML, RSS, or XML. Monitoring mode plus a schedule plus a Slack integration is the setup most buyers land on: a channel that fills up when a watched company starts hiring.
🤖 Use with AI agents via MCP
This Actor is callable from any MCP-capable AI client through the Apify MCP server, so an agent can fetch live hiring data instead of guessing from its training data.
Claude Code:
$claude mcp add apify --env APIFY_TOKEN=your_apify_token -- npx -y @apify/actors-mcp-server --actors webdata_labs/greenhouse-lever-ashby-jobs-scraper
Cursor, Claude Desktop, or any client that reads an MCP JSON config:
{"mcpServers": {"apify": {"command": "npx","args": ["-y","@apify/actors-mcp-server","--actors","webdata_labs/greenhouse-lever-ashby-jobs-scraper"],"env": { "APIFY_TOKEN": "your_apify_token" }}}}
Prompts that work well once it is connected:
- "Get every open engineering role at stripe, ramp, and palantir and group them by location."
- "Which of these 30 companies opened a sales role in the last week?"
- "Pull all remote jobs from this company list and write them to a CSV."
- "Check hiring at these Workday employers using their careers URLs."
🔗 Use this Actor in n8n
- Add the Apify node to your workflow and connect it with an Apify API token.
- Choose Run Actor and pick
webdata_labs/greenhouse-lever-ashby-jobs-scraper. - Paste the input JSON, with
onlyNewJobsset totrueif the workflow runs on a schedule. - Add Get dataset items after it to pull the rows into the workflow.
- Route from there: filter on
isRemote, split bydepartment, append to Google Sheets, post new roles to Slack, or upsert into your CRM keyed onjobId.
The same shape works in Make and Zapier through their Apify integrations, and through a plain webhook if you would rather receive the run-finished event yourself.
⚠️ Limits and caveats
Read this before you build on the Actor. It is the honest list.
- SmartRecruiters cannot say "no such company". Its public API returns HTTP 200 with zero postings for any slug you invent, so a wrong slug is indistinguishable from a real employer with nothing open. To stop that becoming silent bad data, an empty SmartRecruiters board found during auto-detection is reported as
found: false. If you genuinely want an empty SmartRecruiters board back, force it with thesmartrecruiters:prefix and you getfound: true, totalJobs: 0. - Workday auto-detection is best effort. It runs only after the six cheaper ATS checks and can require up to fifteen tenant and career-site probes per slug variant. The careers URL remains the fastest and most reliable Workday input; unusual tenant or site names can still require an explicit URL.
- Field availability varies by ATS. Workday's list endpoint exposes only a relative posting age (kept in
postedOnRaw, withpostedAtnull), Personio's public search does not expose posting dates at all, and neither Workday nor SmartRecruiters includes the ad body in its list endpoint, sodescriptionHtmlstays null for those two even withincludeDescriptionon. - You supply the companies. This Actor enriches a list; it does not discover which companies exist or which ones are hiring. Pair it with your own target list, a CRM export, or a portfolio page.
- Only the seven listed platforms are covered. A company on Workable, BambooHR, JazzHR, Teamtailor, iCIMS, or a hand-built careers page returns
found: falsewith a note. That is a deliberate honest miss, not a silent empty result. - Company-name input is a convenience, not magic.
Y Combinatorresolves because its board slug isycombinator. A company whose slug does not follow from its name (a rebrand, an abbreviation, a parent company) needs the slug or the URL. - Monitoring memory is per Apify account and per resolved company. Changing how you write an input can start a fresh memory for that entry, so the next run returns everything once.
- 1000 companies per run. Extras are not silently dropped: they are trimmed, logged, and listed in the run summary under
skippedCompaniesso you can split them into a second run. - Public postings only. Internal, login-gated, and unpublished requisitions are not exposed by these endpoints and are not returned here.
- Rate limits are ours to manage, not yours. Concurrency, retries, and routing are fixed internally at values that keep the providers answering. That is why there is no dial for them, and it is the main reason the run-success rate holds at 99%.
⚖️ Is it legal to scrape ATS job boards?
This Actor reads job postings that companies publish deliberately and publicly, through the ATS vendors' own public job-board endpoints: the same data any candidate sees on the careers page, in the format the vendor serves. It collects no personal data. No candidates, no applicants, no recruiter contact details, no resumes. Job postings are company-published business information.
How you use the output is still your responsibility: respect the terms of the platforms you interact with, and if you re-publish postings, keep them attributed and current so you are not advertising roles that have closed. Nothing here is legal advice, and this Actor is not affiliated with or endorsed by Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, or Personio.
🧩 Related Actors
A hiring-intelligence pipeline: find who is hiring, get their jobs, enrich with contacts and tech stack.
- Company Career Page Jobs API - covers companies whose careers page is not backed by one of the seven ATS platforms here. Run it over whatever comes back
found: false. - ATS Hiring Monitor API - hiring-change monitoring built around alerting rather than bulk export, when you want the signal and not the dataset.
- Website Contact Extractor - turns the companies you found hiring into outreach-ready emails, phones, and social profiles. This is the step that makes hiring data usable by a sales team.
- Website Tech Stack Detector - qualifies those same companies by the tools their site actually runs.
- Naukri Job Scraper - job listings for the Indian market, where ATS coverage is thin and Naukri is the market.
- Lead List Deduplicator - cleans and merges the enriched rows before they go into a CRM.
Typical chain: scrape jobs here, filter to companies hiring for the roles you care about, run Website Contact Extractor for emails, then Lead List Deduplicator before import.
❓ FAQ
How does ATS auto-detection work?
For a value with no prefix, the Actor probes Greenhouse, Lever, Ashby, Recruitee, Personio, and SmartRecruiters, then uses Workday discovery as the final fallback. An empty SmartRecruiters response does not stop detection because that API cannot distinguish an unknown company from a real company with zero postings. Force any platform with a prefix to skip detection entirely.
Where do I find a company's board slug?
It is the company identifier in its careers URL: job-boards.greenhouse.io/stripe, jobs.lever.co/palantir, jobs.ashbyhq.com/ramp, bunq.recruitee.com, everphone.jobs.personio.de, careers.smartrecruiters.com/BoschGroup. You can paste the whole URL instead and let the Actor extract it.
Can I just use company names?
Usually, yes. A name is tried literally, then normalized (lowercased, corporate suffix removed, spaces stripped) and tried again. Slugs that do not follow from the company name need the slug or the URL.
How do I scrape a Workday company?
Paste its careers URL, for example https://adobe.wd5.myworkdayjobs.com/external_experienced, or use workday:adobe. An unprefixed company name or slug also reaches Workday after the other ATS checks. With a bare slug the Actor probes the tenant's Workday host and career-site name automatically; if discovery fails, the URL is the reliable fallback.
Am I charged for companies that are not found?
A not-found company writes one company summary row, so it costs one result, not a full board. A failed company writes one error row. There is no start fee.
How does monitoring mode remember what it has seen?
It keeps a per-company set of job IDs in a named key-value store on your own Apify account, ats-jobs-scraper-delta-state. Delete the store, or one record in it, to reset the memory and treat the next run as a first run.
Does it need a proxy?
No, and there is no proxy field to configure. Routing, retries, and concurrency are handled internally at values tuned to these providers' rate limits. That decision is why the Actor holds a 99% success rate, and it is why the dial is not exposed.
Can it return full job descriptions?
Yes for Greenhouse, Lever, Ashby, Recruitee, and Personio: turn on includeDescription. Workday and SmartRecruiters do not include the ad body in their list endpoints, so descriptionHtml stays null for those two.
Can I filter by title, location, remote, or salary?
Not from the input yet. Every row carries title, location, isRemote, department, and employmentType, so filtering after export works today. Input-side filters are the next thing being built here; if there is a specific filter you need, open an issue and it gets weighted by how many people ask for it.
How many companies can I run at once?
Up to 1000 per run. Anything beyond that is trimmed and reported in the run summary rather than failing the run.
📝 Changelog
- 0.1.10 - 2026-08-01 - Fixed the run Output tab by linking the default dataset and run summary with valid output-schema templates. Unprefixed company names and slugs now include Workday as the final ATS auto-detection fallback.
- 0.1.7 - 2026-07-30 - Input simplified to four fields:
proxyConfiguration,requestRetries, andmaxConcurrencyremoved and handled internally. Company names now work alongside slugs and URLs in the same list.companyUrls,startUrls, andqueriesaccepted as aliases ofcompanies. Empty SmartRecruiters boards found by auto-detection are now reported as not found instead of as a valid company with zero jobs. Full ATS coverage list, output field tables, MCP and n8n sections added to this README. - 0.1.6 - 2026-07-27 - Reliability and coverage maintenance.
- 0.1.5 - 2026-07-15 - Reliability and coverage maintenance.
- 0.1.3 and 0.1.4 - 2026-07-03 - Reliability and coverage maintenance.
- 0.1.1 and 0.1.2 - 2026-06-27 - First public release: seven ATS platforms, automatic detection, unified schema, and monitoring mode.
🛠️ Support
For bugs or missing fields, open an Actor issue with the run URL, the company value you passed, and the field or behavior you expected. Requests for an additional ATS platform or an input filter are welcome in the same place and are prioritized by how often they are asked for.
⭐ Rate this Actor
If this Actor saved you time, please take 30 seconds to leave a review on the Reviews tab of ATS Jobs Scraper. Reviews are the main trust signal other buyers see, and they directly decide what gets built next. If something is broken or a field is missing, please open an issue first: we typically respond within a day and would rather fix it than be rated on it.