# Hiring.cafe Job Scraper (`solidcode/hiringcafe-scraper`) Actor

\[💰 $1.1 / 1K] Every job listing on Hiring.cafe as 60 flat, named columns — title, normalized title, seniority, workplace type, pay in yearly and hourly units, coordinates, and full employer context. Paste a filtered search URL, run, and export to JSON, CSV or Excel.

- **URL**: https://apify.com/solidcode/hiringcafe-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 job results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Hiring.cafe Job Scraper

Pull job listings from Hiring.cafe at scale — 60 flat, named columns per posting covering the
role, the pay, the location and the employer behind it, starting from a search URL you paste
straight out of your address bar. Built for talent-intelligence teams, recruiters and
labour-market analysts who need a job dataset they can filter and join on day one, instead of
reshaping a raw job-feed export before the first question gets answered.

### Why This Scraper?

- **60 fields on every job** — role, seniority, workplace type, pay, requirements, coordinates and the hiring company all arrive as flat, named columns on a single row. Nothing to unpack.
- **Titles that join across languages and job boards** — `normalizedTitle` is the aggregator's canonical rewrite, and it differs from the posted title on 274 of 492 sampled postings, so a Berlin "Examinierte Pflegefachkraft (m/w/d)" groups with a New York "Registered Nurse".
- **Closed enums you can safely build a filter on** — `workplaceType` is exactly Onsite, Hybrid, Remote or Field, and `seniorityLevel` exactly Entry Level, Mid Level, Senior Level or No Prior Experience Required, on all 492 postings in the measured sample.
- **Pay in two units, plus the employer's own wording** — the annual and hourly columns carry the same figure expressed both ways, `salaryPeriodListed` records the period the employer actually quoted, and `salaryIsTransparent` marks every row where pay was published at all.
- **Two company URLs, because they are two different things** — the employer's own website and the page that hosts the application resolved to different hosts on 119 of the 247 sampled postings carrying both, so a job board never gets filed as a company site.
- **Employer context on the job row itself** — sector, industry list, headcount, year founded, HQ country, organisation type, stock symbol and latest funding round, so you can segment by company size or maturity without joining a second dataset.
- **Mapped, multi-site-aware locations** — `latitude` and `longitude` ship with the posting, and `locationCount` flagged 81 of 492 sampled postings as covering more than one site; one chain-retail requisition spanned 80.
- **Global from the first page** — the 492-posting measurement sample spanned 77 countries and USD, GBP and EUR pay, drawn from New York, Dallas, London and Berlin across software, nursing and warehouse roles.
- **Dates you can sort and diff** — `postedAt` is UTC ISO-8601 and agreed with the aggregator's own second timestamp on all 492 sampled postings, so daily snapshots line up without timezone repair.

### Use Cases

#### Talent Market Intelligence

- Track hiring volume by `jobCategory`, `seniorityLevel` and country, week over week, from repeat runs.
- Measure the remote / hybrid / onsite mix in a market from the four-value `workplaceType` column.
- Spot expanding employers by joining posting counts to `companySizeEmployees` and `companyLatestFundingYear`.
- Compare demand for the same role across New York, London and Berlin using `normalizedTitle` as the join key.

#### Compensation Benchmarking

- Build salary bands per role and city from the annual columns, restricted to rows where `salaryIsTransparent` is true.
- Compare hourly pay across warehouse and clinical roles without converting units by hand.
- Track pay-transparency rates by jurisdiction — `salaryPeriodListed` and `salaryIsTransparent` are there even when amounts are not.
- Keep `salaryCurrency` in the group-by so USD, GBP and EUR rows are never averaged together.

#### Recruiting & Sourcing

- Build target lists of employers hiring for a role in a specific metro, with `companyWebsite` and `companyJobBoardUrl` on every row.
- Narrow to roles offering `visaSponsorship` or `relocationAssistance` for candidates who need them.
- Route postings by `minYearsExperience`, `bachelorsDegreeRequirement` and `licensesOrCertifications`.
- Surface `fairChance` employers for programmes placing candidates with a record.

#### Product & Data Enrichment

