# Career Page Jobs API (`asgardlabs/career-page-jobs-feed`) Actor

Every open job from company career sites on nine applicant-tracking systems (Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Personio, Recruitee, Workable, BambooHR), one schema, new-job flag. Half a cent per company, a third of a cent per job.

- **URL**: https://apify.com/asgardlabs/career-page-jobs-feed.md
- **Developed by:** [Asgard Labs](https://apify.com/asgardlabs) (community)
- **Stats:** 2 total users, 1 monthly users, 50.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?

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

## Career Page Jobs API – Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Personio, Recruitee, Workable, BambooHR

Give it a list of companies, as career-page links or short keys. Get every open job from each company's own career site in one identical format: title, department, location split into city, region and country, remote or hybrid, employment type, salary when published, posting date, apply link, full description.

Run it again with **only new** on and you get only the jobs it has not seen before. Schedule it daily and you have a hiring monitor for any watchlist of companies.

It reads the public job feeds of nine applicant-tracking systems. No proxies, no logins, no browser, no LinkedIn.

### Career page job data per posting

- **title, department, team, employmentType, url, applyUrl, postedAt, updatedAt**
- **location** – raw text plus city, region, country, remote flag, workplaceType (onsite / hybrid / remote); `all` lists every location when a job names several
- **salary** – min, max, currency, period (year / month / hour) and the raw text; structured when the system publishes it (Lever, Ashby), otherwise read from the description
- **descriptionHtml / descriptionText** when `includeDescription` is on
- **isNew, firstSeenAt** – whether this run saw the job for the first time, and when it was first seen
- **provider, company, jobId, id** – `id` is stable across runs (`greenhouse:stripe:7201641`)

### Use cases

- Job boards and aggregators.
- Recruiters watching target companies.
- Sales teams using hiring as a buying signal.
- Market researchers.

### Input

| Field | Default | Meaning |
|---|---|---|
| `companies` | – | Career-site URLs or short keys: `greenhouse:stripe`, `ashby:openai`, `lever:palantir`, `workday:nvidia.wd5/NVIDIAExternalCareerSite`, `https://bunq.recruitee.com`. The same company written several ways counts once. |
| `includeDescription` | true | Full description. Workday, SmartRecruiters, Workable and BambooHR need one extra request per job; those run five at a time. |
| `onlyNew` | false | Output only jobs not seen in earlier runs. The seen list lives in a key-value store per company. |
| `keywords`, `excludeKeywords` | – | Match on title, department and description. Jobs hidden by a filter are not marked seen, so widening the filter later surfaces them as new. |
| `locations` | – | Substring match on city, region, country, e.g. "Berlin", "United States". |
| `remoteOnly` | false | Remote jobs only. |
| `postedWithinDays` | – | Skip older jobs when the system publishes a date. |
| `maxJobsPerCompany` | 0 | 0 = all. With `onlyNew`, each run returns the next N unseen jobs. |
| `timeoutSecs` | 600 | Time budget per company. |
| `concurrency` | 4 | Companies read in parallel. |
| `stateStoreName` | ats-jobs-state | Where the seen list lives. Use a different name for a separate watchlist. |

### Output example

```json
{ "id": "greenhouse:stripe:7201641", "provider": "greenhouse", "company": "stripe", "jobId": "7201641",
  "title": "Backend Engineer", "department": "Engineering", "team": null,
  "location": { "raw": "Dublin, Ireland", "city": "Dublin", "region": null, "country": "Ireland", "remote": false, "workplaceType": "onsite", "all": [] },
  "employmentType": "Full-time", "url": "https://...", "applyUrl": "https://...",
  "postedAt": "2026-08-30T10:00:00.000Z", "updatedAt": null,
  "salary": { "min": 150000, "max": 225000, "currency": "USD", "period": "year", "raw": "$150,000 - $225,000" },
  "descriptionHtml": "...", "descriptionText": "...", "extra": {},
  "firstSeenAt": "2026-09-05T00:00:00.000Z", "isNew": true }
```

### How to use

1. Paste your career-site links or `provider:key` entries, one per line into the input form. The example input is ready to run as is.
2. Click **Start**. Rows appear in the **Output** tab as they are found.
3. Download the table as CSV, JSON or Excel, or read it through the API.
4. For monitoring, create a **Schedule** and switch on `onlyNew`: later runs return only what changed, and only that is charged.

### Pricing

Pay per event: **`company-scan` $0.005** per company that was read, **`job` $0.003** per job in the output. A 50-company watchlist with 2,000 jobs is about $6.25 for the first full pull; a daily `onlyNew` run that finds 50 new jobs is about $0.40. Companies that fail (wrong key, dead domain, feed switched off) are free.

### Good to know

- **Supported systems:** Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Personio, Recruitee, Workable, BambooHR. Not yet: Teamtailor, Jobvite, iCIMS, Taleo, SuccessFactors.
- **Salary** is only as good as the posting. Structured ranges from Lever and Ashby are exact; ranges read from descriptions carry the matched text in `raw` so you can check them.
- **Location** is parsed from free text. `raw` is always kept; a country is only filled when it is recognised.
- **Errors are in plain words:** `not found` (wrong key), `ENOTFOUND (domain not found)`, `timeout (company budget 600 s)`.
- **Stopping at your spend limit** is clean: the seen list is saved and the summary written, so the next run continues without re-charging.

### Use from code or an AI agent

Every run can be started and read through the Apify API, the JavaScript and Python clients, or an AI agent with tool access. Open the **API** tab on this page for ready-made snippets. Pricing is per event, so an agent pays only for what it receives.

### FAQ

**Which career-page systems are covered?**
Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Personio, Recruitee, Workable and BambooHR. Teamtailor, iCIMS and Taleo are not covered yet.

**What if a company is not found?**
It is reported with a plain reason such as `not found` or `blocked (403)` and is not charged.

**Can I get only new jobs each run?**
Yes. Switch on `onlyNew`; job ids are remembered per company in your account and later runs return only postings not seen before.

**Is salary parsed?**
When the career page states it. Structured salary from Ashby, otherwise parsed from the description with amount, currency and period.

**Does it read LinkedIn?**
No. It reads the companies' own career pages, which is where the complete and current list lives.

# Actor input Schema

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

One entry per company. Accepts career-site URLs (https://boards.greenhouse.io/stripe, https://jobs.ashbyhq.com/openai, https://jobs.lever.co/<site>, https://<tenant>.wd5.myworkdayjobs.com/<site>, https://jobs.smartrecruiters.com/<Company>, https://<co>.jobs.personio.de, https://<co>.recruitee.com, https://apply.workable.com/<co>, https://<co>.bamboohr.com) or short keys like greenhouse:stripe, ashby:openai, workday:nvidia.wd5/NVIDIAExternalCareerSite.

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

Fetch job descriptions (HTML + plain text). Some providers need one extra request per job for this.

## `onlyNew` (type: `boolean`):

Remembers job IDs per company in a key-value store and outputs only jobs not seen before. Ideal for scheduled monitoring.

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

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

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

Drop jobs containing any of these.

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

Substring match on city/region/country, e.g. "Berlin", "United States".

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

Keep only jobs the ATS marks as remote or whose location says so.

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

Skip jobs older than N days (when the ATS exposes a date).

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

0 = unlimited. With onlyNew, each run returns the next N unseen jobs.

## `timeoutSecs` (type: `integer`):

A company that takes longer is reported as timed out and not charged. Large Workday tenants with descriptions can need several minutes.

## `concurrency` (type: `integer`):

How many companies to read at the same time.

## `stateStoreName` (type: `string`):

Key-value store in your account used for onlyNew diffing. Change it to keep separate watchlists. Letters, digits and dashes.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "ashby:openai",
    "workday:nvidia.wd5/NVIDIAExternalCareerSite"
  ],
  "includeDescription": true,
  "onlyNew": false,
  "keywords": [],
  "excludeKeywords": [],
  "locations": [],
  "remoteOnly": false,
  "maxJobsPerCompany": 50,
  "timeoutSecs": 600,
  "concurrency": 4,
  "stateStoreName": "ats-jobs-state"
}
```

# Actor output Schema

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

One row per job: title, company, provider, location, employment type, salary, description, dates, url, isNew.

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

Counts, skipped inputs with reasons, errors in plain words, charge-limit state.

# 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",
        "ashby:openai",
        "workday:nvidia.wd5/NVIDIAExternalCareerSite"
    ],
    "maxJobsPerCompany": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("asgardlabs/career-page-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:stripe",
        "ashby:openai",
        "workday:nvidia.wd5/NVIDIAExternalCareerSite",
    ],
    "maxJobsPerCompany": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("asgardlabs/career-page-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:stripe",
    "ashby:openai",
    "workday:nvidia.wd5/NVIDIAExternalCareerSite"
  ],
  "maxJobsPerCompany": 50
}' |
apify call asgardlabs/career-page-jobs-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,asgardlabs/career-page-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/Z0tNMw2vYhhFfZ87j/builds/hEunaUPw4aZemao7C/openapi.json
