Hiring.Cafe Scraper - Jobs, Salaries, Companies & Benefits avatar

Hiring.Cafe Scraper - Jobs, Salaries, Companies & Benefits

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Hiring.Cafe Scraper - Jobs, Salaries, Companies & Benefits

Hiring.Cafe Scraper - Jobs, Salaries, Companies & Benefits

Scrape Hiring.Cafe jobs from $1/1K results. Search with advanced filters or URLs and extract 100+ fields per job, including salaries, company insights, benefits and job details. Fast, scalable job data extraction with Gold discounts starting at $1.

Pricing

from $1.00 / 1,000 results

Rating

3.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

3

Bookmarked

29

Total users

0

Monthly active users

a day ago

Last modified

Share

Hiring Cafe Scraper: Job Listings, Salaries, Skills & Company Data

Hiring Cafe scraper turns Hiring Cafe job search into a clean data feed. Get job titles, salary ranges and currency, seniority and workplace type, required skills, certifications, visa sponsorship, benefits, and the hiring company's size, funding and headquarters, for roles indexed from company career sites. Search by keyword and filters, or paste search links and single job links, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

Why This Scraper?

  • Two ways to search. Filter by keyword, location, workplace type, employment type and seniority, or paste Hiring Cafe search links and single job links directly.
  • 100+ structured attributes per job. The complete nested payload the site publishes, plus a curated flat view for filtering and sorting.
  • Full job descriptions on request. Switch on Fetch full job descriptions to pull each posting's complete text; leave it off for a fast, listing only crawl.
  • Company context on every job. Employee count, founding year, headquarters country, funding stage and stock ticker, when the posting publishes them.
  • Pay, requirements and benefits at a glance. Salary range and frequency, minimum years of experience, required education, certifications, visa sponsorship, security clearance, benefits and schedule flags.
  • Built for schedules. Incremental mode returns only new and changed jobs on recurring runs, and a run that cannot connect at all fails loudly instead of returning an empty dataset.
  • Send results into your apps. Optional MCP connectors pipe a summary of each job into Notion, Linear or Airtable right after the scrape.

Use Cases

  • Job boards and aggregators: mirror Hiring Cafe postings with structured salary, benefits and requirement fields ready to filter and republish.
  • Recruiting and sourcing teams: track new roles at target companies, along with funding stage and headcount, to time outreach.
  • Compensation and market research: build salary benchmarks by title, seniority, location and workplace type.
  • Job seekers and career tools: power a personal alert feed for a keyword and location search, refreshed daily with incremental mode.
  • Labor market analysis: study hiring trends across employment types, seniority levels, required skills and certifications over time.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
id"abc123XYZ"
job_title"Senior Backend Engineer"
company_name"Sample Robotics Inc."
employment_types"Full Time"
seniority"Senior Level"
workplace_type"Remote"
location"United States"
remote_worldwidetrue
salary_min / salary_max120000 / 160000
salary_currency / salary_frequency"USD" / "yearly"
salary_transparenttrue
posted_at"2026-09-20"
min_years_experience5
education_required["bachelors"]
certifications / technical_tools["AWS Certified Solutions Architect"] / ["Python", "Kubernetes"]
visa_sponsorship / security_clearance"No" / "Not required"
benefits["retirement_plan", "generous_paid_time_off"]
schedule["four_day_work_week"]
company_employees / company_founded"51-200" / 2015
is_public_companyfalse
investors / latest_investment_series / latest_investment_amount["Sample Capital"] / "Series B" / 20000000
views_on_site / applies_on_site340 / 28
job_url / apply_urlHiring Cafe link to the job / the employer's own application link

Every record also carries the complete nested payload the site publishes: job_information, v5_processed_job_data (85+ structured attributes), the company record (v5_processed_company_data), and _geoloc coordinates, so no source field is ever dropped. With Fetch full job descriptions on, records also carry description (HTML) and description_text (plain text), plus detailFetched (true when this job's page was read to build the record; false when the page was refused, the toggle was off, or the job's page was not needed). Incremental mode runs add changeType, changedFields, firstSeenAt and lastSeenAt to every record.

How to Use

  1. Pick a way to search: paste Start URLs (Hiring Cafe search links or single job links), or fill in Search keyword and the filters below it.
  2. Turn Fetch full job descriptions on or off; it is on by default.
  3. Set Maximum jobs to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV or Excel, or read it through the API.

Search by keyword and location:

{
"keyword": "data scientist",
"location": "Germany",
"workplaceType": "Remote",
"maxItems": 50
}

Filter by employment type, seniority and recency:

{
"keyword": "product manager",
"commitmentType": "Full Time",
"seniorityLevel": "Senior Level",
"postedWithinDays": 7,
"salaryTransparentOnly": true
}

