# Career Page Jobs - Greenhouse, Lever, Ashby, Workable (`onescriptfix/career-page-jobs`) Actor

Open jobs from Greenhouse, Lever, Ashby, Workable, Recruitee and Personio boards in one table. Paste career-page links or a company's own careers page; filter by title, location, remote and date. Published salaries included.

- **URL**: https://apify.com/onescriptfix/career-page-jobs.md
- **Developed by:** [One Script Fix](https://apify.com/onescriptfix) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.95 / 1,000 job listings

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

## Career Page Jobs Scraper - Greenhouse, Lever, Ashby, Workable, Recruitee, Personio

Get every open job from a list of companies in one table, whichever applicant tracking system each company uses. Paste
career-page links such as `boards.greenhouse.io/figma` or `jobs.ashbyhq.com/linear`, or just a company's own careers
page, and the actor finds the right job board and returns clean, comparable rows.

Useful for job boards and newsletters, sales teams watching who is hiring, recruiters tracking competitors, and anyone
who wants job data without running six different scrapers.

### Supported systems

| System | Example link |
| --- | --- |
| Greenhouse | `https://boards.greenhouse.io/figma` or `https://job-boards.greenhouse.io/figma` |
| Lever | `https://jobs.lever.co/spotify` (EU boards too) |
| Ashby | `https://jobs.ashbyhq.com/linear` |
| Workable | `https://apply.workable.com/<company>` |
| Recruitee | `https://<company>.recruitee.com` |
| Personio | `https://<company>.jobs.personio.de` or `.com` |

You can also give a company's own careers page (`https://www.example.com/careers`). The actor opens it once, looks for a
link or embed from one of the systems above and reads that board. SmartRecruiters is not supported: its robots.txt asks
crawlers to stay away, and the actor respects that.

### Quick start

```json
{
  "companies": [
    "https://jobs.ashbyhq.com/linear",
    "https://boards.greenhouse.io/figma",
    "https://jobs.lever.co/spotify"
  ],
  "titleContains": "engineer"
}
```

### Input

| Field | Default | What it does |
| --- | --- | --- |
| `companies` | required | Up to 50 entries: career-board links, careers pages, or objects like `{"slug": "figma", "ats": "greenhouse"}`. |
| `titleContains` | empty | Keep jobs whose title contains this text (not case sensitive). |
| `locationContains` | empty | Keep jobs whose location contains this text. |
| `department` | empty | Keep jobs whose department contains this text. |
| `postedAfter` | empty | Keep jobs posted after this date, such as `2026-09-01`. Jobs without a date are left out. |
| `remoteOnly` | `false` | Keep only jobs the board marks as remote. |
| `maxJobsPerCompany` | `1000` | Cap per company. |
| `maxItems` | `10000` | Cap for the whole run. |

Filters run before anything is saved, so you only pay for the jobs you keep.

### Output

One row per job. The field names are the same for every system:

```json
{
  "company": "linear",
  "ats": "ashby",
  "jobId": "d3bc1ced-3ce4-4086-a050-555055dbb1ff",
  "title": "Senior / Staff Fullstack Engineer",
  "department": "Product",
  "team": "Engineering",
  "location": "Europe",
  "country": "European Union",
  "isRemote": true,
  "workplaceType": "remote",
  "employmentType": "FullTime",
  "createdAt": "2021-04-27T20:13:45.158000Z",
  "sourceUrl": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff",
  "applyUrl": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff/application",
  "description": "At Linear, we're building the product development system for teams and agents. ...",
  "salaryMin": null,
  "salaryMax": null,
  "salaryCurrency": null,
  "salaryInterval": null
}
```

Descriptions are plain text with paragraphs kept. Salary fields are filled only when the company publishes a structured
pay range (common on Ashby and Lever); the actor never guesses pay from the description text. Each row also carries a
stable `sourceId`, so you can spot new jobs between runs.

Companies that could not be read (a wrong slug, a removed board, a careers page with no supported system) are listed in
the run's `OUTPUT` record with the reason. They never appear as dataset rows and cost nothing.

### Pricing

$1.50 per 1,000 jobs on the Free plan, $1.35 on Starter, $1.15 on Scale and $0.95 on Business. No start fee; filtered-out
and duplicate jobs are free.

### FAQ

**Is this the same data as the careers page?** Yes. Every system here has a public job feed that powers the company's own
careers page, and the actor reads that feed. In our checks the counts matched the careers pages.

**How fast is it?** Requests to each site are spaced out (about one per second) to stay polite. A few hundred jobs take
well under a minute.

**Can I run it every day?** Yes. Schedule it and compare `sourceId` values to find new and closed jobs.

**Does it log in anywhere?** No. Only public job boards are read.

# Actor input Schema

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

Up to 50 job boards. Paste a Greenhouse, Lever, Ashby, Workable, Recruitee or Personio board URL, or a company's own careers page and the actor finds the board it embeds.

## `titleContains` (type: `string`):

Keep only jobs whose title contains this text, for example "engineer". Not case sensitive.

## `locationContains` (type: `string`):

Keep only jobs whose location contains this text, for example "London" or "Remote".

## `department` (type: `string`):

Keep only jobs whose department or team contains this text.

## `postedAfter` (type: `string`):

Date in YYYY-MM-DD format. Jobs posted on or before this date, and jobs without a posting date, are left out.

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

Keep only jobs the board marks as remote.

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

Stop collecting a board after this many jobs. Leave empty for 1,000.

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

Stop the run after this many jobs across all boards. Leave empty for 10,000.

## `pageSize` (type: `integer`):

Jobs requested per page on boards that paginate. Leave empty for 100.

## `maxPages` (type: `integer`):

Safety limit for paginated boards. Leave empty for 100.

## `requestDelaySeconds` (type: `number`):

Minimum wait between two requests to the same site. Leave empty for 1.2 seconds.

## Actor input object example

```json
{
  "companies": [
    "https://jobs.lever.co/spotify"
  ],
  "maxJobsPerCompany": 1000,
  "maxItems": 10000,
  "pageSize": 100,
  "maxPages": 100
}
```

# Actor output Schema

## `results` (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 = {
    "companies": [
        "https://jobs.lever.co/spotify"
    ],
    "maxJobsPerCompany": 1000,
    "maxItems": 10000,
    "pageSize": 100,
    "maxPages": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("onescriptfix/career-page-jobs").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://jobs.lever.co/spotify"],
    "maxJobsPerCompany": 1000,
    "maxItems": 10000,
    "pageSize": 100,
    "maxPages": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("onescriptfix/career-page-jobs").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://jobs.lever.co/spotify"
  ],
  "maxJobsPerCompany": 1000,
  "maxItems": 10000,
  "pageSize": 100,
  "maxPages": 100
}' |
apify call onescriptfix/career-page-jobs --silent --output-dataset

```

## MCP server setup

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

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/ab1BBtusi4u9PTjcr/builds/MwPqtSU9RwonAj0qA/openapi.json
