# Job Search Scraper: 25,500+ Company Career Sites (`richiedc95/company-jobs-search`) Actor

Scrape job postings from 25,500+ company career sites in one search (Greenhouse, Lever, Ashby, Workday and more): a legal alternative to LinkedIn and Indeed job scrapers. Salaries, remote filter, daily alerts. $3.00 per 1,000 jobs.

- **URL**: https://apify.com/richiedc95/company-jobs-search.md
- **Developed by:** [Richie Data](https://apify.com/richiedc95) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 jobs

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Job Search Scraper: 25,500+ Company Career Sites

Type a job title and get **matching open jobs from 25,500+ companies at once**, straight from their official career sites. You do not need a list of companies: the Actor searches its directory of companies that hire on Ashby (3,236), BambooHR (3,732), Breezy HR (348), Greenhouse (4,757), Jobvite (345), Lever (572), Oracle Cloud HCM (1,248), Personio (2,141), Pinpoint (100), Recruitee (1,290), Rippling (1,268), SmartRecruiters (1,297), Teamtailor (1,151), Workable (220), Workday (3,953).

⭐ **Is this Actor useful to you?** A short review on the Reviews tab helps other users find it, and tells us what to build next.

- 🔎 **One search, thousands of career sites**: startups, scale-ups and enterprises in tech, finance, health, retail and more.
- 💰 **Salary ranges parsed into numbers** when the company publishes them.
- 🔔 **Daily job alerts**: save your search as a task, schedule it daily and turn on **Only new jobs**: each run returns just the jobs posted since the last one, straight to Slack, email, Google Sheets or a webhook.
- 📅 **Only fresh jobs**: keep jobs posted in the last day, week or month with **Posted within (days)**.
- 🌍 **Location and remote filters**, experience level, employment type, minimum salary and words in the description.
- 🛂 **Visa sponsorship filter**: keep only jobs whose description says the company sponsors visas (H-1B, work permits). Every job carries a `visaSponsorship` field: true, false or null when the posting does not say.
- 🟧 **Y Combinator filter**: search only YC startups; every YC company's jobs carry its batch (`ycBatch`, e.g. W24).
- 🧹 **Merge duplicate titles**: one job per opening even when a company posts it once per city.
- 🎯 **Companies output for lead generation**: switch **Output** to *Companies* and get one row per company hiring for your role, with its careers page, number of matching and remote jobs, titles, locations, salary range and newest posting date.
- 🔔 **Monitoring mode**: schedule it daily and receive only jobs you have not seen before.
- ⚡ **Fresh and fast**: job titles are indexed daily, then every matching job is fetched live from the company's career site, so you get current details and closed jobs drop out.
- 💵 **$3.00 per 1,000 jobs** plus a small fee per run that covers scanning the directory.

### Who uses it

- **Job seekers and career coaches** building a personal job alert for a role.
- **Job boards and newsletters** that publish curated openings (remote jobs, AI jobs, design jobs...).
- **Recruiters and sourcers** mapping which companies hire for a role right now.
- **Sales teams** looking for companies that are hiring for a function they sell to.
- **Analysts** tracking hiring demand and salaries by role.

### How to use it

1. Enter one or more **job title keywords** (for example `data engineer`, `machine learning`, `account executive`).
2. Optionally narrow it down: **locations** (or locations to exclude), **remote only**, **posted within N days**, **experience level** (intern, junior, senior...), **employment type**, **minimum salary**, **words in the description**, **visa sponsorship**, or only some companies or ATS.
3. Click **Start**. For a daily alert, turn on **Only new jobs** and add a schedule.

#### Example input

```json
{
    "keywords": ["data engineer", "analytics engineer"],
    "locations": ["Remote", "New York"],
    "excludeKeywords": ["intern"],
    "postedWithinDays": 7,
    "onlyNewJobs": true
}
```

### Output

Each job has the same clean schema as our other job scrapers: company, title, department, location, workplace type (remote/hybrid/on-site), employment type, seniority, salary min/max/currency/period, visa sponsorship, posting date, URL and description. The `SUMMARY` record lists how many companies were scanned and which ones matched.

### Pricing

**$3.00 per 1,000 jobs** saved plus about $0.01 per run for scanning the directory. Use **Max jobs** to cap the cost of a run. In the **Companies** output (lead lists), each hiring company costs $0.01 more, because one record bundles every matching role, the careers page and the salary range.

### FAQ

**Is this an alternative to a LinkedIn or Indeed jobs scraper?** Yes, and a safer one. Most jobs you see on LinkedIn and Indeed are first published on the employer's own career site (Greenhouse, Lever, Workday and the other ATS this Actor reads), so you get the same openings from the original source, usually earlier and with the full description, salary range and direct apply link. No LinkedIn or Indeed account, cookies, proxies or login are needed, nothing is scraped from those sites, and there are no blocked runs or duplicated reposts. This Actor is not affiliated with LinkedIn or Indeed.

**How does it find companies?** It keeps a directory of companies with an active public job board on each supported ATS, built from public sources and refreshed regularly (current directory: 25,658 companies).

**How fresh are the results?** Job titles across the directory are indexed every day, so the search runs in minutes instead of hours. Then every matching job is fetched **live from the company's own career site** at run time: you get the current title, salary, description and apply link, and jobs that were closed since the last index are simply not returned. For brand-new jobs, schedule the Actor daily with **Only new jobs** turned on.

**How long does a run take?** A search across the full directory usually finishes in about 3 minutes; most of that time goes to downloading the details of the matching jobs. Use **Max jobs in total** for quick previews.

**My target company is missing.** Use the [Career Site Jobs Scraper](https://apify.com/richiedc95/career-site-jobs-scraper) with the company's careers URL, or open an issue and we will add it to the directory.

**Is it legal?** It reads public job postings that companies publish for anyone to see, through each ATS's public job board endpoints. No login and no personal data.

### Supported ATS

| Supported ATS | | |
|---|---|---|
| Greenhouse | Lever | Ashby |
| Workday | SmartRecruiters | Workable |
| Recruitee | Personio | Teamtailor |
| BambooHR | Breezy HR | Rippling |
| Oracle Cloud HCM | Pinpoint | Jobvite |

### Use it from your code, AI agents and automations

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("richiedc95/company-jobs-search").call(run_input={
    "keywords": [
        "data engineer"
    ],
    "locations": [
        "Remote"
    ],
    "postedWithinDays": 1,
    "onlyNewJobs": True
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript**

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('richiedc95/company-jobs-search').call({
    "keywords": [
        "data engineer"
    ],
    "locations": [
        "Remote"
    ],
    "postedWithinDays": 1,
    "onlyNewJobs": true
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

- 🤖 **AI agents (MCP)**: add the [Apify MCP server](https://mcp.apify.com) to Claude, ChatGPT, Cursor or any MCP client and this Actor becomes a tool your agent can call.
- 🔗 **No-code (n8n, Make, Zapier)**: one HTTP request runs the Actor and returns the results, so any automation tool can use it. In n8n, add an *HTTP Request* node with method `POST`, URL `https://api.apify.com/v2/acts/richiedc95~company-jobs-search/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>` and the JSON input above as the body, then send the items to Slack, Google Sheets, email or a CRM. Put a *Schedule* node in front for daily alerts. Make and Zapier have official Apify apps (*Run an Actor* → *Get dataset items*). Ready-made n8n workflows (import from URL) and a step-by-step guide: [n8n / Make / Zapier examples](https://github.com/richiedc95/job-search-mcp/blob/main/examples/README.md).
- 📥 **Exports**: download every run as JSON, CSV, Excel, XML or RSS, or read it through the [Apify API](https://docs.apify.com/api/v2).

### Get a fresh feed automatically (job boards, dashboards, alerts)

1. Click **Save as a new task** with your input (turn on the monitoring option if the Actor has one, so each run returns only new jobs).
2. Add a **schedule** to the task (hourly, daily or weekly) under **Schedules**.
3. Read the latest results from one stable URL, in the format your tool expects:

```text
https://api.apify.com/v2/actor-tasks/<TASK_ID>/runs/last/dataset/items?token=<YOUR_APIFY_TOKEN>&status=SUCCEEDED&format=csv
```

Use `format=json`, `csv`, `xlsx`, `xml` or `rss`. Job-board plugins and spreadsheets can import that URL directly.

### Related Actors

- [Career Site Jobs Scraper](https://apify.com/richiedc95/career-site-jobs-scraper)
- [Greenhouse Jobs Scraper](https://apify.com/richiedc95/greenhouse-jobs-scraper)
- [Lever Jobs Scraper](https://apify.com/richiedc95/lever-jobs-scraper)
- [Ashby Jobs Scraper](https://apify.com/richiedc95/ashby-jobs-scraper)
- [Workday Jobs Scraper](https://apify.com/richiedc95/workday-jobs-scraper)

Found a bug or need a feature? Open an issue on the Issues tab and we will usually answer within a day.

# Actor input Schema

## `keywords` (type: `array`):

Jobs whose title contains at least one of these words or phrases (case-insensitive), e.g. "data engineer", "product designer".

## `excludeKeywords` (type: `array`):

Skip jobs whose title contains any of these words, e.g. "senior", "intern".

## `locations` (type: `array`):

Keep only jobs whose location contains one of these texts, e.g. "Remote", "London", "Berlin".

## `remoteOnly` (type: `boolean`):

Keep only jobs detected as fully remote.

## `postedWithinDays` (type: `integer`):

Keep only jobs posted in the last N days. 0 = no limit.

## `excludeLocations` (type: `array`):

Skip jobs whose location contains any of these texts, e.g. "India", "Remote".

## `seniorityLevels` (type: `array`):

Keep only these levels, detected from the job title (e.g. "Junior", "Graduate", "Senior", "Head of"). "Mid" is any title without a level word. Leave empty for all.

## `employmentTypes` (type: `array`):

Keep only these employment types. Jobs that do not state a type are skipped when this is set.

## `minSalary` (type: `integer`):

Keep only jobs that publish a pay range whose top reaches at least this yearly amount, in the job's own currency (hourly and monthly pay are converted to yearly). Jobs without a published salary are skipped when this is set. 0 = no filter.

## `descriptionKeywords` (type: `array`):

Keep only jobs whose title or description contains at least one of these words, e.g. "Python", "visa sponsorship", "Spanish".

## `visaSponsorship` (type: `boolean`):

Keep only jobs whose description says visa sponsorship is offered (e.g. "we sponsor H-1B visas"). Every job also gets a visaSponsorship field: true, false (says it does not sponsor) or null (does not say).

## `ycOnly` (type: `boolean`):

Search only the ~950 Y Combinator startups in the directory. Every job from a YC company also carries its batch in ycBatch (e.g. W24).

## `companyNames` (type: `array`):

Search only companies whose name contains one of these texts, e.g. "Stripe", "Bank". Leave empty to search the whole directory.

## `excludeCompanyNames` (type: `array`):

Skip companies whose name contains any of these texts (e.g. staffing agencies or your own company).

## `atsList` (type: `array`):

Limit the search to some ATS. Leave empty to search all of them.

## `onlyNewJobs` (type: `boolean`):

Return only jobs not returned in previous runs. Schedule it daily for a job alert feed.

## `descriptionFormat` (type: `string`):

Format of the job description field.

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

Stop after saving this many jobs. 0 = no limit.

## `outputMode` (type: `string`):

Companies gives one record per company with matching jobs: careers page, how many matching and remote jobs, titles, locations, salary range and newest posting date. Max jobs then counts companies.

## `mergeDuplicates` (type: `boolean`):

Companies often post the same opening once per city. Keep one job per company and title, with every location in locations and the merged postings in duplicates.

## `maxJobsPerCompany` (type: `integer`):

Keep at most this many jobs from each company, for a more varied list. 0 = no limit.

## `maxCompanies` (type: `integer`):

For testing: scan only the first N companies of the directory. 0 = all.

## Actor input object example

```json
{
  "keywords": [
    "data engineer"
  ],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "minSalary": 0,
  "visaSponsorship": false,
  "ycOnly": false,
  "onlyNewJobs": false,
  "descriptionFormat": "text",
  "maxItems": 100,
  "outputMode": "jobs",
  "mergeDuplicates": false,
  "maxJobsPerCompany": 0,
  "maxCompanies": 0
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "keywords": [
        "data engineer"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("richiedc95/company-jobs-search").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 = {
    "keywords": ["data engineer"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("richiedc95/company-jobs-search").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "data engineer"
  ],
  "maxItems": 100
}' |
apify call richiedc95/company-jobs-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,richiedc95/company-jobs-search"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6UgknsMlMDAewA3JS/builds/XacfQalNxy8GJu1lp/openapi.json