Start from URLs (a search link plus a single job link):

{
"startUrls": [
"https://hiringcafe.com/?searchState=%7B%22searchQuery%22%3A%22nurse%22%7D",
"https://hiringcafe.com/job/1234567"
],
"fetchDetails": true
}

Fast listing only crawl, no descriptions:

{
"keyword": "warehouse associate",
"location": "Chicago",
"fetchDetails": false,
"maxItems": 200
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/hiring-cafe-scraper").call(run_input={"keyword": "data scientist", "location": "Germany"})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["job_title"], job["company_name"], job.get("salary_min"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/hiring-cafe-scraper').call({ keyword: 'data scientist', location: 'Germany' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Start URLs take priority

Default behaviour: Start URLs ships with six example links, one per supported shape (the table below). A run started with the field untouched, or an API call that leaves the field out and sets no keyword or filter, scrapes those six links: a bare search page, four searches for software engineer (one starting at page 2, one with the older base64-encoded filter form) and one single job. Filter inputs that still hold their form default (Posted within days 30, Salary transparent only off, Sort by default, "Any" choices, empty lists) count as "not set", so the platform filling those in for you does not switch the actor to filter mode.

Precedence: (1) Start URLs you changed always win and the filters are ignored. (2) If Start URLs is empty or still holds exactly the six example links, and you set a keyword, location, or any filter to a non-default value, the actor searches by your filters instead. (3) With neither, it runs the six example links. The keyword box is not pre-filled in the input form, so a form run left untouched runs the six example links.

Link shapeHandled as
https://hiringcafe.com/classic?searchState=โ€ฆsearch (this is the example)
โ€ฆ?searchState=โ€ฆ&page=Nsearch, starts at page N
https://hiringcafe.com/?searchState=โ€ฆsearch (same as the classic link)
https://hiringcafe.com/classicsearch, no filters
https://hiringcafe.com/?searchState=<base64>search (older base64-encoded filter form)
https://hiringcafe.com/job/<id> (also old /viewjob/<id>)single job

Any other link is skipped with a warning in the log naming the link.

Start URLs you change take priority and the filters (Search keyword, Location, Workplace type, Employment type, Seniority level, Posted within, Salary transparent only, Sort by and the extra company, industry, salary and experience filters) are ignored for that run; the untouched example links give way to a keyword or filter you set. Clear Start URLs to search by filters instead.

Run summary

Every run saves a record named OUTPUT in the run's key-value store: one entry per search link (or the filter-built search) and per single-job link, each with the link, start page, rows returned, pages read and why it stopped (last_page: the last page of results was read; empty_page: a page came back with no jobs; max_items: the Maximum jobs cap was reached; fetch_failed: the page could not be loaded; saved: a single job link was returned; no_data: a single job link had no data, for example an expired job; duplicate_or_suppressed: a single job link loaded but nothing was returned because it was already returned in this run or incremental mode left it out as unchanged), plus run totals. It is not part of the dataset, which stays one job per row.

How the filters were checked

Each filter was tested against the live site by comparing the number of matching jobs with and without it, plus a nonsense value that must match nothing (2026-10-15, about 111,000 jobs without filters): job title text (nurse 5,226; nonsense 0), company names (Google 69; nonsense 0), excluded company names (Google 111,063), industries (Software Development 2,578; nonsense 0), excluded industries (108,543), years of experience (0 to 2 years 84,103; 10 or more 12,152), employment types (Temporary 10,484; Seasonal 3,699; Volunteer 1,620; Full Time 76,873; nonsense 0), workplace Remote 4,097, salary transparent 23,294. Pay bounds narrow only jobs that disclose pay (disclosed-pay jobs: no bound 23,294; minimum 150,000 gives 1,750; minimum 1,000,000,000 gives 0), which is why setting a bound also limits results to disclosed pay. The site applies the "Posted within days" window only for some values: 2 days (6,048), 14 days (24,546) and 1,440 days (109,815) narrowed the count, while 1, 3, 7, 30, 60, 90, 180, 365 and 1,000 returned the full count, so treat that filter as approximate.

Output views

The dataset has four views: Overview (id, links, change fields), Job Details (title, company, pay, level, workplace, requirements), Companies (company record and coordinates) and Changes (incremental mode rows with changeType, changedFields, firstSeenAt, lastSeenAt).

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every job already collected there, so you don't pay twice.
  • Incremental mode (incrementalMode) is for running the same search again and again, for example daily. The first run returns everything as NEW. Later runs return only NEW, UPDATED (with changedFields) and REAPPEARED jobs; UNCHANGED jobs are suppressed and not billed unless emitUnchanged is on, and EXPIRED jobs are only produced after a run that scanned the tracked search all the way through, and only with emitExpired. stateKey names or shares the stored state. A job counts as UPDATED when any published field changes; views_on_site and applies_on_site are running counters and never trigger UPDATED (they stay in the output), and ignoreFieldsForChanges lets you exclude more fields, by name or by dotted path such as v5_processed_job_data.some_field. A Start URL that begins after page 1 never produces EXPIRED jobs, and EXPIRED rows never exceed the room left under maxItems. Saved state keeps loading after the example links were added: a recurring call that uses incremental mode with no keyword, no filter and no Start URLs of its own still runs the six example links, and it is tracked under the same saved state as before, so nothing already tracked is returned or billed again as NEW. Changing any filter or Start URL starts a separate saved state, as it always did. With incremental mode off, output is exactly as before. One-time change on upgrade: this version adds new top-level job fields (for example core_job_title, the *_min_compensation / *_max_compensation family, workplace_*, industries, subsidiaries, investors). Jobs already tracked by an earlier version are not re-billed as UPDATED because of those new fields alone: the first run after the upgrade records them silently as UNCHANGED. A real change to the job in that same run still returns UPDATED, and after that first run any later change to the new fields counts as a normal update.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human readable summary of each job, not the full JSON. Each job becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify โ†’ Settings โ†’ Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where jobs should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
startUrlsarraysix example links (one per shape)Hiring Cafe search links (with ?searchState=โ€ฆ) and/or single job links (โ€ฆ/job/โ€ฆ). Links you change take priority over the filters below; the untouched example links give way to a keyword or filter you set.
keywordstring(none)Job title, skill, or company name. Used when Start URLs is empty or still the six example links; other Start URLs take priority.
locationstring(none)Country or city. Combined with the keyword; leave empty for worldwide results.
workplaceTypestringAnyAny, Remote, Hybrid, or Onsite.
commitmentTypestringAnyAny, Full Time, Part Time, Contract, or Internship.
seniorityLevelstringAnyAny, No Prior Experience Required, Entry Level, Mid Level, or Senior Level.
postedWithinDaysinteger30Only jobs published in the last N days (maximum 1440). Approximate: the site applies this window only for some values (measured: 2, 14 and 1440 days narrowed the results, 30 did not), so treat it as a hint, not an exact cut-off.
salaryTransparentOnlybooleanfalseReturn only jobs whose pay is publicly disclosed.
sortBystringdefaultResult order: default (relevance), date (newest first), date_asc (oldest first), compensation, experience.
workplaceTypesarray(none)Several values at once; when set they override the single-value fields above.
commitmentTypesarray(none)Several values at once; when set they override the single-value fields above.
seniorityLevelsarray(none)Several values at once; when set they override the single-value fields above.
jobTitleQuerystring(none)Match text against the job title only.
companyNamesarray(none)Only, or never, these companies.
excludedCompanyNamesarray(none)Only, or never, these companies.
industriesarray(none)Only, or never, these industries.
excludedIndustriesarray(none)Only, or never, these industries.
minSalaryinteger(none)Yearly compensation bounds (site currency units). Setting a bound also limits results to jobs that disclose their pay, because the site otherwise lets jobs without pay information through.
maxSalaryinteger(none)Yearly compensation bounds (site currency units). Same disclosed-pay behaviour as Minimum salary.
minYoeinteger(none)Bounds on required years of experience.
maxYoeinteger(none)Bounds on required years of experience.
maxItemsinteger1000Stop after this many jobs (0 = unlimited). The input form pre-fills 20 as a light starting run; raise it for a full pull. Each results page carries up to ~100 jobs.
resumeFromRunIdstring(none)Paste a previous run ID or dataset ID to continue a large search without returning or charging for jobs already collected there.
incrementalModebooleanfalseTurn on for daily or recurring monitoring of the same search: returns only new and changed jobs on later runs.
stateKeystring(none)Name this monitoring campaign, or deliberately share state across differently configured runs. Left empty, the actor derives a key from the search/filters/URLs automatically.
emitUnchangedbooleanfalseAlso return (and bill) jobs that have not changed since the last run, marked UNCHANGED. Incremental mode only.
emitExpiredbooleanfalseAlso return (and bill) jobs no longer found after a complete scan of the tracked search, marked EXPIRED. Incremental mode only.
ignoreFieldsForChangesarray(none; counters ignored by default)Field names or dotted paths left out of UPDATED detection (incremental mode only). They remain in the output.
proxyobjectResidential (Apify Proxy)Connection settings. Hiring Cafe challenges datacenter connections, so keep the Residential group selected (see Plan Requirement).
mcpConnectorsarray(none)Optional: send a summary of each job to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which job pages are created.
maxNotifyListingsinteger50Cap on jobs written to each connector per run. Does not affect the dataset.
fetchDetailsbooleantrueRead each matched job's own page for the full description and the freshest view/apply counts. Each delivered job whose page was read is charged as one detail-page event on top of the per-result charge. Turn off for a fast, listing only crawl.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"id": "abc123XYZ",
"requisition_id": "REQ-4821",
"source": "greenhouse",
"job_title": "Senior Backend Engineer",
"company_name": "Sample Robotics Inc.",
"employment_types": "Full Time",
"seniority": "Senior Level",
"workplace_type": "Remote",
"location": "United States",
"remote_worldwide": true,
"salary_min": 120000,
"salary_max": 160000,
"salary_currency": "USD",
"salary_frequency": "yearly",
"salary_transparent": true,
"posted_at": "2026-09-20",
"min_years_experience": 5,
"education_required": ["bachelors"],
"certifications": ["AWS Certified Solutions Architect"],
"technical_tools": ["Python", "Kubernetes"],
"visa_sponsorship": "No",
"benefits": ["retirement_plan", "generous_paid_time_off"],
"company_employees": "51-200",
"company_founded": 2015,
"company_hq_country": "United States",
"views_on_site": 340,
"applies_on_site": 28,
"description_text": "We are looking for a Senior Backend Engineer to join our platform team...",
"job_url": "https://hiringcafe.com/job/REQ-4821",
"apply_url": "https://sample-robotics.example.com/careers/req-4821/apply",
"job_information": {},
"v5_processed_job_data": {},
"v5_processed_company_data": {},
"_geoloc": { "lat": 37.77, "lng": -122.41 }
}

