# Greenhouse Jobs Lookup — Live Postings by Company (`accountable_eel/greenhouse-jobs-lookup`) Actor

Look up any company's live Greenhouse job board and get every open role — title, location, department, apply link. Paste company names or URLs, press Start. Charged once per company checked, no matter how many roles it has open — none open costs nothing.

- **URL**: https://apify.com/accountable\_eel/greenhouse-jobs-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 successful lookups

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Greenhouse Jobs Lookup — Live Postings by Company

Paste a list of companies and get every open role from each one's **Greenhouse** job board —
title, location, department, and apply link — as one row per posting, or one row per company.
No API key and no HTML scraping: this reads Greenhouse's own public job board API directly.
Optional filters narrow results by title, location, or posting date, and a delta mode returns
only the postings that are new since your last run.

### Who it's for

The accountable\_eel catalogue sells company intelligence columns for outbound. Each actor takes a
list of domains or company identifiers and returns one flat, stably-named row per input —
firmographics, registry IDs, tech stack, email route, hiring activity — the shape a Clay table, an
n8n workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event and
per-domain: a few tenths of a cent for a row that was actually found, and nothing for a
miss, so a list that doesn't enrich costs you next to nothing. Where an official source exists —
VIES, GLEIF, SEC EDGAR, Brønnøysund, PRH, RDAP — it is queried directly instead of scraped. No
seat licence, no monthly minimum, no credit system to decode. Here, the "identifier" is a
Greenhouse board token or careers URL, and the "row" is a job posting — useful for sourcing
candidates, watching a competitor's hiring, or tracking headcount signal across a target list.

### Why this one

- **Direct from Greenhouse's own API.** No HTML scraping to break when a careers page gets
  redesigned — this calls `boards-api.greenhouse.io` the same way Greenhouse's own careers pages
  do.
- **You pay per company, not per job.** A board with 578 open roles and a board with 2 both cost
  one `item-lookup` charge. A company with no board, or zero open roles, is a free miss.
- **Real filters, not a wall of raw fields.** Title keyword include/exclude, location, remote-only,
  and posted-after-date all combine, so you can ask for exactly the roles you want instead of
  filtering 578 rows by hand afterward.
- **A delta mode for watching hiring over time.** Turn on `onlyNewSinceLastRun`, put the actor on a
  schedule, and every run after the first returns only postings you haven't seen — a quiet week
  still gets a row, so you can tell "nothing new" from "the run broke."
- **Flexible input.** A bare Greenhouse token or the full `boards.greenhouse.io` /
  `job-boards.greenhouse.io` careers URL both work — no need to go find the raw API slug first.

### What you get

One row per open job posting by default — toggle "One row per job posting" off to get one row per
company instead, with the job list nested in `jobs`. The columns never move, whether or not
filters or delta mode are on:

| Field | Type / format | Description |
| --- | --- | --- |
| `query` | text | The company value you passed in, unchanged. |
| `found` | boolean | `true` if the company has a Greenhouse board with at least one open role. Gates billing. |
| `status` | text | `OK`, `NOT_FOUND` (no board or no open roles), or `BAD_FORMAT` (not a token or URL). |
| `boardToken` | text | The board token, extracted from whatever you pasted. |
| `jobCount` | number | Roles matched, after filters and delta filtering. |
| `totalJobCount` | number | Roles on the board before filtering — shows what a filter dropped. |
| `newJobs` | number | Roles new since your last run. Empty unless `onlyNewSinceLastRun` is on. |
| `firstRun` | boolean | `true` on the baseline run for a watchlist. Empty unless delta mode is on. |
| `jobs` | array | All matching jobs, each with the fields below. Expanded into separate rows in one-row-per-job mode. |
| `title` | text | Job title. |
| `location` | text | Office or region as Greenhouse lists it — e.g. "San Francisco", "Remote". |
| `departments` | array | Department name(s), fetched from the board's separate department listing. |
| `remote` | boolean | `true` if location or title reads as remote — matches "remote", "anywhere", "work from home", "wfh", "distributed". |
| `postedAt` | date (ISO) | When Greenhouse first published the posting, falling back to `updated_at`. |
| `updatedAt` | date (ISO) | When the posting was last edited. |
| `applyUrl` | link | Direct apply link for the role. |
| `scrapedAt` | date (ISO) | When this actor fetched the row. |

A company with no board, or a board with zero open roles, still returns one row with
`found: false` and a `status`/`message` explaining why — never charged.

### Price

$5 per 1,000 companies, plus a $0.005 start fee. Misses (`found:false`) are never charged.

