# Greenhouse, Lever & Ashby Jobs Scraper: New Jobs Monitor (`hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor`) Actor

Scrape Greenhouse, Lever and Ashby careers pages and get only the new jobs since your last run: title, department, location, remote, salary, posted date and apply URL, normalized from official public job board APIs. No login or API key. $1.50 per 1,000 jobs.

- **URL**: https://apify.com/hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor.md
- **Developed by:** [Haniel Azevedo](https://apify.com/hanielazevedo) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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

**English** · [Português (BR)](#português-br)

**Paste Greenhouse, Lever or Ashby careers page URLs and get every open job (or only the jobs posted since your last run) as clean, normalized JSON: title, department, location, remote/hybrid, employment type, salary where published, posted date and apply URL. No login, no API key.**

One Actor covers the three most common startup and scale-up applicant tracking systems (ATS). It reads each company's **official public job board API** (the same feeds the companies' own careers pages use), so results are complete, fast and stable: no browser, no proxies, no HTML scraping.

### Who it's for

- **Job seekers and job-alert builders** who want to hear about new roles at a list of target companies the day they are posted.
- **Recruiters, sales and lead-generation teams** who use hiring as a buying signal ("company X just opened 5 data engineering roles").
- **Job boards, newsletters and aggregators** that need a clean, deduplicated feed across Greenhouse, Lever and Ashby with one schema.
- **Analysts and investors** tracking headcount plans, salary ranges and remote policies across companies.

### Try it

Click **Start** without changing anything. The prefilled input returns the 10 newest jobs from each of Airbnb (Greenhouse), Spotify (Lever) and Linear (Ashby), 30 in total:

```json
{
    "companies": [
        "https://job-boards.greenhouse.io/airbnb",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/linear"
    ],
    "maxResults": 30,
    "maxJobsPerCompany": 10
}
```

It finishes in about a second (three API requests) and costs **$0.045**. An empty input `{}` uses the same three companies with a 100-job limit. Then replace the companies with your own list and add filters.

### What you can put in "Companies"

One entry per line, mixed freely:

| You paste                                                                                 | What happens                                                                                                                                                            |
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `https://job-boards.greenhouse.io/airbnb`, `https://boards.greenhouse.io/stripe/jobs/123` | Greenhouse board detected from the URL                                                                                                                                  |
| `https://jobs.lever.co/spotify`, `https://jobs.eu.lever.co/acme`                          | Lever board (EU instance supported)                                                                                                                                     |
| `https://jobs.ashbyhq.com/linear`                                                         | Ashby board                                                                                                                                                             |
| `https://www.notion.com/careers`                                                          | The company's own careers page: the Actor opens it once, finds the Greenhouse, Lever or Ashby board it links to or embeds, and falls back to the domain name (`notion`) |
| `stripe`                                                                                  | Bare board token: tried on Greenhouse, then Lever, then Ashby                                                                                                           |
| `greenhouse:stripe`, `lever:palantir`, `ashby:openai`                                     | Token with the ATS named, one request                                                                                                                                   |

Embed URLs (`boards.greenhouse.io/embed/job_board?for=…`) and API URLs work too. The same board given twice is fetched once.

### How to use it

**All** (default): every open job that matches your filters, newest first per company.

**Monitor**: set `mode` to `monitor` and schedule the Actor (hourly or daily). It remembers which jobs it has already delivered, in a named key-value store `ats-job-boards-monitor` that persists between runs (one entry per company list + filters), and delivers **only new jobs**, marked `"changeType": "new"`. You pay once per job, not once per run. Options:

- `firstRun: "baseline"` remembers the current jobs on the first run without delivering or charging them, so you are only alerted about jobs posted later.
- `includeRemoved: true` also outputs a free `"type": "removed"` record when a job you were sent disappears from its board (usually filled or closed).
- `stateKey` names the monitor, so you can edit the list without losing its history.

Connect the dataset to Slack, email, Google Sheets or a webhook with Apify integrations to get alerts.

**Filters** (all optional, combined with AND):

- `keywords` / `excludeKeywords`: whole-word, case-insensitive, in the title (or title + description with `keywordsIn`).
- `locations` / `excludeLocations`: text match on any location or country, e.g. `London`, `United States`, `Remote`.
- `remote`: `remote`, `remoteOrHybrid`, `hybrid` or `onsite`.
- `departments`: matches department or team, e.g. `Engineering`.
- `employmentTypes`: `FULL_TIME`, `PART_TIME`, `CONTRACT`, `INTERN`, `TEMPORARY`.
- `postedWithinDays`: only jobs first published in the last N days.
- `salaryOnly`: only jobs that publish a pay range.

**Size and limits**: `maxResults` (default 100), `maxJobsPerCompany`, `descriptionFormat` (`both`, `text`, `html` or `none`; descriptions are most of the output size) and `descriptionMaxChars`.

### Get new job alerts in Slack or email (step by step)

1. In **Companies**, paste one careers page URL or board token per line (for example `https://job-boards.greenhouse.io/airbnb`, `https://jobs.lever.co/spotify`, `https://jobs.ashbyhq.com/linear`).
2. Add filters if you want: **Keywords**, **Locations**, **Workplace** (remote, hybrid, onsite) or **Departments / teams**.
3. Set **Mode** to `monitor` and **Monitor: first run** to `baseline`, so the jobs already open are remembered without being delivered or charged.
4. Click **Save as a new task** and run it once.
5. Open **Schedules** and run the task daily or hourly.
6. On the task's **Integrations** tab, add Slack, Gmail, Zapier, Make or a webhook, triggered when a run succeeds.
7. Each run then delivers only jobs posted since the last run, at $0.0015 per job. Runs with nothing new cost only the $0.00005 start fee.

### Use with AI agents (MCP) and Python

**MCP:** add this Actor as a tool in Claude Desktop, Cursor, VS Code or any MCP client through the Apify MCP server: `https://mcp.apify.com?tools=hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor` (sign in with your Apify account or pass your API token). The agent sees the input schema and can run the Actor and read the dataset itself.

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor").call(run_input={
    "companies": [
        "https://jobs.ashbyhq.com/linear",
        "stripe"
    ],
    "mode": "monitor",
    "keywords": [
        "engineer"
    ],
    "remote": "remoteOrHybrid"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Sample output

One job (description shortened):

```json
{
    "type": "job",
    "jobKey": "greenhouse:airbnb:8337229",
    "ats": "greenhouse",
    "company": "Airbnb",
    "companyToken": "airbnb",
    "jobId": "8337229",
    "title": "Senior Manager, Community Policy",
    "department": "Public Policy",
    "team": null,
    "location": "United States",
    "locations": ["United States"],
    "country": null,
    "workplaceType": "remote",
    "isRemote": true,
    "employmentType": null,
    "employmentTypeRaw": null,
    "salary": {
        "min": 204000,
        "max": 255000,
        "currency": "USD",
        "interval": "year",
        "label": "Pay Range",
        "text": "Pay Range: 204,000–255,000 USD",
        "ranges": [{ "min": 204000, "max": 255000, "currency": "USD", "interval": "year", "label": "Pay Range" }]
    },
    "postedAt": "2026-10-30T19:19:06.000Z",
    "updatedAt": "2026-10-30T19:19:06.000Z",
    "jobUrl": "https://careers.airbnb.com/positions/8337229?gh_jid=8337229",
    "applyUrl": "https://careers.airbnb.com/positions/8337229?gh_jid=8337229",
    "boardUrl": "https://job-boards.greenhouse.io/airbnb",
    "changeType": null,
    "scrapedAt": "2026-10-31T21:08:00.540Z",
    "descriptionHtml": "<p>Airbnb was born in 2007 when two hosts welcomed three guests…</p>",
    "descriptionText": "Airbnb was born in 2007 when two hosts welcomed three guests…"
}
```

A company that fails produces a free error record instead, and the run continues:

```json
{
    "type": "error",
    "input": "nonexistentco12345",
    "ats": null,
    "companyToken": "nonexistentco12345",
    "detectedVia": "token",
    "errorCode": "BOARD_NOT_FOUND",
    "errorMessage": "No public board named \"nonexistentco12345\" on Greenhouse, Lever or Ashby",
    "httpStatus": 404,
    "url": null,
    "scrapedAt": "2026-10-31T21:12:16.000Z"
}
```

### What you get (fields)

| Field                                     | Notes                                                                                                                                                                                                                     |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `jobKey`                                  | `ats:companyToken:jobId`, unique and stable: use it to deduplicate                                                                                                                                                        |
| `ats`, `company`, `companyToken`, `jobId` | Source ATS, company name (Greenhouse publishes it; for Lever and Ashby it is derived from the board name), board token, the ATS's job ID                                                                                  |
| `title`, `department`, `team`             | As published                                                                                                                                                                                                              |
| `location`, `locations[]`, `country`      | Primary location, all locations, and country when the ATS provides it                                                                                                                                                     |
| `workplaceType`, `isRemote`               | `remote`, `hybrid`, `onsite` or null. From the ATS field when there is one, otherwise inferred from the location text ("Remote")                                                                                          |
| `employmentType`, `employmentTypeRaw`     | Normalized (`FULL_TIME`, `PART_TIME`, `CONTRACT`, `INTERN`, `TEMPORARY`) plus the original label                                                                                                                          |
| `salary`                                  | `min`, `max`, `currency`, `interval` (`year`, `month`, `week`, `day`, `hour`), `label`, the employer's `text` summary, and every published range in `ranges[]` (e.g. per pay zone). Null when the job doesn't publish pay |
| `postedAt`, `updatedAt`                   | ISO 8601 UTC. Greenhouse: first published / updated; Lever: created; Ashby: published                                                                                                                                     |
| `jobUrl`, `applyUrl`, `boardUrl`          | Posting page, application page, company board                                                                                                                                                                             |
| `descriptionHtml`, `descriptionText`      | Full description (Lever includes the lists and closing sections), optional                                                                                                                                                |
| `changeType`                              | `new` in monitor mode, null otherwise                                                                                                                                                                                     |

Salary coverage depends on the employer and the law where the job is located: in our tests about 80% of Airbnb's Greenhouse jobs, Ashby boards using compensation tiers, and Lever postings with a salary range published pay. The run's **SUMMARY** record (key-value store) has per-company counts, detected ATS and token, and error details.

### How much does it cost to scrape Greenhouse, Lever and Ashby jobs?

Pay per event:

- **$0.0015 per job delivered** ($1.50 per 1,000 jobs).
- **$0.00005 per run** (Apify's standard actor-start event).
- **Free:** error records, removed-job records, jobs skipped by filters, and jobs already delivered in monitor mode.

Examples:

- Prefilled run (30 jobs): **$0.045**.
- Monitor of 50 companies, checked daily, ~20 new matching jobs a day: about **$0.03 a day**, under $1 a month.
- Full snapshot of a 1,000-job board: **$1.50**.

Set **Max cost per run** in the run options to cap spending: the Actor stops cleanly at the limit (`CHARGE_LIMIT_REACHED`), and in monitor mode the jobs it did not deliver are sent next run.

### Reliability and error codes

- Up to 3 boards fetched in parallel (`maxConcurrency`, max 10), with requests to the same API host spaced out.
- Retries with exponential backoff on HTTP 429 (honouring `Retry-After`), 5xx, timeouts and network errors (`maxRetries`, default 4).
- One company failing never fails the run. Error records carry one of these codes:

| Code                                         | Meaning                                                                                                                         |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `BOARD_NOT_FOUND`                            | No public board with that token (404). Check the spelling, or the company may have moved ATS                                    |
| `ATS_NOT_DETECTED`                           | The careers page doesn't link to a Greenhouse, Lever or Ashby board (it may use another ATS or load jobs in a way we can't see) |
| `CAREERS_PAGE_UNREACHABLE`                   | The careers page couldn't be loaded and no board matched its domain name                                                        |
| `INVALID_COMPANY`                            | The entry is not a URL or a valid token                                                                                         |
| `RATE_LIMITED`                               | Still HTTP 429 after all retries                                                                                                |
| `ACCESS_DENIED`                              | HTTP 401/403 from the ATS                                                                                                       |
| `UPSTREAM_ERROR`, `TIMEOUT`, `NETWORK_ERROR` | ATS server or network problems after retries                                                                                    |
| `BAD_RESPONSE`                               | The API answered with something that isn't the documented format                                                                |

Run-level status codes in SUMMARY: `NO_RESULTS`, `MAX_RESULTS_REACHED`, `CHARGE_LIMIT_REACHED`, `BASELINE_CREATED`, `ALL_COMPANIES_FAILED` (the run still succeeds, with error records), `INVALID_INPUT` and `STATE_ERROR` (the only ones that fail the run).

### Data source and terms

The Actor only calls the documented, unauthenticated public job board APIs that each ATS provides for publishing jobs:

- Greenhouse Job Board API: `boards-api.greenhouse.io/v1/boards/{token}/jobs?content=true`
- Lever Postings API: `api.lever.co/v0/postings/{company}?mode=json`
- Ashby Job Postings API: `api.ashbyhq.com/posting-api/job-board/{name}?includeCompensation=true`

It never logs in, never submits applications and only reads jobs that companies have published publicly. Careers pages on company websites are fetched once (a normal page view) to find the board link. Data is live: each run reads the boards at that moment.

### Greenhouse vs Lever vs Ashby scrapers: how this one compares

- **Three ATSs, one format.** Greenhouse, Lever and Ashby boards go in the same list, and every job comes out with the same fields (`title`, `locations`, `workplaceType`, `employmentType`, `salary`, `postedAt`, `applyUrl`), so you don't need one scraper and one parser per ATS.
- **Only new jobs.** Monitor mode is built in: each job is delivered and charged once, and `includeRemoved` can flag jobs that were taken down, for free.
- **Official public feeds.** It reads each board's public job board API, the same feed the careers page uses. No browser, proxy, login or API key.
- **Price.** $1.50 per 1,000 jobs delivered; errors, removed-job records and jobs already sent are free. On 31 Oct 2026, two other ATS job-board Actors in the Apify Store charged $1.50 and $12.00 per 1,000 jobs on the free plan, and the first is cheaper on its paid discount tiers.
- **Limits.** Only these three ATSs. Workday, SmartRecruiters, Workable and others are not supported yet.

### FAQ

**Does it support Workday, SmartRecruiters, Workable or others?** Not yet: only Greenhouse, Lever and Ashby. Pages using another ATS return `ATS_NOT_DETECTED`.

**How do I find a company's board token?** Paste the careers page URL and the Actor finds it. The token is also the last part of the board URL (`jobs.lever.co/`**`spotify`**). Each job's `companyToken` and the SUMMARY record show what was detected.

**Why is the company name in lowercase or slightly off for Lever/Ashby jobs?** Those APIs don't return a company name, so it is derived from the board token (`palantir` becomes "Palantir").

**Why is `employmentType` null for some Greenhouse jobs?** Greenhouse has no standard field for it; the Actor reads it from the board's custom fields when the company provides one.

**How does monitor mode know what's new?** It compares each job's `jobKey` with the ones it already delivered for the same companies and filters. A job edited after posting is not resent. A board that fails in one run doesn't make its jobs look removed or new.

**Can I run it for hundreds of companies?** Yes. Each board is one request (a few seconds for very large boards); a run accepts up to 5,000 entries.

**What if a company has boards on two ATSs?** Bare tokens stop at the first ATS that has the board. Turn on `probeAllAts` to collect from every ATS that has one.

### Other Actors by Haniel

- [PDF to Markdown & Text Extractor with OCR (DOCX)](https://apify.com/hanielazevedo/document-to-markdown-ocr): PDF, scanned PDF, DOCX, HTML and images to clean Markdown or text for RAG and AI agents. $3 per 1,000 documents.
- [SAM.gov Scraper: Federal Contract Opportunities Monitor](https://apify.com/hanielazevedo/samgov-contract-opportunities): New SAM.gov contract opportunities, RFPs and sources sought by NAICS, set-aside and agency. No API key. $2 per 1,000 notices.
- [Consulta CNPJ em Lote: Brazil CNPJ Lookup (Receita Federal)](https://apify.com/hanielazevedo/brazil-cnpj-company-lookup): Bulk Brazil CNPJ lookup: legal name, CNAE, partners (QSA), address, Simples Nacional and MEI. $1.20 per 1,000 companies.
- [Floor Plan Takeoff: PDF Room Areas, Wall LF & Door Counts](https://apify.com/hanielazevedo/floor-plan-takeoff): Construction takeoff from vector floor-plan PDFs: room SF, wall linear feet, door counts and a check overlay. $2.50 per measured sheet.

***

### Português (BR)

**Cole URLs de páginas de carreira do Greenhouse, Lever ou Ashby e receba todas as vagas abertas (ou só as publicadas desde a última execução) em JSON limpo e padronizado: título, departamento, local, remoto/híbrido, tipo de contrato, salário quando publicado, data de publicação e link para se candidatar. Sem login, sem chave de API.**

Um único Actor cobre os três ATS (sistemas de recrutamento) mais usados por startups e scale-ups. Ele lê a **API pública oficial do quadro de vagas** de cada empresa (o mesmo feed que a página de carreiras da empresa usa), sem navegador, proxy ou raspagem de HTML.

#### Para quem é

- **Quem procura emprego e quem cria alertas de vagas**: saiba das vagas novas nas empresas-alvo no dia em que são publicadas.
- **Recrutadores, vendas e geração de leads**: contratações como sinal de compra ("a empresa X abriu 5 vagas de engenharia de dados").
- **Sites de vagas, newsletters e agregadores**: um feed único, sem duplicatas, com o mesmo formato para os três ATS.
- **Analistas e investidores**: acompanhe planos de contratação, faixas salariais e política de trabalho remoto.

#### Experimente

Clique em **Start** sem mudar nada: o exemplo traz as 10 vagas mais recentes de Airbnb (Greenhouse), Spotify (Lever) e Linear (Ashby), 30 no total, em cerca de um segundo, por **US$ 0,045**. Uma entrada vazia `{}` usa as mesmas empresas com limite de 100 vagas.

#### Como usar

- Em **Companies**, uma empresa por linha: URL do quadro (`https://jobs.lever.co/spotify`), página de carreiras do site da empresa (`https://www.notion.com/careers`, o Actor encontra o quadro vinculado), token simples (`stripe`, testado no Greenhouse, Lever e Ashby) ou token com prefixo (`lever:palantir`).
- **Filtros**: palavras-chave (no título ou também na descrição), palavras excluídas, locais, remoto/híbrido/presencial, departamento, tipo de contrato, publicadas nos últimos N dias e só vagas com salário.
- **Modo monitor** (`mode: "monitor"`): agende a execução; o Actor guarda as vagas já entregues no key-value store nomeado `ats-job-boards-monitor` e entrega **só as vagas novas** (`changeType: "new"`). `firstRun: "baseline"` memoriza as vagas atuais sem entregar nem cobrar; `includeRemoved: true` avisa (grátis) quando uma vaga sai do ar.
- `descriptionFormat: "none"` reduz bastante o tamanho da saída.

#### Alertas de vagas novas no Slack ou por e-mail (passo a passo)

1. Em **Companies**, cole uma URL de página de carreiras ou token por linha.
2. Adicione filtros se quiser: **Keywords**, **Locations**, **Workplace** ou **Departments / teams**.
3. Coloque **Mode** em `monitor` e **Monitor: first run** em `baseline` (as vagas já abertas são memorizadas sem entrega nem cobrança).
4. Clique em **Save as a new task** e rode uma vez.
5. Em **Schedules**, agende a task diária ou de hora em hora.
6. Na aba **Integrations** da task, adicione Slack, Gmail, Zapier, Make ou um webhook.
7. Cada execução entrega só as vagas publicadas desde a anterior, a US$ 0,0015 cada.

#### Exemplo de saída

Veja o JSON de exemplo na seção em inglês: cada vaga traz `jobKey`, `ats`, `company`, `title`, `department`, `team`, `locations`, `workplaceType`, `employmentType`, `salary` (mín., máx., moeda, período e texto do empregador), `postedAt`, `jobUrl`, `applyUrl` e a descrição em HTML e texto.

#### Quanto custa raspar vagas do Greenhouse, Lever e Ashby?

- **US$ 0,0015 por vaga entregue** (US$ 1,50 por 1.000 vagas) + **US$ 0,00005 por execução**.
- **Grátis**: registros de erro, registros de vaga removida, vagas descartadas pelos filtros e vagas já entregues no modo monitor.
- Exemplo: monitorar 50 empresas por dia com ~20 vagas novas por dia custa cerca de US$ 0,03 por dia.
- Use **Max cost per run** para limitar o gasto; no modo monitor, o que não foi entregue vai na próxima execução.

#### Códigos de erro

Uma empresa com problema gera um registro gratuito `type: "error"` e a execução continua: `BOARD_NOT_FOUND` (token inexistente), `ATS_NOT_DETECTED` (a página de carreiras não aponta para Greenhouse, Lever ou Ashby), `CAREERS_PAGE_UNREACHABLE`, `INVALID_COMPANY`, `RATE_LIMITED`, `ACCESS_DENIED`, `UPSTREAM_ERROR`, `TIMEOUT`, `NETWORK_ERROR`, `BAD_RESPONSE`. Há novas tentativas automáticas com espera exponencial para 429 (respeitando `Retry-After`), 5xx e falhas de rede.

#### Perguntas frequentes

**Funciona com Workday, Gupy ou outros ATS?** Ainda não: só Greenhouse, Lever e Ashby.

**Precisa de login?** Não. Só são usadas as APIs públicas e documentadas que os ATS oferecem para divulgar vagas; o Actor nunca faz login nem envia candidaturas.

**Como o modo monitor sabe o que é novo?** Compara o `jobKey` de cada vaga com as já entregues para a mesma lista de empresas e filtros. Se um quadro falhar numa execução, as vagas dele não aparecem como removidas nem como novas.

**Por que o nome da empresa vem do token no Lever e no Ashby?** Essas APIs não informam o nome da empresa; ele é derivado do token (`palantir` vira "Palantir").

#### Uso com agentes de IA (MCP) e Python

**MCP:** adicione este Actor como ferramenta no Claude Desktop, Cursor, VS Code ou outro cliente MCP pelo servidor MCP da Apify: `https://mcp.apify.com?tools=hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor`. O agente lê o schema de entrada, roda o Actor e lê o dataset.

**Python** (`pip install apify-client`): veja o exemplo na seção em inglês.

#### Outros Actors do Haniel

- [PDF to Markdown & Text Extractor with OCR (DOCX)](https://apify.com/hanielazevedo/document-to-markdown-ocr): PDF, PDF escaneado, DOCX, HTML e imagens para Markdown ou texto limpo, para RAG e agentes de IA. US$ 3 por 1.000 documentos.
- [SAM.gov Scraper: Federal Contract Opportunities Monitor](https://apify.com/hanielazevedo/samgov-contract-opportunities): Novas oportunidades de contratos federais dos EUA no SAM.gov por NAICS, set-aside e órgão. Sem chave de API. US$ 2 por 1.000.
- [Consulta CNPJ em Lote: Brazil CNPJ Lookup (Receita Federal)](https://apify.com/hanielazevedo/brazil-cnpj-company-lookup): Consulta CNPJ em lote: razão social, CNAE, sócios (QSA), endereço, Simples Nacional e MEI. US$ 1,20 por 1.000 empresas.
- [Floor Plan Takeoff: PDF Room Areas, Wall LF & Door Counts](https://apify.com/hanielazevedo/floor-plan-takeoff): Levantamento de quantitativos de plantas em PDF vetorial: área dos ambientes, metros lineares de parede e portas. US$ 2,50 por prancha medida.

# Actor input Schema

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

One company per line. Accepts: an ATS board URL (<code>https://job-boards.greenhouse.io/airbnb</code>, <code>https://jobs.lever.co/spotify</code>, <code>https://jobs.ashbyhq.com/linear</code>, embed / API URLs, EU boards); the company's own careers page (<code>https://www.notion.com/careers</code>), where the Actor finds the Greenhouse, Lever or Ashby board it links to; a bare board token (<code>stripe</code>), tried on all three ATSs; or a token with a prefix (<code>greenhouse:stripe</code>, <code>lever:palantir</code>, <code>ashby:openai</code>). Empty input uses the three examples.

## `mode` (type: `string`):

<b>all</b> returns every open job that matches. <b>monitor</b> remembers the jobs it already delivered (named key-value store <code>ats-job-boards-monitor</code>, one entry per company list + filters) and delivers only new ones, so you pay once per job. Schedule it hourly or daily.

## `firstRun` (type: `string`):

What the first monitor run does. <b>baseline</b> stores the current jobs without delivering or charging them.

## `includeRemoved` (type: `boolean`):

Also output a free <code>type: "removed"</code> record when a previously delivered job disappears from its board (filled or closed).

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

Name of the monitor entry. Leave empty to derive it from companies + filters. Set it to keep history when you edit the list.

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

Keep jobs whose title (or title + description, see below) contains any of these words or phrases (whole words, case-insensitive). Example: <code>engineer</code>, <code>data scientist</code>.

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

Drop jobs that contain any of these. Example: <code>intern</code>, <code>senior staff</code>.

## `keywordsIn` (type: `string`):

Where keywords are matched.

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

Keep jobs where any location contains one of these (case-insensitive), e.g. <code>New York</code>, <code>London</code>, <code>United States</code>, <code>Remote</code>.

## `excludeLocations` (type: `array`):

Drop jobs whose locations all match one of these.

## `remote` (type: `string`):

Filter by workplace type as published by the employer (inferred from the location text when the ATS has no field).

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

Keep jobs whose department or team contains one of these, e.g. <code>Engineering</code>, <code>Sales</code>.

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

Keep only these types. Jobs without a published type are dropped when this is set.

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

Keep jobs first published (or, if unknown, updated) in the last N days. 0 = any date.

## `salaryOnly` (type: `boolean`):

Keep only jobs that publish a pay range.

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

Stop after this many jobs (each charged). The run also stops when your max charge per run is reached.

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

Newest jobs first. 0 = no limit.

## `descriptionFormat` (type: `string`):

Descriptions are most of the output size; drop them if you only need the listing fields.

## `descriptionMaxChars` (type: `integer`):

0 = full description.

## `ats` (type: `string`):

Which ATS a bare token like <code>stripe</code> belongs to. URLs and prefixed tokens are always detected from the URL.

## `probeAllAts` (type: `boolean`):

By default a bare token stops at the first ATS with a matching board (Greenhouse, then Lever, then Ashby).

## `maxConcurrency` (type: `integer`):

Boards fetched in parallel. Requests to the same API host are also spaced out politely.

## `maxRetries` (type: `integer`):

Retries on HTTP 429 (honouring Retry-After), 5xx, timeouts and network errors, with exponential backoff.

## Actor input object example

```json
{
  "companies": [
    "https://job-boards.greenhouse.io/airbnb",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/linear"
  ],
  "mode": "all",
  "firstRun": "deliver",
  "includeRemoved": false,
  "keywordsIn": "title",
  "remote": "any",
  "postedWithinDays": 0,
  "salaryOnly": false,
  "maxResults": 30,
  "maxJobsPerCompany": 10,
  "descriptionFormat": "both",
  "descriptionMaxChars": 0,
  "ats": "auto",
  "probeAllAts": false,
  "maxConcurrency": 3,
  "maxRetries": 4
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset of job postings from the Greenhouse, Lever and Ashby boards you entered, one item per job in one normalized schema (type job). In new-jobs mode only jobs not seen in earlier runs are returned. Boards that fail appear as free type error items.

## `summary` (type: `string`):

SUMMARY record: mode, companies OK and failed, jobs on boards, matched and delivered, charged jobs, jobs skipped as already seen, removed jobs and any run-level errorCode.

# 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://job-boards.greenhouse.io/airbnb",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/linear"
    ],
    "maxResults": 30,
    "maxJobsPerCompany": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor").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://job-boards.greenhouse.io/airbnb",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/linear",
    ],
    "maxResults": 30,
    "maxJobsPerCompany": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor").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://job-boards.greenhouse.io/airbnb",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/linear"
  ],
  "maxResults": 30,
  "maxJobsPerCompany": 10
}' |
apify call hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hanielazevedo/greenhouse-lever-ashby-new-jobs-monitor"
        }
    }
}
```

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/p1K3vuQE6BbuzBoTS/builds/5sfocZUimZylKKwHB/openapi.json