Plan Requirement

A paid Apify plan with residential proxy access is required for reliable results. Hiring Cafe sits behind a managed browser challenge, and datacenter connections do not get through it. The default Proxy configuration is the Residential group, so keep it selected. This is not a "works with no action needed" actor on a free plan.

On an Apify free plan (no residential proxies) the run does not stop at once: it logs this notice and continues on a backup connection, which may still be refused:

The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.

If the backup connection serves pages, the log says: "Served over the backup connection (the default connection was unavailable)." If nothing can be loaded the run fails with one of these messages:

  • Connection refused for the account: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
  • Free plan, backup also refused: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested hiring.cafe pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
  • Pages failed to load: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."

FAQ

How much does it cost?

You pay per job returned plus a small per-run start fee, on the pay per event model. With Fetch full job descriptions on (the default), each delivered job whose own page was read is also charged as one detail-page event. All events are charged by the platform at the rates shown on the Pricing tab, which are the authoritative live rates and depend on your Apify plan tier. Jobs suppressed by incremental mode (UNCHANGED) are never charged. Use Maximum jobs to cap the cost of any run.

This actor collects only publicly available job listings. You are responsible for how you use it: follow Hiring Cafe's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Job descriptions and company details may carry the original poster's rights.

Can I get only new or changed jobs on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. The first run returns every matching job as NEW; later runs return only NEW, UPDATED and REAPPEARED jobs, classified against a fingerprint of each job's own content, and unchanged jobs are not billed unless you turn on Emit unchanged.

