# Career Site Job Feed API: 2.5M+ Jobs, 50K+ Sites, from $1.50/1K (`tidelane/career-site-job-feed`) Actor

2.5M+ open jobs from 50,000+ company career sites on 18 systems (Greenhouse, Lever, Ashby, Workday, Workable, BambooHR, ADP, Paylocity and more), from $1.50 per 1,000 jobs. Filter by title, country, remote, salary and date; get only jobs new since your last run. JSON, CSV, API, MCP.

- **URL**: https://apify.com/tidelane/career-site-job-feed.md
- **Developed by:** [Tidelane Data](https://apify.com/tidelane) (community)
- **Categories:** Jobs, Automation, Lead generation
- **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.
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?

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

## Career Site Job Feed API: 2.5M+ Jobs, 50K+ Sites

Search open jobs from **more than 50,000 company career sites** in one run, without knowing which companies to look at, from **$1.50 per 1,000 jobs**. The feed is collected every day (Workable and Paylocity every 2 to 4 days) from the public job board APIs and job lists of 18 applicant tracking systems: Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters, Recruitee, Personio, BambooHR, Rippling, Oracle, Teamtailor, Pinpoint, Breezy HR, d.vinci, ADP, Paylocity, Jobvite. You filter it by title, country, city, remote, salary, posting date and description words and get clean, normalized jobs in seconds.

- ✅ **2.5M+ open jobs from 50,000+ company career sites** (2,858,067 jobs from 52,223 sites on 27.10.2026), straight from the employers' own career sites (no recruiters' reposts, no aggregator duplicates)
- ✅ **18 applicant tracking systems:** Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters, Recruitee, Personio, BambooHR, Rippling, Oracle, Teamtailor, Pinpoint, Breezy HR, d.vinci, ADP, Paylocity, Jobvite
- ✅ **Filters that matter:** title words and excluded words, countries (names or ISO codes, derived from cities and states too), location text, remote / hybrid / on-site, company names, posted within N days, new in the feed within N hours, salary published, words in the description
- ✅ **Extra fields and filters, no AI costs:** seniority (intern to executive), years of experience asked, skills (about 110 tools and technologies), yearly salary (hourly and monthly pay converted), visa sponsorship and the ad's language. Filter for example on senior Python jobs, roles asking at most 2 years, jobs offering visa sponsorship or pay from 100,000 USD a year
- ✅ **Only new jobs:** schedule it daily with *Only jobs new since my last run* and get just the jobs you have not seen yet
- ✅ **One schema:** title, company, location(s), countries, workplace type, employment type, salary range when published, posted date, first-seen date, job and apply links. Description words are searched in the full ad text, and each result lists the words it matched
- ✅ **Fast:** a search over the whole feed takes well under a minute; you pay only for the jobs you get

### What can you use it for?

- **Niche job boards:** fill a board for one role, region or industry (for example remote data jobs in Europe) with fresh jobs every morning
- **Recruiting and sales intelligence:** find every company that is hiring for a role right now, a strong buying signal for B2B sales
- **Job alerts:** a daily schedule with *only new jobs* and a webhook to Slack, email or Google Sheets
- **Market and salary research:** count openings by country, workplace type or title; collect published salary ranges
- **AI agents and RAG:** give an agent current, structured job data through the Apify API or MCP

### How to use it

1. Set the filters you need, for example title keywords `software engineer` and countries `United States`, `United Kingdom`.
2. Choose how many jobs you want in **Max results** (newest first).
3. Run, then download the results as JSON, CSV, Excel or HTML, or connect them to Google Sheets, Make, Zapier, n8n or your own code.
4. For alerts, turn on **Only jobs new since my last run**, give the search a name and create a daily schedule.

#### Input example

```json
{
    "titleKeywords": ["data engineer", "analytics engineer"],
    "titleExcludeKeywords": ["intern"],
    "countries": ["Germany", "Netherlands"],
    "workplace": "remote_or_hybrid",
    "postedWithinDays": 14,
    "maxResults": 500
}
```

#### Output example