- Seed or refresh a job board with normalized, deduplicated rows instead of raw feed text.
- Enrich an employer database with sector, headcount, founding year and latest funding round.
- Map postings without a geocoding step — `latitude` and `longitude` are already on the row.
- Load straight into a warehouse through the Apify API, webhooks or Google Sheets.

#### Skills & Curriculum Research

- Rank tools and technologies by how often they appear beside a given role and seniority.
- Track which licences and certifications gate entry into clinical and logistics work.
- Measure degree expectations by market with `bachelorsDegreeRequirement` and `degreeFieldsOfStudy`.
- Correlate `minYearsExperience` against pay to see what experience is actually worth.

### Getting Started

#### Simplest run

```json
{
  "maxItems": 100
}
```

#### Paste a filtered search URL from the site

Set your filters on the site, then copy the address bar URL — every filter in it is
carried through.

```json
{
  "searchUrls": [
    "https://hiring.cafe/?searchState=%7B%22searchQuery%22%3A%22software+engineer%22%2C%22workplaceTypes%22%3A%5B%22Remote%22%5D%7D"
  ],
  "maxItems": 1000
}
```

#### Several searches in one run

Jobs that match more than one of your searches are collapsed to a single row.

```json
{
  "searchUrls": [
    "https://hiring.cafe/?searchState=%7B%22searchQuery%22%3A%22registered+nurse%22%7D",
    "https://hiring.cafe/?searchState=%7B%22searchQuery%22%3A%22warehouse+associate%22%7D"
  ],
  "maxItems": 4620,
  "concurrency": 8
}
```

### Input Reference

