# Job Scraper — Greenhouse, Lever & Ashby API (`dev_web_col/ats-job-index`) Actor

Job board API over 1,014 company career pages on Greenhouse, Lever, Ashby and Workable. Recruiting and hiring data without knowing which companies to query.

- **URL**: https://apify.com/dev\_web\_col/ats-job-index.md
- **Developed by:** [Diseño Web de Colombia](https://apify.com/dev_web_col) (community)
- **Categories:** Jobs, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job returneds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## ATS Job Scraper API — Greenhouse, Lever & Ashby Jobs

**Search live jobs across a thousand company career pages — without knowing which companies to query.**

### Call it as an API

One keyword in, live jobs out from a thousand company career pages — in a single HTTP call, no polling and no company list to maintain.

```bash
curl -X POST "https://api.apify.com/v2/acts/dev_web_col~ats-job-index/run-sync-get-dataset-items?token=YOUR_TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{"searchKeyword": "backend engineer", "location": "United States"}'
```

```python
import requests

r = requests.post(
    "https://api.apify.com/v2/acts/dev_web_col~ats-job-index/run-sync-get-dataset-items",
    params={"token": "YOUR_TOKEN"},
    json={"searchKeyword": "backend engineer", "location": "United States"},
)
job = r.json()[0]
print(job["title"], job["companyName"], job["applyUrl"])
```

Single-entity lookup, for calling once per company from your own code:

```bash
curl -X POST "https://api.apify.com/v2/acts/dev_web_col~ats-job-index/run-sync-get-dataset-items?token=YOUR_TOKEN" \\
  -H "Content-Type: application/json" -d '{"companyToken": "greenhouse:stripe"}'
```

`run-sync-get-dataset-items` waits for the run and returns the rows in the same
response. Your token is on the [Integrations page](https://console.apify.com/account/integrations).

### What is the ATS Job Scraper?

This Actor reads jobs straight from the applicant tracking systems companies actually post on: Greenhouse, Lever, Ashby and Workable. These are the same public JSON feeds that power a company's own careers page.

Every other ATS scraper makes you bring your own list of board tokens. If you already knew that Stripe is `greenhouse:stripe` and Ramp is `ashby:ramp`, you probably would not need a scraper. This one ships with a **pre-built, validated company-to-ATS index of 1,014 companies and roughly 24,700 live jobs**, so you can just ask for "backend engineer, remote, posted this week".

### Why this instead of a LinkedIn or Indeed scraper

These jobs come from the company's own system, not from an aggregator:

- **Earlier.** Roles appear here before they are syndicated to job boards, and many never get syndicated at all.
- **Cleaner.** No recruiter spam, no duplicate reposts, no expired listings sitting around.
- **No anti-bot fight.** Greenhouse, Lever, Ashby and Workable publish these as public JSON endpoints so companies can embed boards on their own sites. There is no login wall to get around, which is why runs are fast and reliable.
- **Salary included** wherever the ATS publishes it. Ashby exposes compensation ranges for free.

### What you can use it for

| What you want | How to ask for it |
|---|---|
| **Job board API** — a clean feed for your product | `searchKeyword` + `location`, no company list needed |
| **Recruiting research** — who hires for this skill | `searchKeyword` across the bundled index |
| **Career page monitoring for one company** | `companyToken: "greenhouse:stripe"` |
| **Hiring data for sales** — accounts with budget | Count roles per company |
| **Salary data** | Read `compensationText`; Ashby publishes ranges |
| **Remote job feeds** | `remoteOnly: true` |
| **Department-level tracking** | `department: "engineering"` |
| **Fresh postings only** | `postedSince: 7` for the last week |

Typical jobs: powering a **job board**, **recruiting** research, **career page**
monitoring, and **applicant tracking** system data collection.

### What data you get

Job title, company, department, location, remote flag, employment type, compensation text where published, posting date, the direct apply URL, and the full job description. Every row is keyed by `ats:companyToken:externalId` so reruns deduplicate cleanly.

### Input

Every field is optional unless marked required.

| Field | Type | Description |
|---|---|---|
| `searchKeyword` | string | Filter by job title, e.g. "backend engineer", "product designer", "account executive". Leave empty to get every job. |
| `searchScope` | string | Job title only is precise. Adding the description finds more, but also matches jobs that merely mention the keyword. |
| `location` | string | Free text match against the job location, e.g. "New York", "London", "Germany". |
| `remoteOnly` | boolean | Keep only jobs the company flags as remote. |
| `department` | string | Free text match against the department or team, e.g. "Engineering", "Sales". |
| `postedSince` | integer | Only jobs published within this many days. Leave empty for no date limit. Jobs without a publish date are excluded when this is set. |
| `atsPlatforms` | array | Which applicant tracking systems to search. Leave empty to search all of them. |
| `companyTokens` | array | Only if you want specific companies instead of the built-in index. Accepts "greenhouse:stripe" or a job board URL like https://jobs.lever.co/ro |
| `maxCompanies` | integer | Higher means broader coverage and a slower run. Companies with the most open roles are queried first. |
| `maxResults` | integer | Caps how many jobs land in the dataset. You are charged per job returned. |
| `previewMode` | boolean | ON by default so you can try the actor for the price of a single run start. No per-result charges apply. Turn it OFF for a full run. |

#### Input sample

```json
{
  "searchKeyword": "backend engineer",
  "postedSince": 7,
  "companyTokens": [
    "greenhouse:stripe",
    "lever:ro",
    "ashby:ramp"
  ]
}
```

### Output sample

One real row from an actual run:

```json
{
  "id": "greenhouse:agency:4661538101",
  "ats": "greenhouse",
  "companyToken": "agency",
  "companyName": "Meridial",
  "externalId": "4661538101",
  "title": "Backend Engineering Specialist - Freelance AI Trainer Project",
  "department": "Engineering & Technology",
  "location": "United States of America",
  "isRemote": false,
  "employmentType": null,
  "compensationText": null,
  "postedAt": "2025-08-25T19:51:35.000Z",
  "applyUrl": "https://job-boards.eu.greenhouse.io/agency/jobs/4661538101",
  "descriptionText": "Are you an experienced Backend Engineer eager to shape the future of AI? Large-scale language models are evolving rapidly, moving beyond simple chatbots into powerful engines of research, learning, and applied problem..."
}
```

### Who uses this

- **Job seekers and career tools** — reach postings before they hit the big boards
- **Recruiters** — see who is hiring for a role, across a thousand companies at once
- **Sales teams** — hiring is the strongest buying signal there is
- **Market researchers** — headcount plans by department and location
- **Anyone building a job board** who needs a clean, deduplicated feed

### Honest limits

These are real and none of them is fixable by any tool. They are here so you know what you are buying before you run it.

- **The index covers 1,014 companies**, weighted toward technology and startups. It is large but not the whole market. You can also pass your own board tokens directly.
- **Only these four platforms.** Companies on Workday, SmartRecruiters or a custom system are not covered — their board addresses are not discoverable in the same way.
- **Salary is only present where the ATS publishes it**, which in practice mostly means Ashby.
- **Workable rate-limits harder than the others** and is queried more slowly as a result.
- **Preview mode returns at most 20 rows** and does not charge per result, so you can check the shape of the data before a real run.

### FAQ

#### Do I need to know which companies to search?

No, and that is the whole point. The bundled index maps 1,014 companies to their job board, so a keyword and a location are enough. If you do have specific companies in mind, pass their tokens in `companyTokens` instead.

#### What is a company token?

The identifier a company uses on its ATS, in the form `platform:token` — for example `greenhouse:stripe`, `lever:ro` or `ashby:ramp`. You can read it off the company's job board URL.

#### How fresh are the jobs?

The jobs themselves are fetched live on every run, straight from the ATS, so they are as current as the company's own careers page. The bundled index of which company uses which platform is refreshed periodically.

#### Why do I get fewer results than I expected?

By default the keyword is matched against the job title only. Searching descriptions too inflates results with false positives — a "Talent Lead" posting that merely mentions backend engineering. Use `searchScope` to widen it deliberately.

#### Can I track changes over time instead of dumping everything?

Yes, use the ATS Job Monitor Actor. It runs the same sources but returns only what changed since your last run: new roles, closed roles and edits.

#### Do I need an account or an API key for the source?

No. This Actor only reads public pages and public endpoints, the same ones any
logged-out visitor sees. You never give it credentials, and nothing is done on
your behalf.

#### Is it legal to scrape this data?

Scraping publicly available information is broadly accepted as legal, and this
Actor only ever touches pages that require no login. That said, what you may do
with the data afterwards is a separate question — personal data in particular is
regulated by GDPR and CCPA. If you plan to process personal data, take advice
first. Apify has a good primer: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### How much will a run cost me?

You are charged per result, so the cost scales with what you actually get back.
The pricing is shown on this page above the input form. Start with a small run to
see real numbers before you scale up.

#### Can I export to Excel, CSV or Google Sheets?

Yes. Every run's dataset can be downloaded as CSV, Excel, JSON, XML or HTML from
the **Storage** tab, and Apify integrates directly with Google Sheets, Airtable,
Zapier, Make and Slack.

#### Can I run this on a schedule?

Yes. Open the **Schedules** tab and pick an interval — hourly, daily, weekly.
Each run only costs you what it returns.

#### Can I call it from my own code instead of the console?

Yes. Every Actor on Apify is also an API endpoint. There are official clients for
[Python](https://docs.apify.com/api/client/python/) and
[JavaScript](https://docs.apify.com/api/client/js/), plus a plain REST API. The
**API** tab on this page shows ready-made snippets with your input already filled in.

#### Something came back empty. Is it broken?

Usually not. An empty result normally means the filters were too narrow, or the
source genuinely has nothing to return for that query. This Actor is written to
finish successfully and tell you what happened rather than fail — check the run
log, it says which step returned nothing.

### Related Actors

- **ATS Job Monitor** — the same sources, but only what changed since last run
- **LinkedIn Jobs Scraper + Direct Apply Links** — LinkedIn postings cross-referenced with these boards
- **Company Enrichment** — turn a domain into firmographics plus this hiring signal

### Where the data comes from

The public JSON endpoints of Greenhouse, Lever, Ashby and Workable, which companies publish so their job boards can be embedded elsewhere. No login, no API key, no anti-bot circumvention.

# Actor input Schema

## `searchKeyword` (type: `string`):

One search term matched against job titles. This is the main entry point: a keyword alone searches the whole bundled index of 1,014 companies, no company list needed.

## `companyToken` (type: `string`):

One company board token in the form platform:token, for example greenhouse:stripe. Use this when you call the Actor as an API to fetch one company's jobs per call. For several, use the list below.

## `searchScope` (type: `string`):

Job title only is precise. Adding the description finds more, but also matches jobs that merely mention the keyword.

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

Free text match against the job location, e.g. "New York", "London", "Germany".

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

Keep only jobs the company flags as remote.

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

Free text match against the department or team, e.g. "Engineering", "Sales".

## `postedSince` (type: `integer`):

Only jobs published within this many days. Leave empty for no date limit. Jobs without a publish date are excluded when this is set.

## `atsPlatforms` (type: `array`):

Which applicant tracking systems to search. Leave empty to search all of them.

## `companyTokens` (type: `array`):

Several company board tokens at once, one per line, in the form platform:token. Leave empty to search the bundled index instead.

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

Higher means broader coverage and a slower run. Companies with the most open roles are queried first.

## `maxResults` (type: `integer`):

Caps how many jobs land in the dataset. You are charged per job returned.

## `previewMode` (type: `boolean`):

ON by default so you can try the actor for the price of a single run start. No per-result charges apply. Turn it OFF for a full run.

## Actor input object example

```json
{
  "searchKeyword": "backend engineer",
  "searchScope": "title",
  "remoteOnly": false,
  "postedSince": 7,
  "atsPlatforms": [],
  "companyTokens": [],
  "maxCompanies": 200,
  "maxResults": 1000,
  "previewMode": true
}
```

# Actor output Schema

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

Every matching job posting, one dataset item per job, in the unified schema.

# 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 = {
    "searchKeyword": "backend engineer",
    "postedSince": 7
};

// Run the Actor and wait for it to finish
const run = await client.actor("dev_web_col/ats-job-index").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 = {
    "searchKeyword": "backend engineer",
    "postedSince": 7,
}

# Run the Actor and wait for it to finish
run = client.actor("dev_web_col/ats-job-index").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 '{
  "searchKeyword": "backend engineer",
  "postedSince": 7
}' |
apify call dev_web_col/ats-job-index --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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