That works out to $0.005 per company whose board is found, on the FREE pricing tier (drops to
$0.003 on GOLD) — you're never billed for a company with no Greenhouse board or a `BAD_FORMAT`
input, no matter how many companies are in the list. However many roles a found company has open,
it's one charge: a board with 578 postings costs the same as one with 2.

**1,000 companies through this actor: ~$5** if every one has a findable Greenhouse board, less if
some don't. The same 1,000 rows through a credit-based enrichment platform: **$80–$400**. This
actor does one thing — Greenhouse postings — and prices accordingly; it isn't a substitute for a
general enrichment waterfall.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `companies` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~greenhouse-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"companies":["stripe"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

Paste one company per line — a bare Greenhouse token like `stripe`, or the full careers URL
(`https://boards.greenhouse.io/stripe` or `https://job-boards.greenhouse.io/stripe`). The token is
extracted automatically either way, so you don't need to go look up the raw API slug.

**Common ways teams use this:**

- **Source candidates** by pulling every open role matching a title keyword across a list of
  target companies in one pass.
- **Watch a competitor's hiring** with a fixed company list on a weekly schedule and delta mode
  on, so each run shows only what's new.
- **Score hiring momentum** across a target account list by reading `jobCount` per company in
  one-row-per-company mode.
- **Find roles in a specific market** by combining `locations` with `titleKeywords` instead of
  exporting everything and filtering by hand.
- **Feed an ATS-aware outbound sequence** by joining `applyUrl` and `postedAt` onto an existing
  account list in Clay or n8n.

For a standing watchlist, turn on **`onlyNewSinceLastRun`** in the **🔁 Watch for new jobs**
section and put the actor on a schedule. The first run baselines (returns everything matching your
filters, `firstRun: true`); every run after that returns only postings it hasn't shown you before,
counted in `newJobs`. A quiet run still returns a row per company (`jobCount: 0`, `newJobs: 0`) so
you can tell "nothing new" from "the run failed" — and every company checked is still charged
once. Two schedules with different filter values keep separate seen-lists automatically, so
changing `titleKeywords` mid-stream just re-baselines that watchlist rather than corrupting it.

### Input

```json
{
  "companies": [
    "stripe"
  ]
}
```

One company per line — paste the Greenhouse token or the full careers page URL. Accepted formats: stripe, https://boards.greenhouse.io/stripe, https://job-boards.greenhouse.io/stripe.

To narrow what comes back, open the **🎯 Job filters** section. All of these are optional, and
they combine with AND across fields, OR within a field:

| Input | What it does |
| --- | --- |
| `titleKeywords` | Keep only roles whose title contains at least one of these — `["engineer","designer"]`. Case-insensitive, partial words count. |
| `excludeTitleKeywords` | Drop roles whose title contains one of these — `["intern","contract"]`. Applied after `titleKeywords`. |
| `locations` | Keep only roles whose location contains one of these — `["Berlin","United Kingdom"]`. |
| `remoteOnly` | Keep only roles that read as remote. |
| `postedAfter` | Keep only roles first published on or after this date — `"2026-06-01"`. |

Leave every filter empty and you get every open role. `jobCount` (matched) and `totalJobCount`
(before filtering) both come back on every row, so a filtered result is never ambiguous — and a
company whose roles all get filtered out still returns a `found: true` row with `jobCount: 0`,
charged like any other found company, because it answered the question you asked.

### Sample output

| query | found | status | boardToken | jobCount | totalJobCount | newJobs | firstRun | jobs | title | location | departments | remote | postedAt | updatedAt | applyUrl | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| stripe | true | OK | stripe | 589 | 589 |  |  | \<all matching jobs (full list)> | Account Executive, AI Sales | San Francisco, CA | \["1175 Enterprise - Account Executives (NA)"] | false | 2026-02-03T15:19:01-05:00 | 2026-08-25T17:40:40-04:00 | https://stripe.com/jobs/search?gh\_jid=7532733 | 2026-08-26T06:00:44.199Z |

That table lists every available column. In "one row per job posting" mode — the default — a real
row reads like this:

```json
{
  "query": "stripe",
  "found": true,
  "status": "OK",
  "boardToken": "stripe",
  "jobCount": 589,
  "totalJobCount": 589,
  "title": "Account Executive, AI Sales",
  "location": "San Francisco, CA",
  "departments": ["1175 Enterprise - Account Executives (NA)"],
  "remote": false,
  "postedAt": "2026-02-03T15:19:01-05:00",
  "updatedAt": "2026-08-25T17:40:40-04:00",
  "applyUrl": "https://stripe.com/jobs/search?gh_jid=7532733",
  "scrapedAt": "2026-08-26T06:00:44.199Z"
}
```

A company with no Greenhouse board comes back as a miss and is never charged:

```json
{
  "query": "not-a-real-company",
  "found": false,
  "status": "NOT_FOUND",
  "message": "No Greenhouse board found for this token",
  "scrapedAt": "2026-08-26T06:00:44.199Z"
}
```

Miss rows are still written to the dataset so you can see exactly which companies failed, rather
than diffing your input list against the output.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~greenhouse-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"companies":["stripe"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~greenhouse-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"companies":["stripe"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~greenhouse-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"companies":["{{company}}"]}`, mapping the row's company into the `companies` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Greenhouse Jobs Lookup | Apify" — the agent will find and run this actor.

### Tips

- **Combine filters to build a watchlist query, not just a keyword search.** `titleKeywords: ["engineer"]` plus `locations: ["Berlin"]` plus `remoteOnly: false` gets you Berlin-based
  engineering roles only, in one pass, instead of filtering a full dump afterward.
- **Put delta mode on a weekly schedule for competitor tracking.** `onlyNewSinceLastRun` plus a
  fixed company list turns this into a hiring-alert feed — you only see what changed since last
  time, and a quiet week still confirms the schedule is running.
- **Use `postedAfter` for "what opened this month", not `updatedAt`.** Greenhouse bumps
  `updatedAt` on any edit, including typo fixes — `postedAt` only moves when a role first goes live.
- **Switch to one-row-per-company mode for a headcount signal.** Read `jobCount` per company
  without pulling every posting into your table.
- **Don't combine delta mode with "Only keep rows containing."** That filter runs on the finished
  row and can drop the `newJobs: 0` heartbeat row — the one row that tells you the schedule is
  still alive on a quiet week.

### vs. alternatives

| | What it costs | What you get | Trade-off |
|---|---|---|---|
| **This actor** (`greenhouse-jobs-lookup`) | $0.005 per company whose board is found (less on paid tiers), $0.005 actor start, nothing for a company with no Greenhouse board | Every open posting for a company's Greenhouse board — title, location, department, apply URL — filtered by role keyword, location or posting date, with `onlyNewSinceLastRun` for deltas | Greenhouse only. If your list is mixed-ATS, use `ats-jobs-unified-lookup`. Office data isn't returned — Greenhouse's own endpoint costs 78× the payload to include it. |
| **TheirStack** | $0.005–$0.03 per company | A job-postings dataset with history, normalised across many ATS platforms and job boards | Broader coverage than one platform, and it keeps history. This reads Greenhouse's own API live, at the bottom of that price range. |
| **Greenhouse's own API** | Free | The same JSON | It is the same JSON. This handles the board-token guessing, the second request departments actually live behind, filtering, deltas, and the retries — and hands you a flat table. |
| **Clay** | $0.08–$0.40 per enriched row in credits, on top of a seat | A whole enrichment workspace — waterfalls across dozens of providers, plus the table and the sequencing around it | If you want one place that does everything and you're not counting rows, that's Clay. This is one column, priced per column, callable *from* Clay via its HTTP step. |

Prices for third-party tools are their published list prices as of August 2026 and are not tracked
here — check the vendor before relying on the comparison.

### FAQ

**Why does `found` say false, or a row come back empty?**
Either the input didn't look like a Greenhouse token or URL (`status: BAD_FORMAT`), the company
doesn't have a Greenhouse board, or it currently has zero open roles (`status: NOT_FOUND` either
way). Check the `message` column for the specific reason.

**Was I charged for that row?**
Only if `found` is `true`. A company with no board, or no current openings, is free — check
`status` to confirm which case it was.

**I got charged for a company that returned `jobCount: 0` — why?**
Its board exists and has open roles; they just didn't match your filters, or weren't new since
your last delta run. `totalJobCount` shows what was on the board before filtering. That's a real
answer to the question you asked, so it bills like any other found company. A company with no
board, or nothing open, is `found: false` and free.

**How does delta state work, and can I reset it?**
It lives in a named key-value store, `greenhouse-jobs-lookup-state`, inside your own Apify account
— nobody else can see it, and it holds only job IDs per company. Delete that store to reset every
watchlist. Changing your filters also starts a fresh watchlist automatically, since the filter
values are part of what identifies a seen-list.

**Why is there no office field, and where do departments come from?**
Greenhouse's job-listing endpoint omits both unless you request its heavyweight response, which
inlines every job's full HTML description — a large payload multiplier on a board with hundreds of
roles. So `departments` is filled from one extra request to the board's separate department
listing; if that request fails, every role still comes back, just with an empty `departments`
cell. Offices aren't reported at all, because the only endpoints carrying them cost far more than
the field is worth — better no column than a permanently blank one. `location` carries the place
information, and `remoteOnly` matches on both `location` and `title`.

**Does this hit rate limits on large company lists?**
It calls Greenhouse's public board API once per company (twice with the departments hop), with its
own timeouts and retries. That API is unauthenticated and public — the same one Greenhouse's own
careers pages call — so no proxy is needed. Large lists just take proportionally longer.

**Is this GDPR-safe to run against EU companies?**
Everything returned is already published publicly on each company's own careers page — titles,
locations, departments, apply links. No personal data about applicants or employees is collected.
You remain responsible for how you use the output downstream.

**Can an AI agent call this directly?**
Yes — it's registered with the Apify MCP server. An agent with that MCP connected can find and run
"Greenhouse Jobs Lookup" by name and get dataset rows back without you writing any integration
code; see [Use it from Clay, n8n, Make, or an AI agent](#use-it-from-clay-n8n-make-or-an-ai-agent).

### Related actors

- [ATS Jobs Unified Lookup](https://apify.com/accountable_eel/ats-jobs-unified-lookup) — check a
  company across Greenhouse, Lever, Ashby, and other ATS platforms in one call when you don't know
  which one they use.
- [Lever Jobs Lookup](https://apify.com/accountable_eel/lever-jobs-lookup) — the same lookup, filters,
  and delta mode for companies on Lever.
- [Ashby Jobs Lookup](https://apify.com/accountable_eel/ashby-jobs-lookup) — the same lookup, filters,
  and delta mode for companies on Ashby.

# Actor input Schema

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

One company per line — paste the Greenhouse token or the full careers page URL. Accepted formats: stripe, https://boards.greenhouse.io/stripe, https://job-boards.greenhouse.io/stripe. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

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

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

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

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `titleKeywords` (type: `array`):

Optional. Keep only roles whose title contains at least one of these words — e.g. "engineer", "account executive", "designer". Case doesn't matter, and partial words work ("engineer" matches "Engineering Manager"). Leave empty to keep every role.

## `excludeTitleKeywords` (type: `array`):

Optional. Drop any role whose title contains one of these words — e.g. "intern", "senior", "contract". Applied after the include list above, so a role matching both is dropped.

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

Optional. Keep only roles whose location mentions one of these — e.g. "Berlin", "New York", "United Kingdom". Case doesn't matter and partial matches work. Leave empty to keep every location.

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

Keep only roles whose location or title says remote (also matches "anywhere", "work from home", "distributed"). Companies label remote work inconsistently, so treat this as a strong filter, not a guarantee.

## `postedAfter` (type: `string`):

Optional. A date like 2026-06-01 (or a full timestamp). Keeps only roles Greenhouse first published on or after it — useful for "what opened up this month". Leave empty for no date limit.

## `onlyNewSinceLastRun` (type: `boolean`):

Turn this on for a scheduled watchlist: the first run returns everything that matches and remembers it, and every run after that returns only postings it hasn't shown you before. A company with nothing new still gets a row (with 0 jobs), so a quiet schedule never looks like a broken one. Changing the filters above starts a fresh watchlist.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each job posting found gets its own row instead of being grouped under its company. You're still only charged once per company, no matter how many rows it produces.

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

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

## `proxyConfiguration` (type: `object`):

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "companies": [
    "stripe"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "locations": [],
  "remoteOnly": false,
  "postedAfter": "",
  "onlyNewSinceLastRun": false,
  "columns": [
    "boardToken",
    "jobCount",
    "totalJobCount",
    "newJobs",
    "firstRun",
    "jobs",
    "title",
    "location",
    "departments",
    "remote",
    "postedAt",
    "updatedAt",
    "applyUrl"
  ],
  "expandRows": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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": [
        "stripe"
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "locations": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/greenhouse-jobs-lookup").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": ["stripe"],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "locations": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/greenhouse-jobs-lookup").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": [
    "stripe"
  ],
  "includeKeywords": [],
  "excludeKeywords": [],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "locations": []
}' |
apify call accountable_eel/greenhouse-jobs-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/greenhouse-jobs-lookup"
        }
    }
}

```

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/L3ecPdIBsK5AkOKae/builds/bMdfrexVtJWqL0DoI/openapi.json
