# ATS Job Feed: Greenhouse, Lever, Ashby, Personio & More (`plainfeed/ats-job-feed`) Actor

Get open jobs straight from company career boards on Greenhouse, Lever, Ashby, Recruitee, Personio and Teamtailor. One clean schema, salary where published, keyword and location filters, and a monitoring mode that saves only new jobs.

- **URL**: https://apify.com/plainfeed/ats-job-feed.md
- **Developed by:** [Plainfeed](https://apify.com/plainfeed) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

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

### What does ATS Job Feed do?

**ATS Job Feed collects open jobs straight from company career boards** hosted on six applicant tracking systems: **Greenhouse, Lever, Ashby, Recruitee, Personio and Teamtailor**. Paste a list of companies and get every open role in **one clean, consistent format**: title, department, locations, workplace type (remote / hybrid / on-site), employment type, salary where the company publishes it, posting date, job and apply links, and the full description as text.

It reads the **official public job-board feeds** these systems provide for companies' own careers pages, so there's no browser, no login and no fragile HTML scraping. Runs are fast and cheap, and you can use it from the Apify API, on a schedule, or with integrations like Google Sheets, Zapier, Make and webhooks.

### Why use ATS Job Feed?

- **Job boards and aggregators:** keep listings fresh from hundreds of company boards with one input.
- **Recruiters and talent teams:** watch target companies and get only the roles that match your keywords and locations.
- **Sales and market intelligence:** hiring is a buying signal. Track which companies open roles in engineering, sales or new countries.
- **Job seekers and AI agents:** pull a structured feed of roles at the companies you care about, with salary ranges where published.
- **Monitoring mode:** schedule it hourly or daily and pay only for jobs that are new since the last run.

### How to use ATS Job Feed

1. Click **Try for free**.
2. In **Companies**, add one company per line. Any of these work:
   - A job board URL: `https://job-boards.greenhouse.io/stripe`, `https://jobs.lever.co/palantir`, `https://jobs.ashbyhq.com/ramp`, `https://acme.recruitee.com`, `https://acme.jobs.personio.de`, or a Teamtailor career site such as `https://career.teamtailor.com`
   - The company's own careers page, e.g. `https://www.figma.com/careers/`. The job board is detected automatically when the page links to it.
   - A shorthand: `greenhouse:stripe`, `lever:palantir`, `ashby:ramp`, `recruitee:acme`, `personio:acme`, `teamtailor:careers.acme.com`
3. Optionally set **title keywords**, **locations**, **workplace type** or **posted within (days)**.
4. Click **Start**. When the run finishes, download the jobs as JSON, CSV, Excel or HTML, or read them through the API.
5. To monitor companies, turn on **Only jobs not seen in previous runs** and create a **Schedule** in Apify Console.

### Input

See the **Input** tab for every option. Example:

```json
{
  "companies": [
    "https://job-boards.greenhouse.io/stripe",
    "https://jobs.ashbyhq.com/ramp",
    "https://www.figma.com/careers/"
  ],
  "keywords": ["engineer", "data"],
  "locations": ["London", "Remote"],
  "workplaceTypes": ["remote", "hybrid"],
  "postedWithinDays": 14,
  "onlyNewJobs": false,
  "includeDescription": true
}
```

### Output

Each job is one item. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "ats": "ashby",
  "companySlug": "ramp",
  "companyName": null,
  "jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "title": "Security Engineer, Cloud",
  "department": "Engineering",
  "team": "Backend",
  "locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
  "locationText": "New York, NY (HQ); Remote (Canada); Remote (US); Miami, FL",
  "workplaceType": "hybrid",
  "employmentType": "FullTime",
  "salary": { "min": 211400, "max": 290600, "currency": "USD", "period": "year" },
  "postedAt": "2026-04-07T17:12:35.753000+00:00",
  "updatedAt": null,
  "jobUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
  "descriptionText": "About Ramp\nRamp is building the smart infrastructure for finance teams…",
  "scrapedAt": "2026-09-17T09:06:26.859921+00:00"
}
```

A per-company **SUMMARY** record (in the run's key-value store) shows how many jobs each board had, how many were saved, and any company that couldn't be found.

### Data fields

| Field | Description |
| --- | --- |
| `ats` | greenhouse, lever, ashby, recruitee, personio or teamtailor |
| `companySlug` / `companyName` | Board name used by the ATS; company name when the feed includes it |
| `jobId` | The job's ID in that ATS |
| `title`, `department`, `team` | Role details as published |
| `locations`, `locationText` | All listed locations, as a list and as one string |
| `workplaceType` | remote, hybrid, onsite, or unknown when the board doesn't say |
| `employmentType` | e.g. Full-time, Part-time, Contract (as published) |
| `salary` | `min`, `max`, `currency`, `period` (hour/day/week/month/year), when published |
| `postedAt`, `updatedAt` | ISO 8601 UTC timestamps, when available |
| `jobUrl`, `applyUrl` | Links to the job and its application page |
| `descriptionText` / `descriptionHtml` | Description as clean text, and optionally the original HTML |
| `scrapedAt` | When the job was collected |

### How much does it cost?

ATS Job Feed uses pay-per-event pricing, so you only pay for what you get:

- **$1.00 per 1,000 jobs** saved to your dataset
- **$0.10 per 1,000 job boards** checked
- **$0.50 per 1,000 runs** (a small start fee, which keeps frequent monitoring runs viable)

For example, pulling 2,000 jobs from 50 companies in one run costs about **$2.01**. Checking 100 companies every hour in monitoring mode costs about **$0.011 per run**, plus $0.001 for each new job found. Apify's free plan includes monthly usage credits, enough to try this out at no cost. Set a maximum cost per run in the run options and the Actor stops cleanly when it's reached.

### Tips

- Use **title keywords** and **locations** to cut costs; you're only charged for jobs that pass your filters.
- Turn off **Include description text** if you only need titles and links; runs get smaller and faster.
- For monitoring, give the run a **Monitoring name**. Runs with the same name share their history even when you add companies.
- Salary appears only where the company publishes it in its job-board feed. In testing that was most common on Ashby and Recruitee boards.

### FAQ, limitations and support

**Which careers pages are auto-detected?** Pages that link to or embed a Greenhouse, Lever, Ashby, Recruitee or Personio board, and Teamtailor career sites. Some careers pages load their job links with JavaScript or use other systems (Workday, SmartRecruiters, iCIMS and others), and those aren't detected. Paste the job board URL directly in that case.

**Is this legal?** The Actor reads only the public job-board endpoints that these ATS vendors provide so companies can publish their open roles, and it only collects job information. It doesn't collect candidate or recruiter personal data. You're responsible for using the data in line with applicable laws and each company's terms, especially if you republish job descriptions.

**Something doesn't work, or you need another ATS?** Open an issue in the **Issues** tab with the company URL, and it will be looked at promptly.

# Actor input Schema

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

One company per line. Paste a job board URL (e.g. https://job-boards.greenhouse.io/stripe, https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/ramp, https://acme.recruitee.com, https://acme.jobs.personio.de, https://careers.acme.com on Teamtailor), the company's own careers page (the job board is detected automatically), or a shorthand like greenhouse:stripe, lever:palantir, ashby:ramp, recruitee:acme, personio:acme, teamtailor:careers.acme.com.

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

Keep jobs whose title contains any of these words (case-insensitive). Leave empty to keep all jobs.

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

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

## `searchDescriptions` (type: `boolean`):

Match title keywords against the full description as well as the title.

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

Keep jobs whose location contains any of these words, e.g. London, Germany, Remote.

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

Keep only these workplace types. Leave empty for all. Not every job board reports this; such jobs are 'unknown'.

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

Keep only jobs posted in the last N days. 0 keeps all. Jobs without a posting date are dropped when this is set.

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

Monitoring mode for scheduled runs: save only jobs that weren't on these boards the last time you ran the same input. You pay only for new jobs.

## `monitoringKey` (type: `string`):

Optional. Runs with the same name share their 'already seen' history, even if you change the company list.

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

Add the job description as clean plain text.

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

Add the original description HTML as well.

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

Stop after this many matching jobs per job board. 0 means no limit.

## `personioLanguage` (type: `string`):

Language of Personio job ads, if the company publishes several.

## Actor input object example

```json
{
  "companies": [
    "https://jobs.ashbyhq.com/ramp",
    "https://career.teamtailor.com"
  ],
  "searchDescriptions": false,
  "postedWithinDays": 0,
  "onlyNewJobs": false,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "maxJobsPerCompany": 20,
  "personioLanguage": "en"
}
```

# 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 = {
    "companies": [
        "https://jobs.ashbyhq.com/ramp",
        "https://career.teamtailor.com"
    ],
    "maxJobsPerCompany": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainfeed/ats-job-feed").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.ashbyhq.com/ramp",
        "https://career.teamtailor.com",
    ],
    "maxJobsPerCompany": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("plainfeed/ats-job-feed").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.ashbyhq.com/ramp",
    "https://career.teamtailor.com"
  ],
  "maxJobsPerCompany": 20
}' |
apify call plainfeed/ats-job-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plainfeed/ats-job-feed"
        }
    }
}
```

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/y3qq83IdSpPlwdDV3/builds/zAMtNdZcu5bCW4Nnj/openapi.json
