# Job Postings API — Greenhouse, Lever & Ashby in one (`esco.api/ats-job-postings`) Actor

Pull live job postings for any list of companies from Greenhouse, Lever, and Ashby public job boards — one normalized schema, salary data where published, and a new-only mode so scheduled runs return (and charge for) only new postings.

- **URL**: https://apify.com/esco.api/ats-job-postings.md
- **Developed by:** [Francesco Freedman](https://apify.com/esco.api) (community)
- **Categories:** Jobs, Lead generation, Business
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## 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

## Job Postings API — Greenhouse, Lever & Ashby in one

Pull **live job postings for any list of companies** across the three most popular tech ATS platforms — Greenhouse, Lever, and Ashby — in one run, with one normalized schema. Salary data where published, remote flags, full descriptions, and a **new-only mode** that makes scheduled runs return (and charge for) *only postings you haven't seen before*.

### Why this actor

- **Three ATS platforms, one schema.** Stop juggling separate scrapers — mix `greenhouse:stripe`, `https://jobs.lever.co/palantir`, and `ashby:openai` in one input. Same columns out, whatever the source.
- **Auto-detection.** Don't know which ATS a company uses? Just give the bare slug (`duolingo`, `notion`) — the actor probes all three platforms and finds the board.
- **Official public APIs, not scraping.** Greenhouse, Lever, and Ashby publish these job-board APIs for public consumption — fast, stable, no proxies, no breakage when a careers page is redesigned.
- **You only pay for new postings.** With `newOnly` (default), a daily scheduled run returns just the jobs posted since your last run. Perfect for job alerts, talent-market tracking, and hiring-signal lead generation.
- **Salary data where it exists.** Structured min/max/currency/interval from Lever, published ranges from Ashby (`$185K – $325K`), plus remote flags and employment type.

### Output example

```json
{
    "platform": "ashby",
    "company": "openai",
    "title": "Forward Deployed Software Engineer - SF",
    "department": "Model Deployment for Business",
    "location": "San Francisco",
    "remote": true,
    "salary_text": "$185K - $325K",
    "posted_at": "2025-11-15T01:25:39.198Z",
    "url": "https://jobs.ashbyhq.com/openai/00207abc-...",
    "description_text": "..."
}
```

### Who uses this

- **Recruiters & sourcers** — track competitor and client hiring across hundreds of companies daily.
- **Sales teams** — hiring is the strongest budget signal there is: a company adding SDRs is buying sales tools; one hiring DevOps is buying infrastructure.
- **Job boards & aggregators** — clean, normalized feed for your niche board (remote-only, AI companies, fintech…).
- **Job seekers & career coaches** — daily alerts on new roles at target companies, before they hit LinkedIn.
- **Analysts & researchers** — headcount growth, salary benchmarking, team-structure signals.

### Inputs

| Field | Default | Notes |
|---|---|---|
| `companies` | demo list | Careers URLs, `platform:slug` pairs, or bare slugs (auto-detected) |
| `newOnly` | `true` | Skip postings delivered by previous runs |
| `postedSinceDays` | `0` (all open roles) | e.g. `7` = only jobs first published in the last week |
| `includeDescription` | `true` | Disable for lighter rows |
| `maxResults` | `0` (no cap) | Handy for test runs |

### Recommended setup: daily hiring feed

1. Create a **Schedule** in Apify Console (daily).
2. Input: your company list, `newOnly: true`.
3. Add an integration (email, Slack, webhook, Google Sheets, Make/Zapier) — every morning you get only the new postings.

First run returns each company's full board (that's your baseline); every run after that returns only what's new.

### Notes & limits

- Boards that don't exist (or companies not on these three platforms) are skipped with a warning — the run continues and the status message lists any failures.
- Greenhouse does not expose salary via its public board API; salary fields are null there.
- More ATS platforms (SmartRecruiters, Workable, Recruitee…) are added by demand — **open an issue and tell me which one you need**.

### Data & fair-use notes

Job postings are published by companies specifically for public distribution, via APIs the ATS vendors provide for that purpose. The actor queries them politely (paced, identified) and stores no personal data.

# Actor input Schema

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

Companies to pull job boards for. Accepts: a careers-page URL (https://boards.greenhouse.io/stripe, https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/openai), an explicit platform prefix (greenhouse:stripe, lever:palantir, ashby:openai), or a bare slug (stripe) which is auto-detected across all three platforms.

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

0 = all currently open postings (default). Set e.g. 7 to only get jobs first published within the last week.

## `newOnly` (type: `boolean`):

When enabled, postings already returned by previous runs of this actor are skipped — a scheduled run only yields (and only charges for) job postings you haven't seen before. Perfect for daily new-job alerts and hiring-signal tracking.

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

Disable for lighter rows (titles, locations, salaries, URLs only).

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

Hard cap on total results across all companies (0 = no cap). Useful for test runs.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:openai"
  ],
  "postedSinceDays": 0,
  "newOnly": true,
  "includeDescription": true,
  "maxResults": 0
}
```

# 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:stripe",
        "lever:palantir",
        "ashby:openai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("esco.api/ats-job-postings").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:stripe",
        "lever:palantir",
        "ashby:openai",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("esco.api/ats-job-postings").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 '{
  "companies": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:openai"
  ]
}' |
apify call esco.api/ats-job-postings --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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