# ATS Jobs Feed: Greenhouse, Lever, Ashby, Workable & more (`clearfeedlabs/ats-jobs-feed`) Actor

AI-agent & MCP ready: get normalized job postings for any company from 8 ATS public APIs (Greenhouse, Lever, Ashby...). Input: company names/URLs + filters. Output: JSON jobs with salary, location, remote. Incremental mode returns only new, changed and removed jobs.

- **URL**: https://apify.com/clearfeedlabs/ats-jobs-feed.md
- **Developed by:** [Clearfeed Labs](https://apify.com/clearfeedlabs) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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

## ATS Jobs Feed: Greenhouse, Lever, Ashby, Recruitee, Personio, Teamtailor, Pinpoint & Polymer jobs API

**ATS Jobs Feed** turns company career pages into one clean, normalized job feed. Give it company names, board URLs or careers pages; it auto-detects the applicant tracking system (ATS), pulls every open job from that ATS's **public job-board API**, and returns the same schema for all of them, with **parsed salary, location, remote/hybrid flag, seniority and employment type**. Turn on **incremental mode** and repeat runs return only **new, changed and removed** jobs, and you pay only for new and changed ones.

No browser, no proxies, no login. It uses only public, unauthenticated interfaces that ATS vendors publish for embedding job boards.

Use it as a **Greenhouse jobs scraper, Lever jobs API, Ashby job board scraper, Recruitee, Personio and Teamtailor jobs feed, and Pinpoint and Polymer careers API**, all in one Actor with one output format.

![ATS Jobs Feed output: a normalized jobs table from Greenhouse, Teamtailor, Pinpoint and Polymer, with location, workplace type, seniority and salary, plus the per-company run report](https://api.apify.com/v2/key-value-stores/zeAEpuBfJyP8cpu5j/records/ats-jobs-feed-run-output.png)

### For AI agents & MCP

**Tool summary:** given a list of companies, return their open jobs as normalized JSON, pulled from the official public job-board APIs of 8 applicant tracking systems. No login, no browser.

**When to call it:** "What is <company> hiring for?", "Find remote ML roles at these startups", "Which jobs were added or removed since yesterday?"

**Input (key fields):**

- `companies` (array, required): board URLs, `ats:slug` strings such as `greenhouse:stripe`, or plain company names
- `keywords` / `excludeKeywords`, `locations`, `remoteOnly`, `postedSinceDays`, `maxItems`
- `incremental` + `stateKey`: on repeat runs, return only new and changed jobs, plus free `changeType: "removed"` records

**Output (one item per job):** `title`, `company`, `ats`, `locations[]`, `workplaceType`, `isRemote`, `employmentType`, `seniority`, `salary`, `department`, `postedAt`, `jobUrl`, `applyUrl`, `descriptionText`.

**Call it through Apify's hosted MCP server:** connect your MCP client to `https://mcp.apify.com?tools=clearfeedlabs/ats-jobs-feed` (Apify's server; you'll need your own Apify account). Then:

```json
call-actor { "actor": "clearfeedlabs/ats-jobs-feed",
  "input": { "companies": ["greenhouse:stripe", "Notion"], "keywords": ["machine learning"], "remoteOnly": true, "maxItems": 50 } }
```

`call-actor` returns the run and its `datasetId`. Fetch the jobs with `get-dataset-items { "datasetId": "<id>" }`. Set `maxItems` to cap the cost.

### What can it do?

- 🔎 **8 ATSs, one schema:** Greenhouse, Lever (US + EU), Ashby, Recruitee, Personio, Teamtailor, Pinpoint, Polymer. (Workable is temporarily unavailable.)
- 🧭 **Auto-detect the ATS** from a board URL, an `ats:slug` string, or just a company name ("Notion" → Ashby).
- 🌐 **Company discovery:** paste a company's own careers page and the Actor follows the ATS board link it embeds.
- 💰 **Salary parsing:** structured salary where the ATS provides it (Ashby, Lever, Recruitee), otherwise parsed from the posting text (pay-transparency ranges like "$87,069–$124,385", "€50.000 – €60.000", "$211.4K – $290.6K", "CAD").
- 📍 **Locations parsed** into city / region / country / ISO country code, multiple locations per job, remote/hybrid/onsite flag.
- 🧑‍💼 **Seniority inferred** from the title (intern → executive) and **employment type normalized** (full_time, part_time, contract…).
- 🔁 **Incremental monitoring:** only new/changed jobs, plus free `removed` records when a job closes. Ideal for daily schedules, alerts and job-board syncing.
- 🧹 **Cross-board dedupe**, per-company **status report**, and **fail-soft** runs: one bad company never fails the run.
- 🛡️ **Privacy by default:** e-mail addresses and phone numbers are stripped from descriptions.

### Popular uses

- [Greenhouse jobs API: export any Greenhouse job board](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/greenhouse-jobs-scraper)
- [Lever scraper: Lever job postings as JSON](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/lever-jobs-api)
- [Ashby jobs scraper](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/ashby-jobs-scraper)
- [Remote jobs feed: remote startup engineering jobs](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/remote-startup-engineering-jobs)
- [Job postings with salary data](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/job-postings-with-salary-data)
- [Data science & AI/ML jobs](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/data-science-ai-ml-jobs)
- [Sales & go-to-market jobs (SDR, AE)](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/sales-go-to-market-jobs)
- [EU tech jobs in Europe (Personio, Recruitee, Teamtailor)](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/eu-tech-jobs-europe)
- [Hiring signals: companies hiring security leaders](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/companies-hiring-security-leaders)
- [Daily new job alerts for a company watchlist](https://apify.com/clearfeedlabs/ats-jobs-feed/examples/daily-new-job-alerts)

### Who is it for?

Job boards and aggregators, recruiting and staffing agencies, HR-tech and labor-market analysts, sales teams tracking hiring signals ("who is hiring a Head of Security?"), and job seekers monitoring target companies.

### How to use it

1. Add companies in **Companies**, one per line, in any of these forms:
   - `https://boards.greenhouse.io/airbnb`, `https://jobs.lever.co/spotify`, `https://jobs.ashbyhq.com/ramp`, `https://bunq.recruitee.com`, `https://ottonova.jobs.personio.de`, `https://career.teamtailor.com`, `https://workwithus.pinpointhq.com`, `https://jobs.polymer.co/aperturelabs`
   - `greenhouse:stripe`, `lever:palantir`, `lever-eu:<slug>`, `ashby:notion`, `personio-com:<slug>`
   - a bare name like `Notion` (looked up across all supported ATSs)
2. Optional: filters (title keywords, locations, remote only, departments, seniority, employment type, posted within N days).
3. For monitoring, turn on **Incremental mode**, give the search a **State key**, and schedule the Actor daily.
4. Run, then export JSON, CSV or Excel, or connect via API, webhooks, Make, Zapier, n8n or Google Sheets.

#### Input example

```json
{
  "companies": ["greenhouse:airbnb", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/ramp", "Notion"],
  "keywords": ["engineer", "data"],
  "locations": ["US", "Remote"],
  "incremental": true,
  "stateKey": "eng-us"
}
```

### Use cases

**1. Hiring-signal alerts for sales.** Get a daily list of target accounts that just opened security leadership roles.

```json
{ "companies": ["greenhouse:airbnb", "https://jobs.ashbyhq.com/ramp", "lever:palantir"],
  "keywords": ["security", "CISO", "trust"], "seniority": ["director", "executive", "lead"],
  "incremental": true, "stateKey": "security-leaders" }
```

**2. Niche job-board sync.** Keep a remote-engineering board up to date and pay only for new and changed jobs.

```json
{ "companies": ["https://jobs.lever.co/spotify", "https://career.teamtailor.com", "https://workwithus.pinpointhq.com"],
  "keywords": ["engineer", "developer"], "remoteOnly": true,
  "incremental": true, "stateKey": "remote-eng-board" }
```

**3. Job-seeker watchlist.** Track a short list of companies in one country and get new postings each morning.

```json
{ "companies": ["Notion", "https://ottonova.jobs.personio.de", "https://bunq.recruitee.com"],
  "locations": ["Germany", "Netherlands", "Remote"], "postedSinceDays": 7,
  "incremental": true, "stateKey": "my-watchlist" }
```

**4. Labor-market snapshot.** Take a one-off pull of every open role, with salary, for analysis.

```json
{ "companies": ["greenhouse:airbnb", "greenhouse:stripe", "ashby:notion", "https://jobs.polymer.co/aperturelabs"],
  "includeDescription": false }
```

### Output example

```json
{
  "id": "lever:spotify:2a55d6c9-c564-443a-be3e-a3851db5a93b",
  "ats": "lever",
  "company": "spotify",
  "title": "Account Executive - Commercial, Spotify Technology",
  "department": "Operations and Business Support",
  "team": "Platform",
  "locations": [{ "raw": "New York, NY", "city": "New York", "region": "New York", "country": "United States", "countryCode": "US" }],
  "workplaceType": "hybrid",
  "isRemote": false,
  "employmentType": "full_time",
  "seniority": "mid",
  "salary": { "min": 87069, "max": 124385, "currency": "USD", "period": "year", "source": "parsed", "raw": "$87,069-$124,385 plus equity" },
  "descriptionHtml": "<div>…</div>",
  "descriptionText": "Spotify Technology is our business-to-business software team…",
  "applyUrl": "https://jobs.lever.co/spotify/2a55d6c9-…/apply",
  "jobUrl": "https://jobs.lever.co/spotify/2a55d6c9-…",
  "postedAt": "2026-10-23T15:00:40.768Z",
  "updatedAt": null,
  "sourceUrl": "…",
  "contentHash": "3e617db17ac69ad2",
  "changeType": "new",
  "firstSeenAt": "2026-10-29T20:13:37.138Z",
  "scrapedAt": "2026-10-29T20:13:37.099Z"
}
```

In incremental mode a closed job comes back once as `{ "id": "...", "changeType": "removed", "title": "...", "applyUrl": "..." }` (not charged).

The run also stores:

- `COMPANY_REPORT`: one row per company with `status` (`ok`, `empty`, `not_found`, `unresolved`, `robots_disallowed`, `host_refused`, `skipped`, `error`), jobs found, matched, output, new/changed/removed counts and timing.
- `RUN_SUMMARY`: totals, request count and jobs per ATS.

### What to expect from a run

Figures from our own local test runs on 2026-10-29:

- **7 inputs → 219 jobs in about 2.6 seconds** (11 HTTP requests): Greenhouse airbnb 197, Teamtailor 15, Pinpoint 5, Polymer 2. Two Workable inputs were skipped, and a repeated Greenhouse URL was recognised as a duplicate and not fetched again.
- **6 inputs → 216 jobs in about 12.7 seconds** with full descriptions. Polymer needs one extra request per job for descriptions, and those requests are spaced out politely, so Polymer boards take longer.
- Large boards return in one or two requests. A 197-job Greenhouse board took about 2 seconds.
- Every input gets a row in `COMPANY_REPORT`, so you can see exactly what was found, skipped or failed.

### Integrations, API & AI agents

**API (cURL).** Run the Actor and get the jobs back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/clearfeedlabs~ats-jobs-feed/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies":["greenhouse:airbnb"],"keywords":["engineer"]}'
```

**JavaScript**

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('clearfeedlabs/ats-jobs-feed').call({ companies: ['greenhouse:airbnb'], incremental: true, stateKey: 'daily' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python**

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("clearfeedlabs/ats-jobs-feed").call(run_input={"companies": ["greenhouse:airbnb"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

**AI agents (MCP).** Add the Apify MCP server (`https://mcp.apify.com`) to Claude, Cursor or any other MCP client, and the agent can call `clearfeedlabs/ats-jobs-feed` as a tool. For example: "find open data-engineering roles at these 20 companies".

**Schedule + webhook.** Create a daily schedule in Apify Console with `incremental: true`. Then add a webhook on *Run succeeded* that posts to Slack, your backend, Make, Zapier or n8n. Each run carries only new, changed and removed jobs.

**Google Sheets.** Use Apify's Google Sheets integration, or open the dataset's export link in Sheets with `=IMPORTDATA()` (CSV format), to keep a sheet of open roles up to date.

### How much does it cost?

Pay per event: **$3.00 per 1,000 jobs output** plus a $0.00005 run start. No proxy or compute charges for you.
In incremental mode you pay **only for new and changed jobs**; unchanged and removed records cost nothing. Monitoring 50 companies (≈5,000 open jobs) daily typically outputs a few hundred changes a day, about **$0.60–1.20 a day** instead of $15 for a full re-scrape.

### How does it compare?

| | ATS Jobs Feed | Typical Greenhouse/Lever scrapers | Hosted job-database Actors |
|---|---|---|---|
| ATSs covered | 8 (Greenhouse, Lever, Ashby, Recruitee, Personio, Teamtailor, Pinpoint, Polymer) | 1–3 | many, via a pre-built database |
| Real-time from the source | ✅ | ✅ | ⏱ indexed hourly/daily |
| Auto-detect ATS from a name or careers page | ✅ | ❌ / URL only | n/a (search by filters) |
| Salary min/max/currency/period | ✅ structured + parsed | rarely | ✅ (AI-derived) |
| Location → city/region/country code | ✅ | raw string | ✅ |
| Incremental: new + changed + removed | ✅ (pay only for changes) | new only, or none | separate expired-jobs feed |
| Per-company status report | ✅ | ❌ | n/a |
| Contact details redacted by default | ✅ | rarely | varies |
| Price per 1,000 jobs | $3.00, and only new/changed jobs are billed in incremental mode | $1–4 (+ start fees) | $1.50–12 |

### Compliance & responsible use

Each supported source has to pass three checks. Its job-board interface must be officially documented by the vendor. It must need no login, employer key or employer permission. And the vendor's terms must allow this use. We keep an evidence record for every supported ATS and re-check existing sources; they are not grandfathered in.

| ATS | Status |
|---|---|
| Greenhouse | ✅ Supported (official public job-board API) |
| Lever (US + EU) | ✅ Supported (official public postings API) |
| Ashby | ✅ Supported (official public job posting API) |
| Recruitee | ✅ Supported (official careers-site API) |
| Personio | ✅ Supported (official public job feed) |
| Teamtailor | ✅ Supported (official public careers-site feed) |
| Pinpoint | ✅ Supported (official public job postings feed) |
| Polymer | ✅ Supported (official public API for job boards) |
| Workable | ⏸ Temporarily unavailable. Inputs are skipped, nothing is output or billed. |
| SmartRecruiters, Workday, BambooHR, TalentLyft, Manatal, Rippling, Gem, Breezy HR | Not supported |

Safeguards:

- Robots rules are honoured, requests to each host are polite and spaced out, and the User-Agent is honest.
- **No proxies, no browser, no CAPTCHA solving, no login, no fingerprint tricks.** If a host refuses or rate-limits us, the Actor stops contacting it for the rest of the run.
- The same board and the same job are fetched, output and billed only once per run, whatever form the input takes.
- E-mail addresses and phone numbers are removed from descriptions by default. No recruiter or applicant data is collected.

**Your responsibilities.** Job descriptions are the hiring companies' content. Use the output in line with each ATS's and employer's terms, link back to the original posting (`applyUrl`), don't republish full descriptions without permission, and comply with GDPR/CCPA and other laws that apply to you. This Actor is not affiliated with or endorsed by any ATS vendor or employer named here. If you run a board and want it excluded, open an issue.

### FAQ

**My run stopped early with `limitReached: true`.** It hit the run's Max total charge (default $5 ≈ 1,666 jobs). Raise it under the run's Options, or use incremental mode so later runs only bill changes.

**Why are some salary fields empty?** The posting didn't publish pay. Salary coverage depends on the employer and region (pay-transparency laws). In our test of 12 companies, 40% of jobs had a salary.

**Why is `employmentType` empty for Teamtailor jobs, or `postedAt` empty for Pinpoint jobs?** Those feeds don't include the field: Teamtailor's public feed has no employment type, and Pinpoint's has no publish date.

**Is Workable supported?** Not right now. Workable support is temporarily unavailable; Workable inputs are skipped with the note "Workable support paused pending vendor confirmation", and nothing is output or billed for them.

**A company was "unresolved".** It may use an ATS we don't support yet, or a custom slug. Paste the board URL from its careers page, or its careers page into **Company careers pages**.

**Can I run it from code or an AI agent?** Yes. See *Integrations, API & AI agents* above.

**Is it legal?** This Actor reads only job postings that employers publish publicly, through interfaces that ATS vendors document for that purpose. It never logs in or gets around access controls, and it doesn't collect personal data. Whether your particular use is allowed depends on your jurisdiction and on what you do with the data. This is not legal advice; check with your own counsel if in doubt.

**Feedback / new ATS requests?** Open an issue on the Issues tab. Requests for more public ATS feeds are welcome.

### Changelog

- **0.1.6 (2026-10-29):** Workable temporarily unavailable. Its inputs are skipped and not billed.
- **0.1.5 (2026-10-29):** Teamtailor moved to its official public feed. The same board or job is now output and billed once per run, whatever form the input takes.
- **0.1.4 (2026-10-29):** Added Pinpoint and Polymer.
- **0.1.x (2026-10):** First release: Greenhouse, Lever, Ashby, Recruitee, Personio, Teamtailor, incremental mode and salary parsing.

***

Built and maintained by **Clearfeed Labs**. For support, bugs or new ATS requests, open an issue on the Actor's **Issues** tab.

# Actor input Schema

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

One per line. Accepts a job board URL (e.g. https://jobs.lever.co/spotify, https://boards.greenhouse.io/airbnb, https://jobs.ashbyhq.com/ramp, https://bunq.recruitee.com, https://ottonova.jobs.personio.de, https://workwithus.pinpointhq.com, https://jobs.polymer.co/aperturelabs), an explicit 'ats:slug' (e.g. greenhouse:stripe, lever:palantir, lever-eu:slug, personio-com:slug, pinpoint:workwithus, polymer:aperturelabs), or a bare company name/slug, which is looked up across all supported ATSs.

## `careerPageUrls` (type: `array`):

Optional. A company's own careers page; the Actor reads it once (if robots.txt allows) and follows any Greenhouse/Lever/Ashby/Recruitee/Personio/Teamtailor/Pinpoint/Polymer board links it finds.

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

Keep jobs whose title or department contains any of these (case-insensitive).

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

Drop jobs whose title contains any of these.

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

City, region, country name or 2-letter country code (e.g. 'New York', 'Germany', 'US'). Remote jobs also match 'remote'.

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

Keep only jobs flagged remote.

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

Keep only these workplace types.

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

Substring match on department or team.

## `seniority` (type: `array`):

Inferred from the title.

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

Keep only these normalized employment types.

## `postedSinceDays` (type: `integer`):

0 = no limit. Jobs without a posted date are kept.

## `incremental` (type: `boolean`):

Remembers what earlier runs saw (in the named key-value store 'ats-jobs-feed-state'). Outputs only new and changed jobs, plus free 'removed' records for jobs that disappeared. You pay only for new/changed jobs.

## `stateKey` (type: `string`):

Use a different key per saved search/filter set so their histories don't mix. Letters, digits, '\_' and '-'.

## `emitUnchanged` (type: `boolean`):

In incremental mode, also output (and pay for) jobs that did not change.

## `reportRemoved` (type: `boolean`):

In incremental mode, add a free record with changeType 'removed' for each job that is gone.

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

Include description (HTML + text).

## `redactContacts` (type: `boolean`):

Strips personal contact details (e.g. recruiter e-mails) from descriptions. Recommended for GDPR/CCPA.

## `dedupeAcrossSources` (type: `boolean`):

Drops a job if the same company + title + city was already output from another board in this run.

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

0 = no limit.

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

0 = no limit.

## `probeUnknownAts` (type: `boolean`):

For names without a URL, try each ATS's public board for the name (about 1 request per ATS).

## `enableSmartRecruiters` (type: `boolean`):

SmartRecruiters' robots.txt currently disallows generic crawlers, so the Actor will still skip it while that is the case.

## `minRequestIntervalMs` (type: `integer`):

Politeness delay per host. Never set below 500 ms; a robots.txt Crawl-delay is honoured if larger.

## `companyConcurrency` (type: `integer`):

Requests to the same host are always serialised and spaced.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:airbnb",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/ramp",
    "Notion"
  ],
  "remoteOnly": false,
  "postedSinceDays": 0,
  "incremental": false,
  "stateKey": "default",
  "emitUnchanged": false,
  "reportRemoved": true,
  "includeDescription": true,
  "redactContacts": true,
  "dedupeAcrossSources": true,
  "maxJobsPerCompany": 0,
  "maxItems": 0,
  "probeUnknownAts": true,
  "enableSmartRecruiters": false,
  "minRequestIntervalMs": 1000,
  "companyConcurrency": 4
}
```

# Actor output Schema

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

No description

## `companyReport` (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": [
        "greenhouse:airbnb",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/ramp",
        "Notion"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearfeedlabs/ats-jobs-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": [
        "greenhouse:airbnb",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/ramp",
        "Notion",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("clearfeedlabs/ats-jobs-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": [
    "greenhouse:airbnb",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/ramp",
    "Notion"
  ]
}' |
apify call clearfeedlabs/ats-jobs-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearfeedlabs/ats-jobs-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/7ERwq2KutvUBiv0Rv/builds/CwfRPtuNcfvd4kzSG/openapi.json