```json
{
    "title": "Junior/Medior Maintenance Engineer",
    "companyName": "VolkerRail",
    "location": "Vianen, Utrecht, Nederland",
    "locations": [
        "Vianen, Utrecht, Nederland",
        "Hoofdkantoor"
    ],
    "countries": [
        "NL"
    ],
    "workplaceType": "hybrid",
    "remote": false,
    "employmentType": "fulltime_fixed_term",
    "department": "Engineering & Ontwerp",
    "team": null,
    "salary": {
        "min": 3900,
        "max": 5400,
        "currency": "EUR",
        "interval": "month",
        "text": null
    },
    "postedAt": "2026-10-14T07:11:59.000Z",
    "firstSeenAt": "2026-10-21T06:44:08.688Z",
    "jobUrl": "https://volkerrail.recruitee.com/o/juniormedior-maintenance-engineer",
    "applyUrl": "https://volkerrail.recruitee.com/o/juniormedior-maintenance-engineer/c/new",
    "ats": "recruitee",
    "companySlug": "volkerrail",
    "jobId": "recruitee:volkerrail:2782873"
}
```

Fields a career site does not publish are `null`. `postedAt` is the date the career site reports; when it reports none, `firstSeenAt` (the day the feed first found the job) is used for sorting and the date filters. `countries` are ISO codes derived from the location texts, so `Munich`, `Bavaria` and `München, DE` all count as Germany. Jobs that only say *Remote* have no country.

Each run also saves a summary as `OUTPUT` in the key-value store: when the feed was updated, how many jobs it holds, how many matched and how many were returned.

### Pricing

You pay per job returned; searching the feed is free, so filters cost nothing. The price per job follows your Apify plan:

| Apify plan | Price per 1,000 jobs |
|---|---|
| Free | $3.00 |
| Starter | $2.50 |
| Scale | $2.00 |
| Business and higher | $1.50 |

Plus $0.00005 per run. Examples: 500 jobs cost $0.75 to $1.50; the free plan's monthly $5 credit covers about 1,600 jobs. Set **Max results** or a run spending limit to cap the cost of a run.

### FAQ

**How are seniority, experience and skills found?** With fixed rules from the title and the ad text, not AI, so they cost nothing extra and give the same answer every time. Seniority comes from the title (Senior, Junior, Head of, Werkstudent, ...) or, without such a word, from the years of experience the ad asks for. Experience is the first "3+ years" or "mindestens 3 Jahre" the ad links to experience. Visa sponsorship is `true` or `false` only when the ad says so, otherwise `null`.

**Which companies are in the feed?** Companies whose career site runs on one of the 18 systems above and that are publicly linked on the web. The list is built from the open Common Crawl web index and grows with every crawl. Missing a company? Use our *Career Site Jobs* Actor with the company's career page URL.

**How fresh is it?** 16 of the 18 systems are collected every day. Workable and Paylocity limit how fast they may be read, so their boards with open jobs are rechecked every 2 to 4 days and new boards join over time; a new job on those two systems can appear up to 4 days late. The `OUTPUT` summary of each run shows the time of the last update. Jobs that are closed disappear with the next check of their board.

**Why do some jobs have no company name?** ADP career sites do not publish the employer's name, so `companyName` is `null` for their jobs; the job and apply links lead to the employer's page.

**How does *Only jobs new since my last run* work?** The Actor remembers the IDs of the jobs it returned for the search name you give, in a key-value store named `career-job-feed-state` in your own account, and skips them next time. Use different names for different searches.

**Why does the description filter return fewer jobs than expected?** Descriptions are checked on the newest jobs that match your other filters (at least 5,000 or 20 times *Max results*). Narrow the other filters for broad description searches. A small share of Workday, Greenhouse and SmartRecruiters jobs that appeared within the last day may not have a description yet; it is added in the next update.

**Why is there no full job description in the results?** The ad texts belong to the employers. The feed searches them for your description words and gives you the structured facts and the link to the original posting, where the full text is always up to date. If you need the full texts of specific companies, our *Career Site Jobs* Actor reads them live from the career sites.

**Is it legal?** The feed uses the public job board APIs that these systems publish so that companies' job ads can be found, plus the public job lists of career sites on systems such as Workday, Oracle and ADP. It returns structured facts and links, not the ad texts, and no personal data. You are responsible for how you use the data. If in doubt, ask a lawyer.

If this Actor saves you time, a short review on its Store page helps others find it. Found a bug or need a filter? Open an issue on the Actor page.

### More job data from Tidelane Data