#### What to Scrape

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchUrls` | array | — | Hiring.cafe search result URLs. Set your filters on Hiring.cafe, then paste the address bar URL here. Overrides the individual filters below when provided. |
| `maxItems` | integer | `100` | Maximum jobs per search URL (0 = collect everything each search returns). Hiring.cafe pages through at most 4,620 jobs per search, so use several narrower searches to collect more. |

#### Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `concurrency` | integer | `8` | How many requests to run in parallel. Lower this if you see failures. |
| `proxyConfiguration` | object | Apify Proxy | Proxy settings for the run. |

### Output

Every job is one dataset row.

A real row, exactly as the actor writes it:

```json
{
  "id": "lever___intenseye___c20f0c7b-ba58-4c65-8826-3959874d315e",
  "url": "https://jobs.lever.co/intenseye/c20f0c7b-ba58-4c65-8826-3959874d315e/apply",
  "title": "Software Engineer",
  "normalizedTitle": "Software Engineer",
  "jobCategory": "Software Development",
  "seniorityLevel": "Senior Level",
  "roleType": "Individual Contributor",
  "employmentTypes": ["Full Time"],
  "requirementsSummary": "5+ years professional software engineering with full-stack ownership; strong in C++, Python, React/TypeScript; experience building low-latency data pipelines, REST APIs, and GCP deployments; product-minded and strong communicator.",
  "postedAt": "2026-06-15T13:27:58.789+00:00",
  "source": "lever",
  "isExpired": false,
  "workplaceType": "Hybrid",
  "location": "New York City, New York, United States",
  "cities": ["New York City, New York, US"],
  "states": ["New York, US"],
  "countries": ["US"],
  "latitude": 40.7128,
  "longitude": -74.006,
  "locationCount": 1,
  "isWorldwideOk": false,
  "salaryMinYearly": 160000,
  "salaryMaxYearly": 200000,
  "salaryMinHourly": 76.92,
  "salaryMaxHourly": 96.15,
  "salaryCurrency": "USD",
  "salaryPeriodListed": "Yearly",
  "salaryIsTransparent": true,
  "retirementPlan": false,
  "tuitionReimbursement": false,
  "generousParentalLeave": false,
  "relocationAssistance": false,
  "companyName": "Intenseye",
  "companyBrandName": "Intenseye",
  "companyWebsite": "https://intenseye.com",
  "companyJobBoardUrl": "https://intenseye.com",
  "companyTagline": "Builds AI-powered safety platforms that deliver real-time operational and risk insights for industrial worksites.",
  "companySector": "Information Technology",
  "companyIndustries": ["Software", "Industrial Safety"],
  "companySizeEmployees": 110,
  "companyYearFounded": 2018,
  "companyType": "Private",
  "companyHqCountry": "US",
  "companyStockSymbol": null,
  "companyLatestFundingAmount": 64000000,
  "companyLatestFundingYear": 2024,
  "companyLatestFundingType": "Series B",
  "minYearsExperience": 5,
  "bachelorsDegreeRequirement": "Preferred",
  "degreeFieldsOfStudy": ["computer science", "computer engineering"],
  "technicalTools": ["C++", "Python", "React", "TypeScript", "GCP", "REST"],
  "licensesOrCertifications": null,
  "languageRequirements": ["English"],
  "securityClearance": "None",
  "isDriverLicenseRequired": false,
  "visaSponsorship": false,
  "fairChance": false,
  "physicalLaborIntensity": "Low",
  "workplacePhysicalEnvironment": "Office",
  "onCallRequirement": "None"
}
```

#### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Job ID |
| `url` | string | Apply URL |
| `title` | string | Job title |
| `normalizedTitle` | string | Normalized job title |
| `jobCategory` | string | Job category |
| `seniorityLevel` | string | Seniority |
| `roleType` | string | IC or manager |
| `employmentTypes` | array | Employment type |
| `requirementsSummary` | string | Requirements summary |
| `postedAt` | string | Posted date |
| `source` | string | Posting source |
| `isExpired` | boolean | Expired |

#### Price & Value

| Field | Type | Description |
|-------|------|-------------|
| `salaryMinYearly` | number | Salary min (per year) |
| `salaryMaxYearly` | number | Salary max (per year) |
| `salaryMinHourly` | number | Pay min (per hour) |
| `salaryMaxHourly` | number | Pay max (per hour) |
| `salaryCurrency` | string | Currency |
| `salaryPeriodListed` | string | Period the employer quoted |
| `salaryIsTransparent` | boolean | Salary disclosed |
| `retirementPlan` | boolean | Retirement plan |
| `tuitionReimbursement` | boolean | Tuition reimbursement |
| `generousParentalLeave` | boolean | Generous parental leave |
| `relocationAssistance` | boolean | Relocation assistance |

#### Location

| Field | Type | Description |
|-------|------|-------------|
| `workplaceType` | string | Workplace type |
| `location` | string | Location |
| `cities` | array | Cities |
| `states` | array | States / regions |
| `countries` | array | Countries |
| `latitude` | number | Latitude |
| `longitude` | number | Longitude |
| `locationCount` | number | Number of locations |
| `isWorldwideOk` | boolean | Hire from anywhere |

#### Contacts

| Field | Type | Description |
|-------|------|-------------|
| `companyName` | string | Company (as posted) |
| `companyBrandName` | string | Company (canonical) |
| `companyWebsite` | string | Company website |
| `companyJobBoardUrl` | string | Company job-board page |
| `companyTagline` | string | Company tagline |
| `companySector` | string | Sector |
| `companyIndustries` | array | Industries |
| `companySizeEmployees` | number | Employees |
| `companyYearFounded` | number | Year founded |
| `companyType` | string | Organization type |
| `companyHqCountry` | string | HQ country |
| `companyStockSymbol` | string | Stock symbol |
| `companyLatestFundingAmount` | number | Latest funding (USD) |
| `companyLatestFundingYear` | number | Latest funding year |
| `companyLatestFundingType` | string | Latest funding round |

#### Details & Timestamps

| Field | Type | Description |
|-------|------|-------------|
| `minYearsExperience` | number | Minimum years of experience |
| `bachelorsDegreeRequirement` | string | Bachelor's degree |
| `degreeFieldsOfStudy` | array | Degree fields |
| `technicalTools` | array | Tools & technologies |
| `licensesOrCertifications` | array | Licenses & certifications |
| `languageRequirements` | array | Languages |
| `securityClearance` | string | Security clearance |
| `isDriverLicenseRequired` | boolean | Driver's licence required |
| `visaSponsorship` | boolean | Visa sponsorship |
| `fairChance` | boolean | Fair-chance employer |
| `physicalLaborIntensity` | string | Physical labour intensity |
| `workplacePhysicalEnvironment` | string | Work environment |
| `onCallRequirement` | string | On-call requirement |

### Tips for Best Results

- **The salary columns are annualised; `salaryPeriodListed` is what the employer wrote, not the unit of those numbers.** A real row reads `salaryMinYearly: 91436.8` beside `salaryMinHourly: 43.96` and `salaryPeriodListed: "Hourly"` — the employer quoted $43.96 an hour and the annual column is that same rate converted, not a second figure. Read the unit off the column name (`...Yearly` / `...Hourly`) and treat `salaryPeriodListed` purely as "how this employer chose to advertise it".
- **Filter on `salaryIsTransparent`, not on a non-empty salary.** Whether pay is published at all depends on jurisdiction and role, so the flag is what tells you a blank amount is a genuine non-disclosure rather than a gap.
- **`requirementsSummary` is a short precis, not the advert.** It runs 71 to 326 characters and summarises what the role asks for. When you need the full posting text, follow `url` to the employer's own application page.
- **One search URL reaches at most 4,620 jobs.** To go past that, run several narrower searches — split by city, seniority, employment type or recency — and put them all in `searchUrls`; a job matching more than one is written once and billed once.
- **Expect tools or licences, rarely both.** `technicalTools` fills up on software roles while `licensesOrCertifications` fills up on clinical and warehouse ones. Treat each as present-when-relevant rather than as a coverage gap, and do not build a required-field check on either.
- **`locationCount` above 1 means `latitude`/`longitude` describes the primary site only.** Multi-site requisitions are routine in retail and logistics — one sampled posting covered 80 locations. Use `cities`, `states` and `countries` for the full footprint.
- **Set the recency filter on the site before you copy the URL.** Running the same filtered search on a schedule and keying on `id` gives you a clean new-postings feed, and because `postedAt` is UTC ISO-8601 it sorts lexically with no date parsing at all.

### Pricing

**From $1.10 per 1,000 results.**

| Results | Price |
|---------|-------|
| 100 | $0.11 |
| 1,000 | $1.10 |
| 10,000 | $11.00 |
| 100,000 | $110.00 |

Those are the rates on Gold and above. Higher-volume plans pay less per result:

| Your Apify plan | Price |
|-----------------|-------|
| No discount | $1.30 |
| Bronze | $1.25 |
| Silver | $1.15 |
| **Gold and above** | **$1.10** |

Per 1,000 results.

A "result" is any job row in the output dataset. When you run several searches at once, a job matching more than one of them is de-duplicated before it reaches the dataset, so you are never charged twice for the same job. Platform fees (compute, storage) are additional and depend on your Apify plan.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

**This is an unofficial scraper. It is not affiliated with, endorsed by, or connected to Hiring.cafe or its operators in any way.** All trademarks belong to their respective owners.

This actor is intended for legitimate market research and analytics. You are responsible for complying with applicable laws and with Hiring.cafe's Terms of Service.

Results may include personal data such as contact details. Treat them accordingly: do
not use them for spam, harassment, or any unlawful purpose, and follow applicable
privacy rules when storing or processing them.

# Actor input Schema

## `searchUrls` (type: `array`):

Hiring.cafe search result URLs. Set your filters on Hiring.cafe, then paste the address bar URL here. Overrides the individual filters below when provided.

## `maxItems` (type: `integer`):

Maximum jobs per search URL (0 = collect everything each search returns). Hiring.cafe pages through at most 4,620 jobs per search, so use several narrower searches to collect more.

## `concurrency` (type: `integer`):

How many requests to run in parallel. Lower this if you see failures.

## `proxyConfiguration` (type: `object`):

Proxy settings for the run.

## Actor input object example

```json
{
  "searchUrls": [],
  "maxItems": 100,
  "concurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `core` (type: `string`):

Core Fields for each job.

## `financial` (type: `string`):

Price & Value for each job.

## `location` (type: `string`):

Location for each job.

## `contact` (type: `string`):

Contacts for each job.

## `meta` (type: `string`):

Details & Timestamps for each job.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/hiringcafe-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/hiringcafe-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call solidcode/hiringcafe-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=solidcode/hiringcafe-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/w1pNCmEctDbSppaYd/builds/A87iEBOyFoufSDI9h/openapi.json
