# Company Jobs Scraper – Workday, Greenhouse & Lever (`quinic_resin/company-jobs-tracker`) Actor

Get every open job from company career sites – Workday, Greenhouse, Lever, Ashby, SmartRecruiters, Workable, Recruitee, Personio, Breezy and BambooHR. Paste websites or job-board links; get clean JSON with salaries, locations and remote status, plus new-job alerts on a schedule.

- **URL**: https://apify.com/quinic_resin/company-jobs-tracker.md
- **Developed by:** [JP](https://apify.com/quinic_resin) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Company Jobs Scraper – Workday, Greenhouse, Lever, Ashby & 6 more

Get **every open job from any company's own career site** in one clean format, plus **alerts for new postings**. Paste company websites or job-board links; the Actor finds each company's job board and reads it through the same public endpoints its careers page uses. No login, no browser, no LinkedIn.

**Supported job boards:** Workday · Greenhouse · Lever · Ashby · SmartRecruiters · Workable · Recruitee · Personio · Breezy HR · BambooHR

### What people use it for

- **Sales and account-based marketing: hiring signals.** Track your target accounts. A company that just opened 5 data-engineering roles, or a job that mentions "migrating to Snowflake", is a buying signal. Schedule a daily run and pipe new jobs into Slack, your CRM or Google Sheets.
- **Recruiters and staffing agencies.** Find companies hiring for the roles you place, the day they post, straight from the source, often before the listing reaches LinkedIn or Indeed.
- **Job boards and aggregators.** Fresh, de-duplicated postings from employers' own systems, with full descriptions, apply links and pay ranges.
- **Salary and labor-market research.** Pay ranges are extracted from structured fields and from description text (pay-transparency laws in CA, CO, NY, WA and the EU mean many postings include them). You get min, max, currency and period.
- **Job seekers.** Get only the new roles at your 30 dream companies every morning.

### What you get for each job

```json
{
  "id": "greenhouse:acme:4001",
  "company": "Acme",
  "title": "Senior Frontend Engineer",
  "department": "Engineering",
  "location": "San Francisco, CA",
  "locations": ["San Francisco, CA"],
  "country": "US",
  "workplaceType": "hybrid",
  "employmentType": "full-time",
  "seniority": "senior",
  "salaryMin": 150000,
  "salaryMax": 190000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "salaryText": "$150,000 - $190,000 per year",
  "postedAt": "2026-09-20T13:00:00.000Z",
  "url": "https://job-boards.greenhouse.io/acme/jobs/4001",
  "applyUrl": "https://job-boards.greenhouse.io/acme/jobs/4001",
  "requisitionId": "ENG-101",
  "descriptionText": "About the role\n\nBuild delightful UI with React & TypeScript…",
  "ats": "greenhouse",
  "isNew": true,
  "firstSeenAt": "2026-10-04T08:00:00.000Z",
  "scrapedAt": "2026-10-04T08:00:00.000Z"
}
```

Every platform is mapped to this same schema. `workplaceType` is `remote`, `hybrid`, `onsite` or empty when the board doesn't say. `seniority` (intern, entry, mid, senior, staff, manager, director, executive) is inferred from the title. `isNew` and `firstSeenAt` appear when you use a monitor name.

You can download results as JSON, CSV, Excel or HTML, or read them through the API. Each run also saves:

| Record | What's in it |
|---|---|
| `COMPANIES` | One entry per company with hiring signals: open jobs, jobs posted in the last 7 and 30 days, new and closed jobs, remote and hybrid share, share of jobs showing salary, top departments and locations, seniority mix |
| `CLOSED_JOBS` | Jobs that disappeared since the previous run of the same monitor (title, link, first seen) |
| `REPORT` | A ready-to-share HTML table of all companies |
| `OUTPUT` | Run summary: boards found, inputs that couldn't be matched and why, failed boards, request stats |

### How to use it

**1. Jobs at a list of companies.** Paste anything that identifies the company:

```json
{
  "companies": [
    "stripe.com",
    "https://boards.greenhouse.io/figma",
    "https://jobs.ashbyhq.com/ramp",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "Notion"
  ],
  "titleKeywords": ["engineer", "designer"],
  "locations": ["US", "Remote"]
}
```

Websites are scanned for a link to a supported job board. If none is found, the company name is tried on each board directly. Workday boards can only be found from a link, so paste the Workday URL for big enterprises.

**2. Daily new-job alerts.** Add a monitor name and schedule the Actor (Schedules → daily):

```json
{
  "companies": ["datadoghq.com", "snowflake.com", "https://jobs.lever.co/palantir"],
  "titleKeywords": ["account executive", "solutions engineer"],
  "monitorId": "enterprise-accounts"
}
```

The first run returns current jobs (or set `firstRunBaseline: true` to just record them). Every later run returns **only jobs that are new since the previous run** and lists closed jobs in `CLOSED_JOBS`. Connect the dataset to Slack, email, Google Sheets, Zapier or Make under **Integrations** to get a message for each new job.

**3. Hiring signals per company, no job rows.** Set `output` to `companies` to get one row per company:

```json
{
  "companies": ["https://boards.greenhouse.io/figma", "https://jobs.ashbyhq.com/ramp"],
  "descriptionKeywords": ["Snowflake", "dbt"],
  "output": "companies"
}
```

### Filters

All filters are optional:

- `titleKeywords` and `excludeTitleKeywords` match whole words.
- `locations` accepts cities, states, countries and two-letter codes.
- `workplaceTypes`
- `employmentTypes`
- `departments` matches the job title when a board has no departments.
- `descriptionKeywords`
- `postedWithinDays`
- `maxJobsPerCompany` and `maxJobs`. In monitor mode, jobs left out by these caps are recorded as seen.

### Pricing

You pay per result. There are no monthly fees, and Apify platform usage is included.

| Event | Price |
|---|---|
| Job returned | **$1.00 per 1,000 jobs** |
| Company job board scanned | **$1.00 per 1,000 companies** |

Examples:

- 50 companies and 2,000 jobs cost about **$2.05**.
- A daily monitor of 300 accounts returning about 40 new jobs a day costs about **$0.34 a day**.

Set a maximum cost per run in the run options. The Actor stops cleanly at your limit and never charges past it.

### Good to know

- **Data source.** The Actor only reads public job postings, using the endpoints each company's own careers page uses. It needs no login and collects no personal data about candidates or employees. You're responsible for how you use the data.
- **Companies that can't be found.** They may use a platform not covered here, such as iCIMS, Taleo, SuccessFactors, Jobvite or a fully custom site. The `OUTPUT` record lists every input that couldn't be matched. If you know the job-board URL, paste it directly.
- **Very large Workday boards.** Workday never shows more than 2,000 jobs per listing. For bigger boards, give `titleKeywords` and the Actor uses Workday's own search. Closed-job detection is turned off for boards that can't be listed completely.
- **Speed.** Most boards return all jobs in one request. Workday, SmartRecruiters and BambooHR need one extra request per job for the full description. Turn off `includeDescription` for faster, smaller runs.
- **Proxy.** Not needed for most boards. Enable it only if a career site blocks requests.

### Support

Open an issue on the Actor's **Issues** tab with the run link and the company you expected to work.

# Changelog

This Actor's version history is a separate document: https://apify.com/quinic_resin/company-jobs-tracker/changelog.md

# Actor input Schema

## `companies` (type: `array`):

One per line. Any of: a company website (<code>stripe.com</code>), a careers page, a job-board link (<code>https://boards.greenhouse.io/figma</code>, <code>https://jobs.lever.co/palantir</code>, <code>https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite</code>), a company name (<code>Notion</code>), or <code>ats:board</code> shorthand (<code>ashby:ramp</code>, <code>workday:nvidia.wd5/NVIDIAExternalCareerSite</code>).

## `companiesDatasetId` (type: `string`):

Pick a dataset (for example the output of another Actor) that contains company websites, domains or job-board URLs. Combined with the list above.

## `companiesDatasetField` (type: `string`):

Column to read from the dataset. If it is empty on a row, <code>website</code>, <code>domain</code>, <code>companyWebsite</code> and <code>url</code> are tried.

## `titleKeywords` (type: `array`):

Keep jobs whose title contains at least one of these words (case-insensitive, whole words). Leave empty for all jobs. Example: <code>engineer</code>, <code>designer</code>, <code>account executive</code>.

## `excludeTitleKeywords` (type: `array`):

Drop jobs whose title contains any of these words. Example: <code>intern</code>, <code>principal</code>.

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

Keep jobs in any of these places. Matches cities, states, countries and country codes, e.g. <code>New York</code>, <code>Germany</code>, <code>US</code>, <code>Remote</code>. Jobs with no location listed are excluded when this filter is set.

## `workplaceTypes` (type: `array`):

Keep only these workplace types. Jobs that don't say remote or hybrid count as on-site.

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

Keep only these employment types. Jobs that don't state a type are kept.

## `departments` (type: `array`):

Keep jobs whose department or team contains any of these words, e.g. <code>Engineering</code>, <code>Sales</code>.

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

Keep jobs whose title or description mentions at least one of these terms, e.g. a technology (<code>Snowflake</code>, <code>Salesforce</code>, <code>Kubernetes</code>). Useful for finding companies that use a tool.

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

Keep jobs posted in the last N days. 0 = any date. Jobs without a posting date are excluded when this is set.

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

Newest jobs first. 0 = no limit.

## `maxJobs` (type: `integer`):

Stop after this many jobs across all companies. 0 = no limit. You can also cap spend with the run's maximum cost setting.

## `output` (type: `string`):

<b>Jobs</b>: one row per job. <b>Companies</b>: one row per company with hiring signals (open roles, new and closed roles, top departments and locations, remote share) – no job rows.

## `includeDescription` (type: `boolean`):

Adds the full description as plain text. Turn off for smaller, faster results (Workday, SmartRecruiters and BambooHR then skip one request per job).

## `includeDescriptionHtml` (type: `boolean`):

Adds the original description HTML.

## `monitorId` (type: `string`):

Give this search a name, e.g. <code>target-accounts</code>, and schedule the Actor. Each run then returns only jobs that are new since the previous run with the same name, and lists closed jobs in the <code>CLOSED_JOBS</code> record. Leave empty to return all current jobs every time.

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

With a monitor name, return only jobs not seen in earlier runs. Turn off to return all matching jobs and still get new and closed counts.

## `firstRunBaseline` (type: `boolean`):

With a monitor name, the first run saves the current jobs as the baseline and returns nothing, so later runs alert only on truly new postings.

## `scanWebsites` (type: `boolean`):

For website inputs, look at the homepage and careers pages for a supported job board link.

## `guessBoardNames` (type: `boolean`):

If no link is found, try the company name on each job board (e.g. <code>stripe</code> on Greenhouse, Lever, Ashby…). Workday boards can only be found through a link.

## `maxConcurrency` (type: `integer`):

Higher is faster. Requests to each job-board host are rate-limited regardless.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each request.

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

Not needed for most boards – these are public job-board endpoints. Use a proxy only if a career site blocks requests.

## Actor input object example

```json
{
  "companies": [
    "stripe.com",
    "https://boards.greenhouse.io/figma",
    "https://jobs.ashbyhq.com/ramp",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "lever:palantir"
  ],
  "companiesDatasetField": "website",
  "postedWithinDays": 0,
  "maxJobsPerCompany": 0,
  "maxJobs": 0,
  "output": "jobs",
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "onlyNewJobs": true,
  "firstRunBaseline": false,
  "scanWebsites": true,
  "guessBoardNames": true,
  "maxConcurrency": 8,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items: one row per job, or one row per company when Output = Companies. Add \&format=csv or \&format=xlsx to download a spreadsheet.

## `report` (type: `string`):

Shareable HTML table of every company scanned: open, new and closed jobs, remote share, top departments and locations.

## `companies` (type: `string`):

JSON array with one entry per company: open jobs, jobs posted in the last 7 and 30 days, new and closed jobs, remote and hybrid share, salary disclosure share, top departments and locations, seniority mix.

## `closedJobs` (type: `string`):

JSON array of jobs that disappeared since the previous run with the same monitor name. Empty when no monitor name is set.

## `runSummary` (type: `string`):

Boards found and scanned, jobs delivered, new and closed counts, inputs that could not be matched to a job board, failed boards and request statistics.

# 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 = {
    "companies": [
        "https://boards.greenhouse.io/figma",
        "https://jobs.ashbyhq.com/ramp",
        "https://jobs.lever.co/palantir"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("quinic_resin/company-jobs-tracker").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 = { "companies": [
        "https://boards.greenhouse.io/figma",
        "https://jobs.ashbyhq.com/ramp",
        "https://jobs.lever.co/palantir",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("quinic_resin/company-jobs-tracker").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 '{
  "companies": [
    "https://boards.greenhouse.io/figma",
    "https://jobs.ashbyhq.com/ramp",
    "https://jobs.lever.co/palantir"
  ]
}' |
apify call quinic_resin/company-jobs-tracker --silent --output-dataset

```

## MCP server setup

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

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/XnjynniXtgFYVWZDv/builds/7SzQjVFAFsXYNOjBQ/openapi.json