Why do my filters seem to have no effect?

Start URLs you change take priority over the filters below it: keyword, location, workplace type, employment type, seniority and posted within days are all ignored for that run. The untouched example links give way to a keyword or filter you set. Clear Start URLs to search by filters instead.

Why did my run fail instead of returning an empty dataset?

A run fails only when it cannot connect at all before loading a single page, when every Start URL is unrecognized (neither a Hiring Cafe search link nor a job link), when Resume from a previous run points at an id that cannot be read, or when Resume from a previous run is combined with Incremental mode for a search that already has saved incremental state; each of these stops the run with a clear message. If the connection works but an individual page is later refused, or your filters simply match nothing, the run finishes normally and returns fewer jobs, or none, with the reason logged.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more jobs data?

Pair this actor with these related scrapers from the same team:

๐Ÿ’ผ CareerBuilder Scraper
Scrape CareerBuilder.com job listings by search or URL. Returns title, company profile...
๐Ÿ’ผ Jobsite UK Scraper
Scrape Jobsite.co.uk job listings at scale by keyword, location, filters or URL. Extract...
๐Ÿ’ผ Dice.com Scraper
Scrape tech job listings from Dice.com by keyword, filters, or URL. Extract job titles...
๐Ÿ’ผ NoFluffJobs Scraper
Scrape No Fluff Jobs IT listings across Poland, Czechia, Slovakia, Hungary and the...
๐Ÿงฉ Naukri.com Scraper
Scrape Naukri.com jobs by keyword or URL. Extract job title, company, skills, experience...
๐Ÿ’ผ WeWorkRemotely Scraper
Extract current remote job listings from weworkremotely.com. Use keyword search or WWR...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.