- [Remote Jobs Feed API](https://apify.com/tidelane/remote-jobs-feed): remote jobs by where you may work from (anywhere, Europe, US, a country)
- [Career Site Jobs Scraper](https://apify.com/tidelane/career-site-jobs): every job of the companies you name, from 18 career site systems
- [Greenhouse Jobs Scraper & API](https://apify.com/tidelane/greenhouse-jobs): every job of the Greenhouse boards you name
- [Lever Jobs Scraper & API](https://apify.com/tidelane/lever-jobs): every job of the Lever boards you name
- [Ashby Jobs Scraper & API](https://apify.com/tidelane/ashby-jobs): every job of the Ashby boards you name
- [Workday Jobs Scraper & API](https://apify.com/tidelane/workday-jobs): every job of the Workday sites you name, also past 2,000 jobs

***

#### Impressum (Angaben gemäß § 5 DDG)

Levi Griesinger, Tidelane Data\
Besigheimer Straße 18\
74369, Löchgau, Deutschland\
E-Mail: LeviGriesinger@gmail.com

# Actor input Schema

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

Keep jobs whose title contains at least one of these words. A word matches at the start of a word, so engineer also finds Engineering. Case and accents are ignored. Leave empty for all titles.

## `titleExcludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words, e.g. intern, senior, manager.

## `countries` (type: `array`):

Keep jobs in at least one of these countries. Use names (Germany, United Kingdom) or ISO codes (DE, GB). The country is derived from the job's location; jobs that only say 'Remote' have no country.

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

Keep jobs whose location text contains one of these, e.g. Berlin, London, EMEA. Case and accents are ignored.

## `workplace` (type: `string`):

Remote, hybrid or on-site, as published by the company.

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

Keep jobs of companies whose name or board slug contains one of these texts.

## `ats` (type: `array`):

Limit to some systems. Leave empty for all.

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

Keep jobs posted in the last N days. Jobs without a posting date count from the day the feed first saw them. 0 means no date filter.

## `newInFeedWithinHours` (type: `integer`):

Keep jobs the feed first saw in the last N hours, e.g. 24 for jobs that appeared since yesterday. 0 means no filter.

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

Keep only jobs that publish a salary range.

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

Keep jobs of these levels. The level comes from the job title (e.g. Senior, Junior, Head of, Werkstudent) or, without a title word, from the years of experience the ad asks for.

## `skills` (type: `array`):

Keep jobs that mention at least one of these skills, e.g. Python, React, SAP, Excel, AutoCAD. Matching uses our list of about 110 common tools and technologies (see the README).

## `maxExperienceYears` (type: `integer`):

Keep jobs that ask for at most this many years of experience, e.g. 2 for junior roles. Jobs that state no number pass. 0 means no filter.

## `visaSponsorshipOnly` (type: `boolean`):

Keep only jobs whose ad says visa sponsorship or visa support is available.

## `languages` (type: `array`):

Keep jobs whose ad is written in one of these languages.

## `minYearlySalary` (type: `integer`):

Keep jobs whose published pay reaches at least this amount per year (hourly, daily and monthly pay is converted to a year). Combine with the currency field. 0 means no filter.

## `salaryCurrency` (type: `string`):

3-letter currency code for the salary filter, e.g. USD, EUR or GBP. Leave empty for any currency.

## `descriptionKeywords` (type: `array`):

Keep jobs whose description contains at least one of these words, e.g. python, visa sponsorship. The full text is searched; each result lists the words it matched in matchedKeywords. Checked on the newest matches of the other filters (at least 5,000 or 20 times Max results).

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

Skip jobs this search already returned in an earlier run. Ideal for a daily schedule. The list of returned job IDs is kept in your own key-value store career-job-feed-state.

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

Give each scheduled search its own name, so two searches do not share their list of returned jobs.

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

Newest jobs first. Up to 100,000 per run.

## Actor input object example

```json
{
  "titleKeywords": [
    "software engineer"
  ],
  "countries": [
    "United States",
    "United Kingdom"
  ],
  "workplace": "any",
  "postedWithinDays": 14,
  "newInFeedWithinHours": 0,
  "salaryOnly": false,
  "visaSponsorshipOnly": false,
  "onlyNewSinceLastRun": false,
  "maxResults": 50
}
```

# Actor output Schema

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

All results of the run as dataset items.

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

Summary per input with status (ok, error and the reason).

# 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 = {
    "titleKeywords": [
        "software engineer"
    ],
    "countries": [
        "United States",
        "United Kingdom"
    ],
    "postedWithinDays": 14,
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidelane/career-site-job-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 = {
    "titleKeywords": ["software engineer"],
    "countries": [
        "United States",
        "United Kingdom",
    ],
    "postedWithinDays": 14,
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("tidelane/career-site-job-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 '{
  "titleKeywords": [
    "software engineer"
  ],
  "countries": [
    "United States",
    "United Kingdom"
  ],
  "postedWithinDays": 14,
  "maxResults": 50
}' |
apify call tidelane/career-site-job-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tidelane/career-site-job-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/stT86aCv3OEIuYkjB/builds/if8Ybeh6XWrXhMvZl/openapi.json
