New Job Alerts - Only Postings That Appeared Since Last Run
Pricing
from $2.00 / 1,000 new job postings
New Job Alerts - Only Postings That Appeared Since Last Run
Each run returns only the job postings that are new since your previous run, read live from each employer's applicant tracking system. Schedule it and pipe genuinely new openings into Slack, email or a database.
Pricing
from $2.00 / 1,000 new job postings
Rating
0.0
(0)
Developer
Sulle H
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 hours ago
Last modified
Categories
Share
New Job Alerts — Only New Postings from 27,000+ Career Sites
Watch 27,000+ company career sites and get back only the postings that appeared since your last run.
Every other job feed hands you the same thousands of rows every time and leaves you to diff them. This one remembers what it already showed you. Schedule it hourly or daily and each run returns a clean list of genuinely new openings — ready to pipe into Slack, an email digest, a spreadsheet or your own database.
Postings are read live from each employer's own applicant tracking system, so a row means the job is open on the company's careers page right now, with a direct apply link.
| Platform | Boards watched |
|---|---|
| Greenhouse | 5,578 |
| Personio | 5,172 |
| SmartRecruiters | 4,334 |
| Workday | 2,658 |
| Lever | 1,917 |
| Workable | 1,710 |
| Ashby | 1,596 |
| Breezy HR | 2,800 |
| Rippling | 1,298 |
| Pinpoint | 618 |
| Total | 27,681 |
No login, no cookies, no proxies, no API keys.
How the feed remembers
The first run seeds the feed and returns the most recent matching postings. Every run after that returns only what is new.
State is kept per feed name, in your own account. Run several alerts side by side — remote-react, berlin-sales, new-grad-ml — and give each its own feedId so they don't consume each other's new postings.
A posting older than lookbackDays (7 by default) is never counted as new, even on a first run. Raise it if you run the feed less often than weekly.
What you get
| Field | Description |
|---|---|
company / companySlug | Company name and its board slug |
provider | Which ATS the posting came from |
jobId | Stable per-posting ID |
title | Job title |
location | Location string as published |
department | Department or team |
employmentType | Full-time, contract, etc., where the ATS exposes it |
remote | Remote flag, where the ATS exposes it |
postedAt / updatedAt | Publication and last-modified timestamps |
applyUrl | Direct application link on the employer's own site |
salary | Pay range as the employer wrote it. Only Breezy and Ashby publish this; null elsewhere. |
descriptionText | Full description, when includeDescription is on |
scrapedAt | When this row was read, ISO 8601 |
firstSeenAt | When this feed first reported the posting |
Results come back newest first.
Input
{"keywords": ["engineer", "developer"],"excludeKeywords": ["senior", "staff"],"remoteOnly": true,"feedId": "remote-eng","lookbackDays": 7,"maxBoards": 300}
| Option | What it does |
|---|---|
keywords | Keep titles containing any of these. Empty = every job. |
excludeKeywords | Drop titles containing any of these. |
locations | Keep postings whose location matches any entry. |
remoteOnly | Keep only remote-flagged or remote-looking postings. |
feedId | Names this feed's memory. One per alert you run. |
lookbackDays | How far back a posting can be and still count as new. |
companies / providers | Restrict to specific boards or ATS platforms. |
maxBoards | How many boards to watch, largest employers first. |
maxJobs | Cap on returned rows, so a run costs what you expect. |
includeDescription | Off by default — alerts rarely need the full text. |
Suggested setup
- Run it once with your filters to seed the feed.
- Add a Schedule — daily is a good default, hourly for competitive roles.
- Connect the dataset to Slack, email, Zapier, Make or a webhook via Apify Integrations.
Each scheduled run then delivers only what is new.
A note on Workday
Workday is where most large enterprises post, and it is the biggest single source here — but its
public listing endpoint carries less than the others. Workday rows have the company, title,
location, requisition id and apply link, and no department, employment type or description;
those live behind a per-posting request the price of a result cannot cover. Workday also reports
posting age as text ("Posted Today", "Posted 30+ Days Ago"), so postedAt is exact when the age
is exact and null when it is not — a missing date rather than an invented one. If you filter on
posting date, Workday rows without a date are kept rather than dropped.
How the memory actually works
Worth understanding before you build a workflow on it, because the details decide what you get.
Where state lives. Each feed keeps a small record in a named key-value store inside your own Apify account. Nothing about your feed is stored on our side, and two customers watching the same employers never affect each other.
What gets remembered. Only postings that were actually delivered to you, plus earlier
deliveries still inside the lookback window. A posting trimmed by maxJobs is not marked as
seen — it goes out on the next run instead. That is deliberate: the backlog drains rather than
disappearing.
Why the window matters. lookbackDays bounds both what counts as new and how big the memory
gets. Without it the seen-set would grow towards the registry's million-plus postings and outgrow
the 9 MB record limit. Postings age out of the memory on their own.
Postings with no date. Workday reports age as prose, so many of its rows have no timestamp.
Those are judged purely by the seen-set: reported once, then suppressed. They cannot be filtered by
lookbackDays because their age is genuinely unknown.
Several feeds at once. feedId names the memory. Run remote-react, berlin-sales and
new-grad-ml side by side and each keeps its own position. Reusing one feedId across different
filters is the one thing to avoid — the runs will consume each other's new postings.
Which fields each platform gives you
| Field | Workday | SmartRecruiters | Greenhouse | Workable | Lever | Ashby | Breezy |
|---|---|---|---|---|---|---|---|
| title, company, location | yes | yes | yes | yes | yes | yes | yes |
| applyUrl | yes | yes | yes | yes | yes | yes | yes |
| postedAt | partial | yes | yes | yes | yes | yes | yes |
| department | no | yes | yes | yes | yes | yes | yes |
| employmentType | yes | yes | no | yes | yes | yes | yes |
| descriptionText | no | no | yes | yes | yes | yes | no |
| salary | no | no | no | no | no | yes | yes |
Measured from real runs. includeDescription is off by default here because an alert is usually
title, company and link — and because Workday and SmartRecruiters rows carry no description
whatever the setting.
Recipes
A morning digest. Schedule daily, lookbackDays: 2, your keywords, and connect the dataset to
email or Slack. Each run delivers only what opened since yesterday.
Hiring-intent alerts for sales. keywords: ["sales", "account executive"], lookbackDays: 3.
A company opening sales headcount is a company with budget, and you hear about it the day it posts.
A watchlist of employers. Put slugs in companies and raise lookbackDays to 14. Useful for
tracking competitors, acquisition targets, or companies you want to work for.
Feeding a job board without duplicates. Point it at your niche, run hourly, and append straight
to your database. provider:companySlug:jobId is stable, so you can key on it safely.
Tuning
| Symptom | What to change |
|---|---|
| Too many results per run | Lower maxJobs, or narrow keywords |
| One employer dominates | Lower maxJobsPerCompany (defaults to 25) |
| Missing roles you expected | Raise maxBoards, or widen lookbackDays |
| Nothing new most runs | Run less often, or widen the filters — an idle feed is working correctly |
| Want depth on a few firms | Set companies and raise maxJobsPerCompany |
Cost
Pay per delivered posting. A run that finds nothing new costs nothing, which makes frequent scheduling cheap: the price tracks what actually changed rather than how often you look.
If you only need one ATS
This Actor is built for breadth — it does not ask you which applicant tracking system a company uses, because the registry already knows. When you only care about one platform, a narrower Actor is cheaper to reason about and its input schema has fewer knobs:
| Actor | Coverage |
|---|---|
| Workday Jobs Scraper | 2,658 Workday boards — paste a careers URL |
| SmartRecruiters Jobs Scraper | 4,334 SmartRecruiters boards |
| Breezy HR Jobs Scraper | 2,800 Breezy boards, with pay ranges |
| Workable Jobs Scraper | 1,710 Workable boards, with full descriptions |
| Greenhouse Jobs Scraper | Any Greenhouse board by slug or URL, with full descriptions |
All of them emit the same row shape as this Actor, so datasets from any combination can be unioned without a mapping layer.
Use it as an API
Most people who rely on this Actor never open the Apify console after the first run — they call it from their own code and read the rows straight back. One request in, job rows out, no polling and no dataset id to chase:
curl -X POST "https://api.apify.com/v2/acts/starbright_overlap~new-jobs-feed/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"feedId": "my-feed", "keywords": ["engineer"], "maxJobs": 200}'
import requestsrows = requests.post("https://api.apify.com/v2/acts/starbright_overlap~new-jobs-feed/run-sync-get-dataset-items",params={"token": "YOUR_TOKEN"},json={"feedId": "my-feed", "keywords": ["engineer"], "maxJobs": 200},timeout=300,).json()for r in rows:print(r["company"], "—", r["title"], "—", r["applyUrl"])
const rows = await (await fetch('https://api.apify.com/v2/acts/starbright_overlap~new-jobs-feed/run-sync-get-dataset-items?token=YOUR_TOKEN',{ method: 'POST', headers: { 'Content-Type': 'application/json' },body: JSON.stringify({"feedId": "my-feed", "keywords": ["engineer"], "maxJobs": 200}) },)).json();
Your token is at Settings → Integrations in the Apify console. Keep maxJobs set to what you
actually need — it is the cap that decides what the call costs.
Running it on a schedule instead
If you want the rows to arrive without asking, add a Schedule from the Actor page (Actions →
Schedule) and point a webhook at your endpoint. A daily schedule plus the postedWithinDays filter
is the usual setup for a job board or an alerting pipeline.
Pricing
Pay per result — you are charged per new posting delivered. A run that finds nothing new costs nothing.
Notes
- Boards are scanned largest-first, so a capped run watches the most active employers.
- Dead or rate-limited boards are skipped without aborting the run; details land in a
FAILED_BOARDSrecord. - The board registry is re-validated every month, so dead companies drop out on their own.
Freshness, measured rather than promised
Some employers leave requisitions open for years — across the registry, 15% of Greenhouse postings and about half of the largest SmartRecruiters boards are over a year old. That matters more for an alert feed than for a search: a posting that has sat open since 2017 is not news.
lookbackDays (7 by default) is the guard. A posting older than that is never treated as new, even on a first run. Raise it if you run the feed less than weekly; lower it to 1 or 2 for a tight daily alert.
Postings with no publication date are judged by the seen-set instead, so they are reported once and then suppressed. That is most Workday rows.
A note on Workday
Workday is where most large enterprises post, and it is the biggest single source here — Accenture, Walmart, CVS Health, Lowe's. Its public listing endpoint carries less than the others: Workday rows have company, title, location, requisition id and apply link, and no department, employment type or description. Workday also reports posting age as text ("Posted Today", "Posted 30+ Days Ago"), so postedAt is exact when the age is exact and null when it is not.
Frequently asked
How does it know what is new? It keeps a small record in your own account listing the postings it has already delivered, keyed by feed name. Each run returns what is not in that record. Nothing is stored on our side.
What happens on the very first run? It seeds the feed and returns the most recent matching postings, so the first run is useful rather than empty. Every run after that returns only what appeared since.
Can I run several alerts at once?
Yes — give each its own feedId (remote-react, berlin-sales, new-grad-ml). Feeds have separate memories and do not consume each other's new postings.
What if nothing new appeared? The run returns nothing and costs nothing, since billing is per delivered posting.
I capped maxJobs and there were more new postings than that. Are they lost?
No. Only what was actually delivered is remembered, so the remainder goes out on the next run. The backlog drains rather than disappearing.
Which ATS platforms are covered? Workday, Greenhouse, SmartRecruiters, Workable, Lever, Ashby, Breezy, Rippling and Pinpoint HR — 27,681 company boards in total.
Can I send new jobs straight to Slack or a sheet? Yes. Add an Apify Schedule to run it, then use the platform's integrations (Slack, Zapier, Make, webhooks, Google Sheets) on the dataset each run produces.