Multi-ATS Jobs Feed + Change Alerts avatar

Multi-ATS Jobs Feed + Change Alerts

Pricing

from $1.50 / 1,000 job items

Go to Apify Store
Multi-ATS Jobs Feed + Change Alerts

Multi-ATS Jobs Feed + Change Alerts

Job postings from the official public job-board APIs of Greenhouse, Lever, Ashby, SmartRecruiters, Workable and Recruitee in one normalized schema. Scheduled runs return only new, updated and removed jobs.

Pricing

from $1.50 / 1,000 job items

Rating

0.0

(0)

Developer

Tallow Lane Labs

Tallow Lane Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Categories

Share

One job feed for every company you follow, from Greenhouse, Lever, Ashby, SmartRecruiters, Workable and Recruitee, in one clean schema. Schedule it, and each run returns only what changed: new jobs, updated jobs and closed jobs.

Built and maintained by Tallow Lane Labs.

What it does

  • Reads the official public job-board APIs that each ATS publishes for career sites. There is no browser, no HTML scraping of job pages and no proxies, so runs are fast, cheap and stable.
  • Normalizes every posting into one schema: title, department, team, employment type, remote/hybrid/onsite, locations, salary range (when the company publishes it), posted date, job URL, apply URL, and the description as plain text, Markdown and/or HTML.
  • Change alerts. In changes mode the Actor remembers every board between runs, in a named key-value store, and outputs only:
    • new: postings that weren't there last run
    • updated: postings whose title, location, salary, team, description, URLs and so on changed. The record lists the changed fields and the previous title, department, location and URL.
    • removed: postings that disappeared, meaning the job was closed or filled.
  • Snapshot mode returns the full current list every run.
  • Accepts whatever you paste: a job-board URL (https://jobs.lever.co/palantir), an ats:slug shortcut (greenhouse:stripe), a company careers page that embeds one of these boards (the Actor detects the ATS), or a bare slug (the Actor tries each ATS).
  • Filters: keywords, exclude keywords, locations, departments, workplace type, and posted within N days.

Typical uses include recruiting and sourcing alerts, sales signals ("company X just opened 12 data roles"), competitive hiring intel, job-board aggregation, and labor-market research.

Input

FieldDefaultWhat it does
boards (required)–List of boards. Examples: https://boards.greenhouse.io/stripe, lever:palantir, lever:eu:somecompany (Lever EU), https://jobs.ashbyhq.com/ramp, smartrecruiters:Ubisoft2 (case-sensitive), https://apply.workable.com/huggingface/, bunq.recruitee.com, https://www.example.com/careers
modechangeschanges = only new/updated/removed since the last run. snapshot = every live posting.
changeTypesall threeWhich change types to output.
emitBaselinetrueOn the first run of a board in changes mode, output all current jobs (marked baseline). Turn it off to start silently and alert only on later changes.
keywords / excludeKeywords–Case-insensitive substring match on the job title.
locations, departments–Case-insensitive substring match on any location (city, region, country) or on department and team, e.g. Germany, Remote, Engineering.
workplaceTypes–remote, hybrid, onsite, unknown.
postedWithinDays–Only jobs posted in the last N days.
maxJobsPerBoard–Caps output per board per run (a cost control).
includeDescriptionstrueInclude job descriptions. Turning it off makes runs smaller and faster.
descriptionFormatstext, markdownAny of text, markdown, html.
redactContactInfofalseMasks e-mail addresses and phone numbers inside descriptions.
includeUnlistedfalseAshby only: also return postings the company marked unlisted.
stateStoreName / stateKeyPrefixmulti-ats-jobs-feed-state / –Where change-tracking state lives. Use a different name or prefix for each independent watch list.
resetStatefalseForget the stored state and start a new baseline.
detectFromCareerPages, probeBareSlugstrueTurn off automatic ATS detection.
boardConcurrency, maxConcurrency3 / 4Politeness limits. Per-ATS request spacing is built in and can't be lowered. boardConcurrency also sets memory use; see Memory.
removalSafetyMinJobs5If a board that had at least this many jobs suddenly returns 0, the Actor treats it as an outage and does not report mass removals.

Example input

{
"boards": [
"https://boards.greenhouse.io/stripe",
"https://jobs.lever.co/palantir",
"ashby:ramp",
"smartrecruiters:Ubisoft2",
"https://apply.workable.com/huggingface/",
"bunq.recruitee.com"
],
"mode": "changes",
"keywords": ["engineer", "data"],
"workplaceTypes": ["remote", "hybrid"]
}

Then put it on a schedule (daily is the recommended default; see Choosing a schedule) and connect the dataset to a webhook, Slack, Google Sheets or Zapier.

Output

One dataset record per job (snapshot or baseline) or per change. Errors for individual boards are written as recordType: "error" records and aren't charged. The other boards keep running.

{
"recordType": "change",
"changeType": "new",
"changedFields": [],
"id": "ashby:ramp:34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"ats": "ashby",
"board": "ramp",
"companyName": "ramp",
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"requisitionId": null,
"title": "Security Engineer, Cloud",
"department": "Engineering",
"team": "Backend",
"employmentType": "full_time",
"employmentTypeRaw": "FullTime",
"workplaceType": "hybrid",
"isRemote": false,
"location": "New York, NY (HQ)",
"locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
"city": "New York City",
"region": "NY",
"country": "USA",
"salary": { "min": 211400, "max": 290600, "currency": "USD", "interval": "year", "text": "$211.4K - $290.6K" },
"postedAt": "2026-04-07T17:12:35.753Z",
"firstSeenAt": "2026-10-27T13:33:02.101Z",
"detectedAt": "2026-10-27T13:33:02.101Z",
"url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
"descriptionText": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams ...",
"descriptionMarkdown": "# **About Ramp**\n\nRamp is building the smart infrastructure for finance teams ..."
}

An updated record has the same shape, plus changedFields (for example ["title", "salary"]) and previous, which holds the last known title, department, location and URL. Other fields are tracked by hash, so the record tells you which ones changed but not their old values.

A removed record carries the last known title, company, department, location and URLs, plus firstSeenAt and lastSeenAt. A new record can carry lateDiscovery: true when the posting's postedAt is older than the previous run, meaning the ATS only started listing it now.

Each run also saves a RUN_SUMMARY record in the run's default key-value store. It holds per-board job counts, change counts, pages fetched, warnings and HTTP stats.

The dataset has three views: Overview, Changes and Errors.

Pricing (pay per event)

EventPriceWhen it's charged
Job item$0.0015Each job returned in snapshot mode, and each baseline job on the first changes run of a board
Job change$0.002Each new, updated or removed record on later changes runs
Board check$0.001Each board checked in a run, changed or not. A board with more than 1,000 live jobs counts once per started 1,000 jobs (a 2,400-job board = 3 checks).
Actor start$0.005Once per run (Apify's standard start event; the same price at 256, 512 or 1024 MB)

You don't pay for error records, boards that fail (not found, rate-limited), or jobs your filters exclude, and memory doesn't change the price. The start fee and board checks cover the cost of fetching and comparing your boards on runs that find nothing new, so frequent schedules stay cheap for small watch lists and fair for big ones. RUN_SUMMARY lists the board checks charged for each board.

Examples

  • Watching 6 companies (about 1,500 jobs): a run with no changes costs $0.011 ($0.005 + 6 × $0.001), about $0.33 a month on a daily schedule.
  • Watching 50 companies with about 7,500 open jobs: the first run (baseline) costs about $11.31 ($11.25 for 7,500 jobs + $0.05 for 50 board checks + $0.005). After that, a daily run that finds 150 changes costs about $0.36 ($0.30 + $0.05 + $0.005), roughly $11 a month. A day with no changes costs $0.055.
  • Turning off emitBaseline means the first run costs only the start fee and board checks, and you pay only for changes after that.
  • A full snapshot of 1,000 jobs from 5 boards costs about $1.51.
  • Set Maximum cost per run in Apify to put a hard cap on any run. The Actor stops cleanly at the cap and saves its state, so jobs it didn't deliver arrive on the next run instead of being lost.

Choosing a schedule

Every run pays the base fees (the $0.005 start plus the board checks), even when nothing changed. At 50 boards that is $0.055 a run ($0.05 for 50 board checks + $0.005 start). Over 30 days, including the start fee:

ScheduleRuns a monthBase cost a month at 50 boards, no changes
Daily (recommended default)30about $1.65
Every 6 hours (fresher change alerts)120about $6.60
Hourly720about $39.60

Daily suits most watch lists. Use every 6 hours if you need change alerts sooner. Hourly also works, but at 50 boards it costs about $39.60 a month in base fees alone. Changes are billed on top of these base fees at $0.002 per new, updated or removed job.

Memory

The default 512 MB is enough for almost every watch list. What matters is not how many jobs you watch in total but how many are being processed at the same time: the Actor works on boardConcurrency boards at once (3 by default), so memory depends on your 3 largest boards. Measured peaks:

MemoryUse it whenMeasured peak
256 MBYour 3 largest boards together have at most 1,500 live jobs~190 MB at 1,500 jobs in flight
512 MB (default)Your 3 largest boards together have at most 7,500 live jobs and no single board has more than 5,000~240 MB for a 29-board, 7,700-job no-change run; ~305 MB for its baseline; ~370 MB for 30,000 jobs across 20 boards; ~400 MB at 7,500 jobs in flight
1024 MBAny board has more than 5,000 live jobs, or your 3 largest boards together have more than 7,500~630 MB for three 5,000-job boards; ~700 MB for one 15,000-job board

Above about 15,000 jobs in flight, set boardConcurrency to 1 (memory then depends on your single largest board) and put very large boards in their own task. Lowering boardConcurrency also lets a 512 MB run handle a board of up to ~7,500 jobs. Each run's RUN_SUMMARY.memory shows the jobs in flight and the recommended memory, and the run log warns if you should move up.

Limits and good to know

  • Public postings only. Internal, unlisted (except Ashby with includeUnlisted) and draft postings aren't available through these APIs.
  • Field coverage varies by ATS. Greenhouse doesn't publish employment type, and its remote/hybrid value is inferred from the location text. Salary appears only when the company publishes it (pay transparency). For Lever and Ashby, companyName is the board slug because those APIs don't return a display name.
  • SmartRecruiters pagination isn't fully stable: the same posting can show up twice or be missing from one pass. The Actor makes up to three passes and checks every apparent removal, and every "new" posting, against the posting's own page. A job is only reported removed when SmartRecruiters confirms it's gone or inactive. Descriptions need one extra request per posting, but only for postings that are output.
  • Workable rate-limits its public widget API heavily, so the Actor spaces Workable requests about 5.5 s apart. Large watch lists of Workable boards take longer.
  • Identifiers: SmartRecruiters company IDs are case-sensitive. An unknown SmartRecruiters ID returns an empty list rather than an error, so the Actor reports it as "no postings found / check the identifier".
  • Change tracking is per board and per state store. Running the same board from two different tasks? Give each task its own stateStoreName or stateKeyPrefix.
  • Normalizer updates (for example, better remote/hybrid detection) are applied silently and don't trigger "updated" alerts.

Data sources, terms and privacy

All data comes from the job boards' own public, unauthenticated endpoints, which exist for building career sites:

ATSEndpointDocs
Greenhouseboards-api.greenhouse.io/v1/boards/{token}/jobshttps://developers.greenhouse.io/job-board.html
Leverapi.lever.co/v0/postings/{site} (EU: api.eu.lever.co)https://github.com/lever/postings-api
Ashbyapi.ashbyhq.com/posting-api/job-board/{name}https://developers.ashbyhq.com/docs/public-job-posting-api
SmartRecruitersapi.smartrecruiters.com/v1/companies/{id}/postingshttps://developers.smartrecruiters.com/docs/posting-api
Workableapply.workable.com/api/v1/widget/accounts/{subdomain}https://help.workable.com/hc/en-us/articles/115012771647
Recruitee{company}.recruitee.com/api/offers/https://docs.recruitee.com/reference/intro-to-careers-site-api

The Actor identifies itself with a descriptive User-Agent. It spaces requests to each ATS, backs off on HTTP 429 and 5xx (honoring Retry-After), and never submits applications.

Personal data: the Actor collects only what's in the public job posting. Recruiter and creator names, avatars, internal mailbox addresses, application questions and internal IDs that some APIs return are dropped. Specifically, it drops SmartRecruiters creator, Recruitee mailbox_email, and Greenhouse internal metadata and compliance fields. A posting's description can contain a contact address the company chose to publish, such as an accommodations or recruiting mailbox. That text is kept as published, the run summary counts how many postings contain one, and redactContactInfo masks them. You're responsible for using the data in line with the job boards' terms and the laws that apply to you, such as GDPR and CCPA.

Changelog

  • 0.1: First version. Six ATSs, changes and snapshot modes, PPE pricing (job item, job change, board check, start). SmartRecruiters team, department and employment type are compared by their stable IDs, because the API sometimes returns a page with localized labels (for example Chinese) and that must not show up as an "updated" job.

Support

Questions or issues: open an issue on this Actor's Issues tab, or email Tallow Lane Labs at wdeornellas+tallowlanelabs@gmail.com.