# Job Monitor - New Job Alerts from Career Pages (`firsthand-data/career-page-job-monitor`) Actor

Monitor company career pages for new jobs: each run returns only jobs posted or closed since the last run. Watch your own companies on Greenhouse, Lever, Ashby and SmartRecruiters or 2,878 ready-made ones (remote-first, startups). Schedule it for daily job alerts in Slack, email or Zapier.

- **URL**: https://apify.com/firsthand-data/career-page-job-monitor.md
- **Developed by:** [Firsthand Data](https://apify.com/firsthand-data) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Job Monitor - New Job Alerts from Career Pages

**Get the new jobs from the companies you care about, every morning, straight from their career
pages.** Add your own companies, pick a ready-made list (**1,040 remote-first companies** and
**2,344 startups**, about 900 new jobs a day between them), or both. Every run reads each company's
own hiring system (Greenhouse, Lever, Ashby or SmartRecruiters), remembers what it has already shown
you and returns only the jobs that are new or closed since the last run. Put it on a daily schedule
and get the new jobs in Slack, email, Zapier, Make, n8n or your own webhook.

**Example output.** On October 21, 2026 the first run of a new watch on the four demo companies
returned the 19 jobs they posted in the last 7 days; four of them are below. A second run right
after it returned 0 new jobs and cost nothing.

| Status | Company | Title | Location | Workplace | Salary | Published |
|---|---|---|---|---|---|---|
| new | Linear | Solutions Engineer, APAC | Singapore | remote | | 2026-10-21 |
| new | Gcore | Security Engineer (IT Security) | Poland, Serbia, Georgia, Cyprus | remote | | 2026-10-20 |
| new | PointClickCare | Intermediate Site Reliability Engineer (SRE) | Salt Lake City, UT | hybrid | 138,000-154,000 USD | 2026-10-19 |
| new | Tailscale | Program Manager, EPD Operations | Remote (United States) | remote | 114,000-143,000 USD | 2026-10-17 |

**Try it free in a minute.** Click **Try for free**, then **Start**: in about 5 seconds you see all
current jobs of the four demo companies. The Apify free plan needs no credit card, and its $5 of
credit every month covers about 2,500 new jobs at $2 per 1,000. Then put in your own companies, give
the watch a name of your own and put it on a schedule, step by step below.

**More job data from Firsthand Data:**
[Career Page Jobs Scraper](https://apify.com/firsthand-data/career-page-jobs-scraper) for every open
job of any company, [Remote Jobs Scraper](https://apify.com/firsthand-data/remote-jobs-scraper) for
1,040 remote-first companies and
[Startup Jobs Scraper](https://apify.com/firsthand-data/startup-jobs-scraper) for 2,344 startups on
Ashby.

### Why use Job Monitor?

- ✅ Only-new mode is on by default: every run returns the jobs that are new or closed since the previous run
- ✅ The first run returns the jobs of the last 7 days and remembers all other current jobs for free: fresh jobs at once, no bill for the backlog
- ✅ Any company on Greenhouse, Lever, Ashby or SmartRecruiters: by board name, job board link or company website
- ✅ Ready-made lists of 2,878 companies, checked by us and refreshed monthly: 61,437 open jobs and about 913 new a day on October 20, 2026
- ✅ Filters by words in the job title, locations and remote
- ✅ Every alert has title, team, location, remote, hybrid or on-site, salary as numbers, date, direct link and description
- ✅ You pay only for new jobs: closed rows are free, and a day without new jobs costs nothing
- ✅ The run status says how many jobs are new and closed, ready for a Slack message or an email
- ✅ Official public job board APIs: no login, no API key, no proxies, no browser
- ✅ No personal data: recruiter fields are dropped, emails and phone numbers are removed from descriptions
- 💲 **$2 per 1,000 new jobs.** The Apify free plan ($5 of credit every month) covers about 2,500 jobs.

### What can you monitor?

- **Job seekers.** Get an alert the day the companies you want to work for post a role in your field.
- **Recruiters and agencies.** New roles at your target accounts are new business: see them first.
- **Sales teams (hiring signals).** A company that opens five sales roles is growing. Reach out when
  your prospects start hiring for the teams you sell to.
- **Competitor intelligence.** See which teams your competitors grow, where and at what pay.
- **Job boards and newsletters.** A daily feed of fresh jobs with direct links; closed rows tell you
  which jobs to take down.
- **AI agents.** Let Claude, Cursor or any MCP client answer "what did these companies post since
  yesterday?" with live data.

### Set up job alerts in five minutes

1. Click **Try for free**. The Apify free plan needs no credit card.
2. In **Companies to monitor**, replace the four demo companies with the ones you want to watch, or
   pick a **Ready-made company list**. Optionally add title words, locations or **Remote jobs only**.
3. Keep **What to return** at **Only new and closed since the last run** and give the watch a name,
   for example `competitors`.
4. Click **Start**. The first run returns the jobs published in the last 7 days and remembers all
   other current jobs for free: this is your starting point.
5. Click **Save as new task**. In **Schedules**, add the task, pick a time (daily suits most feeds)
   and your time zone, and switch the schedule on: new schedules are created switched off.
6. In the task's **Integrations** tab, choose where the alerts go (next section).

From then on every run returns only the jobs that are new (`changeStatus: "new"`) or that
disappeared from the job board (`changeStatus: "closed"`). The same job is never returned as new
twice. Use a separate watch name for each feed.

### Where do the alerts go?

| Where | How to set it up | What you get |
|---|---|---|
| Slack | task **Integrations** tab: Slack, your channel, the "run succeeded" event | a message after every run; put `{{resource.statusMessage}}` in the message to see "12 new jobs, 3 closed from 2878 companies", plus a link to the results |
| Email | task **Integrations** tab: **Send results email via Gmail** | an email after every successful run with the jobs attached as a file |
| Zapier | trigger "Finished task run", then "Fetch dataset items" | one message per new job in Slack, email, Google Sheets, Airtable or any app Zapier connects |
| Make or n8n | start on a finished task run and read its dataset items | the same as Zapier |
| Webhook | task **Integrations** tab: HTTP webhook on "run succeeded" | a POST to your endpoint with the run and its dataset ID; read the jobs through the Apify API |

Slack and email messages come after every run, also when nothing is new: the status then says
"0 new jobs". Zapier, Make and n8n send nothing on a quiet day. Turn off **Include job
description** to keep messages short. Connect the alerts after the first run, so its week of jobs
does not flood your channel.

### How many new jobs will I get?

Both lists together on October 20, 2026. New jobs a day = jobs published in the 7 days before that
date, divided by 7.

| Feed (both lists) | Open jobs | New jobs a day | First run: the last 7 days | Then a month of daily runs |
|---|---|---|---|---|
| engineer, developer, DevOps or SRE in the title | 19,047 | about 268 | about $3.75 | about $16 |
| data, analytics, machine learning or AI | 6,323 | about 117 | about $1.64 | about $7 |
| sales, account executive, business development, SDR or BDR | 7,083 | about 108 | about $1.51 | about $6.50 |
| marketing, growth, SEO or content | 3,483 | about 56 | about $0.78 | about $3.40 |
| product manager or designer | 2,913 | about 44 | about $0.62 | about $2.60 |
| operations | 2,495 | about 43 | about $0.60 | about $2.60 |
| customer success or support | 1,860 | about 32 | about $0.45 | about $1.90 |
| remote jobs only | 26,243 | about 418 | about $5.85 | about $25 |
| location names the United States | 32,962 | about 453 | about $6.34 | about $27 |
| Europe (the UK, Germany, France, Spain and more) | 11,702 | about 191 | about $2.67 | about $11.50 |
| United Kingdom | 4,559 | about 75 | about $1.05 | about $4.50 |
| everything in both lists | 61,437 | about 913 | about $12.78 | about $55 |

The first run does not charge for the open jobs older than 7 days: it only remembers them. To pay
less, add title words or locations, lower **First run: jobs from the last N days** (0 starts the
watch without returning anything), or set **Maximum cost per run** in the run options: the monitor
stops before it goes over your limit, and the jobs it did not reach come in the next run.

The four prefilled companies under the default watch name are a demo: every run returns all their
current jobs (183 on October 20, 2026, about $0.37), so you see the output at once. Give the watch a
name of your own and they are monitored like any other companies.

### The ready-made lists

| List | Who is in it | Companies | Open jobs on October 20, 2026 | New jobs a day |
|---|---|---|---|---|
| Remote-first companies | at least half of open jobs are remote, 5 to 1,000 open jobs | 1,040 | 27,266 | about 420 |
| Startups on Ashby | companies that hire through Ashby, an applicant tracking system popular with venture-backed startups, with 1 to 300 open jobs | 2,344 | 44,625 | about 660 |
| Both lists | 506 companies are in both lists and are read once | 2,878 | 61,437 | about 913 |

The lists include Tailscale, Linear, Supabase, Ramp, Vanta, ElevenLabs, PostHog, n8n, GitLab,
Coinbase, Reddit and thousands more. We rebuild them every month from the live job boards, so
companies that stop hiring drop out and new ones come in.

### What data do you get?

| Field | Example | Notes |
|---|---|---|
| `changeStatus` | new | `new` or `closed` in only-new mode; empty in "All open jobs" mode |
| `company` | Tailscale | name from the job board |
| `title` | Analytics Engineer, Data | |
| `department`, `team` | Data | where the board gives it |
| `location`, `city`, `region`, `country` | Remote (United States) | `allLocations` keeps every location of the job |
| `workplaceType` | remote | `remote`, `hybrid`, `onsite` or `unknown` |
| `employmentType` | full_time | where the board gives it |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | 152000, 190000, USD | from salary fields or the description text |
| `salaryText` | original salary text | |
| `publishedAt`, `updatedAt` | 2026-08-04T18:21:42.000Z | |
| `url`, `applyUrl` | link to the job on the company's job board | |
| `description` | plain text | emails and phone numbers removed |
| `id`, `source`, `board`, `sourceJobId` | greenhouse:tailscale:4612... | stable id: the same job keeps it in every run |
| `scrapedAt` | time of the run | |

A closed row is short and free: `id`, `source`, `board`, `sourceJobId`, `company`,
`changeStatus: "closed"` and `scrapedAt`. Closed rows cover every job the watch remembers, also the
older jobs it remembered on the first run.

Jobs from the prefilled demo input on October 20, 2026:

| Company | Title | Location | Workplace | Salary | Published |
|---|---|---|---|---|---|
| Gcore | DevOps Engineer/SRE (Cloud IaaS) | Serbia, Cyprus, Georgia | remote | | 2026-10-16 |
| Tailscale | Analytics Engineer, Data | Remote (United States) | remote | 152,000-190,000 USD | 2026-08-04 |
| PointClickCare | (Canada) Principal ML System Engineer | Remote or Mississauga | remote | 179,000-224,000 CAD | 2026-08-13 |
| Linear | Senior / Staff Fullstack Engineer | Europe | remote | | 2021-04-27 |

Under a watch name of its own, the first run of the same four companies on October 21, 2026
returned 19 new jobs of the last 7 days and remembered 166 older ones without a charge; the second
run returned 0 new and 0 closed jobs and cost nothing. Empty cells are values the company does not publish. Some companies keep
evergreen jobs open for years: `publishedAt` shows when the job was first posted.

### How much does it cost?

- **$2 per 1,000 new jobs** (pay per event). Apify platform usage is included in the price.
- **Free:** closed-job rows, runs and companies without new jobs, companies that are not found, errors.
- The first run of a watch returns the matching jobs of the last 7 days and remembers the older ones
  for free; after that you pay only for jobs that are new.
- The Apify free plan gives $5 of credit every month: about 2,500 jobs.
- Set **Maximum cost per run** in the run options: the monitor stops before it goes over your limit.

**How often should I run it?** Once a day suits most feeds: a company posts a few jobs a week. If
you need faster alerts, run it every few hours: you still pay only for new jobs.

### Input

#### Companies

Use your own companies, a ready-made list, or both. Three ways to add a company:

| You write | Example | What happens |
|---|---|---|
| `system:board` | `greenhouse:tailscale`, `lever:pointclickcare`, `ashby:linear`, `smartrecruiters:gcore` | read directly |
| Job board link | `https://jobs.ashbyhq.com/linear` | read directly |
| Company website | `tailscale.com` | the monitor looks for a job board link on the website; if there is none, it tries the domain name as a board name and says so in the run summary |

The same company written twice (in any letter case, as different links or also in a list) is read
and charged once.

#### Example input

```json
{
  "companies": ["greenhouse:tailscale", "https://jobs.lever.co/pointclickcare", "linear.app"],
  "companyLists": ["startups"],
  "mode": "changes",
  "watchName": "design-europe",
  "firstRunDays": 7,
  "includeKeywords": ["designer", "product manager"],
  "excludeKeywords": ["intern"],
  "locations": ["Europe", "United Kingdom", "Germany"],
  "remoteOnly": false,
  "includeDescription": true
}
```

#### Watch name and memory

The monitor keeps its memory in a key-value store in your own Apify account, named
`firsthand-job-monitor-<watch name>`. To start a watch from scratch, use a new watch name or
delete that store. Jobs not seen for 90 days are forgotten automatically.

**First run: jobs from the last N days** (7 by default) decides what a new watch returns: jobs
published in the last N days come as new, all other current jobs are remembered without a charge.
The same rule applies the first time a watch sees a company you add later. Set 0 to start a watch
silently, or 3650 to get every current job once.

#### Run summary

Each run saves a summary to the key-value store record `OUTPUT`: for every company the system,
board, status (`ok`, `not_found` or `error`), the number of new and closed jobs and a note when
something needs your attention. A company that fails never stops the run.

### Which job boards are supported?

| System | Board link | Notes |
|---|---|---|
| Greenhouse | `boards.greenhouse.io/{board}`, `job-boards.greenhouse.io/{board}` | salary is often found in the description text |
| Lever | `jobs.lever.co/{board}` | salary range where the company publishes it |
| Ashby | `jobs.ashbyhq.com/{board}` | unlisted jobs are skipped |
| SmartRecruiters | `jobs.smartrecruiters.com/{board}` | public jobs only; each description is a separate request |

Job boards hosted in the EU (`eu.greenhouse.io`, `jobs.eu.lever.co`) are not supported yet.

### Use it with AI agents (MCP)

This monitor works as a tool for AI agents through the Apify MCP server: Claude, Cursor, VS Code,
n8n and other MCP clients. Add this URL as a remote MCP server and sign in to Apify when your
browser opens:

```
https://mcp.apify.com?tools=firsthand-data/career-page-job-monitor
```

Then ask, for example, "what new jobs did Linear and Tailscale post since yesterday?". The memory
works for agents too: every call with the same watch name returns only what is new. Turn off
**Include job description** to keep answers short.

### Fair use and data quality

- Reads only the official public job board APIs that these systems provide for career pages.
- Keeps to each source's rules: SmartRecruiters at most about 9 requests per second (their limit
  is 10), Lever job pages at most one request per second (their robots.txt), company websites
  only where robots.txt allows.
- No logins, no proxies, no hidden or unlisted jobs.
- No personal data: recruiter names and photos are not collected; emails and phone numbers are
  removed from descriptions.
- Results and the monitor's memory stay in your own Apify account. We do not keep copies.
- Not affiliated with Greenhouse, Lever, Ashby or SmartRecruiters, or with the companies in the
  lists. Their names are trademarks of their owners.

### FAQ

**How does the monitor know a job is new?**
Every job has a stable id on its job board. The monitor remembers each id it has returned under the
watch name; a job is new when its id was never returned before.

**What does the first run return?**
The jobs published in the last 7 days that match your filters. All other current jobs are
remembered for free, so later runs return only what changed. Change the window in **First run: jobs
from the last N days**: 0 starts silently, 3650 returns every current job once.

**What if a job board is down during a run?**
The company gets status `error` in the run summary, and its jobs are not reported as closed. The
next run compares again from the same memory.

**A company re-posted a job. Is it new?**
If the job board gave it a new id, yes: it comes as new, and the old one as closed.

**Can I change the companies or filters of a watch?**
Yes. Added companies follow the first-run rule: their jobs of the last 7 days come as new on the
next run, older ones are remembered. Jobs that your new filters hide are not reported as closed:
they are still open.

**What if I leave Companies empty and pick no list?**
The run does not fail. With title words or locations it monitors both lists in only-new mode;
without any filter it runs the four sample companies as a demo (all their current jobs, about
$0.37), so an empty call through the API or an AI agent never costs the price of the whole lists.

**Do I need an API key or a proxy?**
No. All four systems publish open jobs through public job board endpoints.

**How fresh is the data?**
Live: every run reads each job board at that moment.

### Changelog and support

- **0.1 (October 2026):** first public version: only-new monitoring by default, two ready-made
  lists (2,878 companies), run status with new and closed counts, title, location and remote filters.
- **0.1.2 (October 21, 2026):** the first run returns the jobs of the last 7 days and remembers the
  rest for free (new field **First run: jobs from the last N days**); the four prefilled companies
  under the default watch name are a demo and return all their current jobs on every run.
- We add output fields; we do not rename or remove them. Price changes are announced in advance.
- Questions, bugs or a company you want in the lists: open an issue on the **Issues** tab. We
  usually answer within 1-3 days.
- If this monitor saved you time, a short review helps other people find it. Thank you!

# Actor input Schema

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

One company per line: "system:board" (greenhouse:tailscale, lever:pointclickcare, ashby:linear, smartrecruiters:gcore), a job board link (https://jobs.ashbyhq.com/linear) or the company website (tailscale.com) - the monitor finds the job board itself. Works with companies on Greenhouse, Lever, Ashby and SmartRecruiters. The four prefilled companies under the default watch name are a demo: they return all their current jobs on every run.

## `companyLists` (type: `array`):

Monitor whole lists checked by us and refreshed monthly. On Oct 20, 2026: 1,040 remote-first companies (27,266 open jobs, about 420 new a day) and 2,344 startups on Ashby (44,625 open jobs, about 660 new a day). The first run returns the jobs of the last 7 days and remembers the rest for free (see First run below); add title filters to get fewer jobs.

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

Only jobs that are new or closed since the previous run with the same watch name (you pay only for new jobs; closed rows are free), or all open jobs every run. In only-new mode the first run returns the jobs published in the last 7 days and remembers all other current jobs for free (see First run below).

## `watchName` (type: `string`):

The monitor remembers what it already returned under this name. Use a different name for each feed, e.g. "competitors" or "remote-engineering".

## `firstRunDays` (type: `integer`):

On the first run of a watch, and the first time it sees a company you add later, the monitor returns only the jobs published in the last N days and remembers all other current jobs for free: you see fresh jobs at once and do not pay for the whole backlog. 0 = return nothing on the first run, only remember. 3650 = return all current jobs.

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

Keep only jobs whose title contains at least one of these words, e.g. "engineer", "designer", "sales". Case-insensitive. Empty - keep all jobs.

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

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

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

Keep only jobs whose location text, region or country contains one of these, e.g. "United States", "London", "Germany".

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

Keep only jobs the company marks as remote.

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

Plain-text description without emails and phone numbers. Turn off for shorter alerts and big lists.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:tailscale",
    "lever:pointclickcare",
    "ashby:linear",
    "smartrecruiters:gcore"
  ],
  "mode": "changes",
  "watchName": "default",
  "firstRunDays": 7,
  "remoteOnly": false,
  "includeDescription": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

Every job returned by this run. In the default mode: jobs that are new (changeStatus new) or closed (changeStatus closed) since the previous run, with company, title, department, location, workplace type, salary, dates, links and description.

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

For every company: job board system, board name, status (ok, not_found or error), number of new jobs, number of closed jobs and a note when something needs attention.

# 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:tailscale",
        "lever:pointclickcare",
        "ashby:linear",
        "smartrecruiters:gcore"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("firsthand-data/career-page-job-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": [
        "greenhouse:tailscale",
        "lever:pointclickcare",
        "ashby:linear",
        "smartrecruiters:gcore",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("firsthand-data/career-page-job-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": [
    "greenhouse:tailscale",
    "lever:pointclickcare",
    "ashby:linear",
    "smartrecruiters:gcore"
  ]
}' |
apify call firsthand-data/career-page-job-monitor --silent --output-dataset

```

## MCP server setup

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