Greenhouse, Lever, Ashby, Workable Jobs Scraper + Job Monitor
Pricing
$1.00 / 1,000 job fetcheds
Greenhouse, Lever, Ashby, Workable Jobs Scraper + Job Monitor
Greenhouse, Lever, Ashby, Workable & Recruitee jobs scraper + monitor — open roles from each company's live feed in one normalized schema. $1 per 1,000 jobs, $0 start. Optional diff mode, off by default: the first run bills the jobs delivered; later runs bill new + watched-field changes.
Pricing
$1.00 / 1,000 job fetcheds
Rating
0.0
(0)
Developer
WickFeed
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
4 hours ago
Last modified
Categories
Share
Know the moment a company you track posts or removes a job — and in diff mode, pay only for what's new.
$1 per 1,000 jobs · no start fee · 1,925 boards verified 2026-07-15 · reads each company's own live job feed, not a copy of the web page, so a careers-page redesign never breaks it · name or URL in, jobs out.
Live status: https://api.apify.com/v2/key-value-stores/WickFeed~wickfeed-public-status/records/status.json — real self-test results for every wickfeed scraper (pass/fail plus 30-day success rate), updated hourly, no login needed. Opens as raw data (JSON).
Choose the right WickFeed tool
- Mixed ATS, or unsure which system a company uses → this tool (ATS Job Aggregator)
- Greenhouse only → Greenhouse Jobs Scraper
- Ashby only, including published salary ranges → Ashby Jobs Scraper
- Workable only → Workable Jobs Scraper
- Need companies and live job counts, not job rows → ATS Company Discovery
Your first run, start to finish
- Click Try for free and sign in to Apify.
- Leave the 5 demo boards as they are and click Start — real jobs back in about a minute for about $0.17 (at most $0.25). The free Apify plan's $5 monthly credit covers it many times over.
- When the run finishes, open Dataset to see the job rows.
- Click Export for CSV, Excel, or JSON.
That's the whole first run — no tokens to hunt, nothing to set up. Want more than the demo? Quick start ↓
Every source lands in one normalized schema. Turn on diff mode and each run returns only the new and changed jobs since your last run, charged only for those — so a daily monitor stays cheap. Prefer a one-shot pull? Leave diff mode off and get the whole board on demand.
Supported ATS: Greenhouse · Lever · Ashby · Workable · Recruitee
Unofficial — not affiliated with or endorsed by Greenhouse, Lever, Ashby, Workable, or Recruitee. Job data is employer-published public information; descriptions may include recruiter contact details — use them for hiring research, not spam.
Just type the company — name or URL in, jobs out
Don't know a company's board token? You don't need it. Put a company name or a careers URL in the "Company names or careers URLs" box and the actor finds the hiring system and board for you. It merges with the preset and Sources lists (duplicates removed), so mix and match freely.
{ "companies": ["Stripe", "https://boards.greenhouse.io/airbnb", "https://apply.workable.com/huggingface"] }
How reliable each kind is (most reliable first):
- A careers/board URL almost always works. An ATS-hosted URL —
https://boards.greenhouse.io/stripe,https://jobs.lever.co/spotify,https://jobs.ashbyhq.com/ashby,https://apply.workable.com/huggingface,https://grid.recruitee.com— carries the board token right in it, so we read it directly. This is the reliable path. - A bare company name is best-effort. We check a bundled index of named boards, then try a short list of live board-name guesses. It works for most names but not all — many companies don't name their board after themselves, and some systems (Ashby, Lever) don't expose a company name at all. That's expected, not a bug.
If we can't find your company, you pay nothing and we tell you why. Resolution is always free — you're only ever charged for jobs a matched board returns. Every input that can't be matched is reported in the RESOLUTION_REPORT key-value record with the reason and a prompt to paste the careers URL (or { ats, token }) instead — at $0. Ambiguous names (a guess that matches more than one company) resolve to nothing on purpose, so you're never billed for the wrong company's jobs. Scanning your own company homepage (e.g. https://acme.com/) is a planned fast-follow, not live yet — paste the careers/board URL (the one with the board id) instead.
For a stable daily monitor, resolve once and pin the result: open RESOLUTION_REPORT, copy the resolved { ats, token } boards into sources (or set a fixed diffStateKey). In diff mode the baseline is keyed on the boards watched, so pinning the tokens keeps the monitor drift-proof — at no cost.
Quick start
Pressing Start with the prefills untouched runs the 5 demo boards (~$0.17, at most $0.25, roughly 165 jobs). Want more than the 5 demo boards?
- Pick a preset from the dropdown —
starter-500loads 500 verified boards in one click. This one isn't free: a first full run can reach ~$25 at the default cap (see the first-run cost table), so lower Max results per source to shrink it. - Optionally add keywords or locations to keep only the jobs you want.
- Press Start. Each board delivers up to 50 matching jobs by default (
maxResultsPerSource) — your keywords, locations, and other filters run over the whole board first, then the matches are capped, so a match never hides past the cap. Runs stay light: at $1 per 1,000 jobs, about 50 jobs costs roughly $0.05. Raise the cap once you like what comes back. - Get the data out — no code. Every run exports to CSV, Excel, or Google Sheets (plus JSON) through Apify's built-in export and integrations.
Pricing
Pay-per-event: job-fetched — $1.00 per 1,000 normalized jobs. Starting a run costs nothing, and empty or failed runs are never charged. You pay only for jobs that pass validation and land in your dataset. In diff mode you pay only for the new and changed jobs delivered — on a day when nothing changed at your boards, the run costs $0, and closed-job detection (the CLOSED_JOBS list) is bundled free, not a paid add-on.
Charge-only-new billing isn't unique to us, but at $1 per 1,000 with a $0 start fee we sit at the cheap end of the store's incremental feeds — most we've checked run $1.50–$12 per 1,000 (that range is for multi-system feeds that cover several hiring systems in one run, like this one; single-system scrapers quote a different, lower range), and at least one lists lower. $1 per 1,000, $0 start — the cheapest feed in our price table below.
If a charge ever looks wrong, open an issue on the Issues tab with your run link. If we over-billed you, we file a credit request with Apify to put it back on your account. (Apify pays seller compensation as account credit rather than cash, so that's what we can promise and what we'll do — not a guarantee about how Apify itself handles it.)
| Actor | Price per 1,000 jobs | Start fee (every run) |
|---|---|---|
| This actor (wickfeed) | $1.00 | $0 |
bovi/greenhouse-lever-ashby-job-scraper | $1.50 | ~$0 (negligible) |
fantastic-jobs/career-site-job-listing-feed | $2.50 | $0.10 |
jobo.world/ats-jobs-api | $4.00 | ~$0 (negligible) |
Competitor store prices as listed on 2026-07-15, at each actor's entry (free) subscription tier; some tier their per-1,000 price down on higher paid subscriptions. We charge one flat $1.00 per 1,000 with no start fee, and in diff mode you're billed only for the jobs that changed.
Run it daily — set up job alerts
Never used Apify before? This is the whole setup. Three steps, and each morning you get an email (or a Slack message) listing the new and changed roles at your boards since yesterday:
- Flip on "Only new & changed jobs (diff mode)" in the input form above, then pick your boards or a preset. That switch is what makes each run deliver only what's new instead of the whole board every time.
- Put it on a daily timer. Click Actions → Schedule at the top of this page — it saves your current settings as a task and schedules that task in one step. (By hand instead: Actions (⋯) → Save as task, then Schedules → Create new → add that task.) Either way, schedule the task, not the bare actor: a bare-actor schedule doesn't carry the diff-mode switch and board picks you just chose, so it would re-fetch and re-bill the whole board every day.
- Get the results sent to you. On your saved task's Integrations tab, connect Slack (or Email) — Apify wires it to your run's Dataset for you. Prefer to check yourself? Every run's results wait on the run's Storage tab: job rows in Dataset, one click to CSV, Excel, or Google Sheets.
What the alert can and can't include. Each diff run's Dataset carries the new and changed jobs — that's what a Dataset integration sends to Slack or email. Removed jobs are recorded separately in CLOSED_JOBS (a Key-value store record), so a Dataset integration alone sends new and changed; including removals needs a webhook or automation that also reads CLOSED_JOBS.
Watching your own hand-typed boards? Give the monitor a fixed name — set diffStateKey to anything you like (say, my-monitor) so its memory of what it saw last time stays put between runs. Preset monitors are already steady (their memory is tied to the preset name), so skip this for those. (Running two separate monitors over the same hand-typed list? Give each its own name, or they'll share one memory.)
Bundled company lists (start here)
Pick a preset and press Start — no token hunting. 1,925 boards, every one verified live against the vendor's own API on 2026-07-15. A dead board never costs you anything — it's isolated and reported, not charged.
| Preset | Boards | First full run¹ | Use |
|---|---|---|---|
all-verified | 1,925 | up to ~$96 | The full verified set — Greenhouse, Ashby, Workable, Recruitee. |
starter-500 | 500 | up to ~$25 | The 500 boards with the most active jobs — best first run. |
engineering | 457 | up to ~$23 | Boards where most open roles are engineering. |
sales | 132 | up to ~$6.60 | Boards where most open roles are sales. |
healthcare | 53 | up to ~$2.65 | Boards where most open roles are healthcare. |
finance | 37 | up to ~$1.85 | Boards where most open roles are finance. |
| Lever | 0 bundled | — | Add boards by hand (see below) — EU list planned. |
¹ Ceilings, not typical bills. Each figure is the most a first full run could cost at the default cap: boards × 50 jobs × $1 per 1,000 (e.g. starter-500 = 500 × 50 = 25,000 jobs = $25). Real runs are almost always well under, because many boards post fewer than 50 jobs, dead boards return nothing and are never charged, and any filter trims further. Lower Max results per source to shrink any preset proportionally. In diff mode the first run bills for the whole board like a normal run (these same ceilings apply); later runs charge only for what changed.
Free Apify plan. The $5 monthly usage credit comfortably covers the 5-board demo, finance, and healthcare. The larger presets exceed $5, so a free-plan run of sales, engineering, starter-500, or all-verified stops partway once the credit is used up.
A preset merges with anything you add in sources (duplicates removed by ats:token). Each preset entry carries company/jobCount/verifiedAt provenance; the actor reads only ats/token. Where the boards came from: tokens were discovered from the public Common Crawl URL index (crawls CC-MAIN-2026-25 + CC-MAIN-2026-21), then each was independently confirmed live by us — no third-party curated dataset was copied. The full funnel and per-board provenance ship inside the actor's source, in presets/NOTES.md (next to the preset files). Lever ships 0 boards because its pages are robots-blocked in Common Crawl, so there was no license-clean way to source US Lever boards; add Lever boards by hand in sources. Region-aware coverage (incl. ~65 verified EU boards) is planned.
Track only what's new — daily job alerts
Turn on diffMode and the actor remembers what it saw last time and returns only the jobs that are new or changed since your last run. Everything else is skipped, and you're not charged for it.
- New jobs (first time we've seen that id) and changed jobs (title, location, salary, or description edited) are delivered — each tagged
changeType("new"/"changed") andfirstSeenAt. - Unchanged jobs are silently skipped and cost nothing.
- Closed jobs (there last run, gone now) are listed compactly under
CLOSED_JOBS(id,ats,companyToken,title,lastSeenAt) on the run's Storage tab, in the Key-value store section — never mixed into your clean job Dataset. Bundled free.
Your comparison history is private to you. When you run a public actor on Apify, its storages are created in your own account — so the baseline (a key-value store named ats-jobs-diff-state) lives under your account; we don't have access to it. Different board lists keep separate histories automatically, or set diffStateKey to name your own.
Honest note on the first run. Your very first diff run has no history to compare against, so every job counts as new — it delivers and charges for the whole board, exactly like a normal run. From the second run on, you pay only for what actually changed — usually cents, and $0 on a day nothing changed.
Diff-mode rules (how it stays accurate and predictable)
- For accurate closed-job detection, keep the cap above each board's number of matching jobs. Set
maxResultsPerSourceat or above how many jobs match your filters on each board (it defaults to 50 for cheap first runs). Filters run over the whole board first, so a board with more matching jobs than the cap is a partial view: the actor notices, skips closed-job detection for that board that run — carrying your baseline forward untouched and recording it (diff.closedDetectionSkipped, plus atruncatedflag on that source's row) — rather than reporting false closures. A big board whose matches all fit under the cap gets full closed detection. A low cap never phantom-closes or re-bills jobs. - Baselines and list changes. Presets key the baseline to the preset name, so a re-verify/refresh does not reset it or re-bill you. Your own boards key the baseline to your board list and your keyword/location filters, so changing either starts a fresh baseline once (a one-time re-bill of the new set). Set a fixed
diffStateKeyto carry history across edits — but a fixed key pins one baseline, so narrowing filters under it will report the now-excluded jobs inCLOSED_JOBSand re-bill them if you widen again. Change filters by starting a newdiffStateKey, not by editing filters on the same one. - "Changed" watches four fields. A job is re-delivered as
changedonly when its title, location, salary, or description is edited. Department, remote flag, and URL changes don't count. - Reposts and a spend ceiling. To cap what any single run can cost, set
maxTotalChargeUsdin the Apify run options — the actor stops charging and delivering at the cap and notes it in the run summary.
When something breaks, you'll know
The worst thing a job feed can do is quietly shrink — one board stops answering, your dataset gets smaller, and the run still shows green. This actor doesn't do that. When a run finishes but one or more boards couldn't be read:
- The run is marked with a warning you can see in the run list — "2 of 12 sources failed this run — see DEGRADED_SOURCES" — instead of a silent green checkmark.
- A
DEGRADED_SOURCESrecord is written to the run's Storage tab, listing every board that failed with, in plain English: what kind of failure it was, what it most likely means (a wrong token, the board went down, the source is throttling us, the company took the board offline…), and what to try next. - A failed board is never faked as empty. Its jobs are not marked closed and not re-charged — they're held as-is until the board answers again. A dead token can't trigger a false wave of "job closed" alerts, and it can't bill you.
A normal quiet day is not a warning: if every board answered fine and there was simply nothing new, that's a healthy $0 run, not a degradation. If you run this on a schedule, point your Apify alerts at any non-SUCCEEDED run status (and watch for the warning message) so a degraded run reaches you the same way a full failure would. This is how we surface a problem — not a promise about how fast we answer support.
Posting age, changes, and removals
This actor makes no claim about a company's intent or whether anyone was hired. It hands you observable, dated, source-linked facts, and you read them yourself:
- How long a role has been up. Every record carries
postedAt(when the company first published it). In diff mode,firstSeenAtrecords when you first saw that id. Use these to see how long a posting has been visible. - The moment a role comes down. In diff mode, the free
CLOSED_JOBSlist flags jobs that were there last run and are gone now, each with alastSeenAttime. These are real removals, not guesses: a board that simply errored is never reported closed. - Reposts. Ids are
<ats>:<companyToken>:<jobId>. If the ATS assigns a new job id, the repost appears as a new record — compare title, source, and dates to spot it. (Not every repost gets a new id.)
Every result links to its public ATS source, so you can open the posting and decide for yourself. These are observable signals — not a compliance or accuracy guarantee, and not a claim about employer intent or hiring outcomes.
Schema stability (the output contract)
- We never rename or remove an existing output field within a major version. The keys we emit —
id,ats,title,url, and the rest — keep their names and meaning. - New fields are added, never forced. Adding a field never touches the ones you already read, so existing code keeps working.
- A breaking change is loud, not silent. Renaming or removing a field is a major version bump, announced in the Changelog with a note in the Issues tab before it lands.
schemaVersionis a breaking-contract version. Every record carries it (and it's inRUN_SUMMARY). It is not our release number and not an exact-shape fingerprint: adding a new field does not bump it — it changes only when an existing field is renamed, removed, or retyped (a breaking change, which also bumps our major version). So an unchangedschemaVersionmeans every field you already read is still present, with the same name, type, and meaning; new fields may have been added alongside. It's1today.
Input
{"companies": ["Stripe", "https://boards.greenhouse.io/airbnb"],"preset": "none","sources": [{ "ats": "greenhouse", "token": "stripe" },{ "ats": "lever", "token": "spotify" },{ "ats": "ashby", "token": "ashby" },{ "ats": "workable", "token": "huggingface" },{ "ats": "recruitee", "token": "grid" }],"maxCompanies": 25,"keywords": ["engineer", "product"],"locations": ["remote", "berlin"],"remoteOnly": false,"postedAfter": "2026-01-01","maxResultsPerSource": 50,"includeHtml": false,"diffMode": false,"diffStateKey": ""}
An API call with no companies, sources, or preset runs the 5 demo boards (up to $0.25) — the same as pressing Start in the Console. An explicit sources: [] returns a clean error.
| Field | Type | Notes |
|---|---|---|
companies | string[] | The easy path. Company names or careers URLs, resolved to { ats, token } for you. A URL is reliable; a bare name is best-effort. Resolution is free; misses are reported in RESOLUTION_REPORT and cost $0. Merges with preset + sources (deduped). |
maxCompanies | integer | Caps how many companies entries are resolved per run. Default 25, max 200. Extras are reported skipped, never charged. |
preset | string | Start from a bundled verified-live list. One of none|starter-500|engineering|sales|healthcare|finance|all-verified; default none. Merged with companies + sources. |
sources | array | The explicit path — one { ats, token } per board. ats ∈ greenhouse|lever|ashby|workable|recruitee. Optional when companies or a preset is set. Malformed/duplicate entries are skipped, never fatal; the run fails only with no usable board at all. |
keywords | string[] | Keep jobs whose title, department or description contains ANY keyword (case-insensitive). |
locations | string[] | Keep jobs whose location contains ANY substring (case-insensitive). |
remoteOnly | boolean | Keep only jobs the ATS explicitly marks remote. Unknown-remote jobs are excluded when true. |
postedAfter | ISO date | Keep jobs posted on/after this date. Unknown-date jobs are excluded when set. |
maxResultsPerSource | integer | Cap on matching jobs delivered per board. Filters run over the whole board first, then the matches are capped — so a match never hides past the cap. Default 50 for a fast, low-cost first run. In diff mode, keep it at or above each board's number of matching jobs for accurate closed-job detection (see the diff-mode rules). |
includeHtml | boolean | Also emit descriptionHtml (raw HTML). Default false. |
diffMode | boolean | Return only new + changed jobs since the last run, and charge only for those. Adds changeType/firstSeenAt; lists vanished jobs in CLOSED_JOBS. Default false. |
diffStateKey | string | Optional. Names the saved diff baseline. Blank = derived from your board list. Same value on two runs shares one baseline. |
The token is the board id inside that ATS, read straight off the careers URL:
| ATS | Endpoint used | Example token |
|---|---|---|
| Greenhouse | boards-api.greenhouse.io/v1/boards/{token}/jobs?content=true | stripe |
| Lever | api.lever.co/v0/postings/{token}?mode=json | spotify |
| Ashby | api.ashbyhq.com/posting-api/job-board/{token}?includeCompensation=true | ashby |
| Workable | apply.workable.com/api/v1/widget/accounts/{token}?details=true | huggingface |
| Recruitee | {token}.recruitee.com/api/offers/ | grid |
Output
One record per job, pushed to the dataset. Every ATS produces the same fields, with honest nulls where a source doesn't expose a value:
{"id": "greenhouse:stripe:6415041","ats": "greenhouse","companyToken": "stripe","company": "Stripe","title": "Software Engineer, Payments","department": "Engineering","location": "San Francisco, CA","remote": null,"url": "https://job-boards.greenhouse.io/stripe/jobs/6415041","postedAt": "2026-07-02T09:15:00.000Z","updatedAt": "2026-07-09T17:42:11.000Z","salaryRaw": null,"descriptionText": "As a Payments engineer, you'll build the systems that move money …","fetchedAt": "2026-07-15T18:00:00.000Z","schemaVersion": 1}
| Field | Type | Meaning |
|---|---|---|
id | string | Stable id: "<ats>:<companyToken>:<jobId>". Deduplicate on this. |
ats | string | Source ATS. |
companyToken | string | The board token you supplied. |
company | string | null | Best-effort display name (see per-ATS notes). |
title | string | Job title. |
department | string | null | Department / team when the ATS provides it. |
location | string | null | Location string as provided/assembled. |
remote | boolean | null | true/false when the ATS tells us; null when unknown. |
url | string | Public posting URL. |
postedAt | ISO string | null | First published time (UTC). |
updatedAt | ISO string | null | Last update time (UTC) when the ATS provides it. |
salaryRaw | string | null | Raw salary text when exposed. Not parsed into numbers. |
descriptionText | string | Plain text, HTML stripped, capped at ~20,000 chars. |
descriptionHtml | string | null | Only present when includeHtml: true. |
fetchedAt | ISO string | When this run fetched the record. |
changeType | string | Diff mode only. "new" or "changed". |
firstSeenAt | ISO string | Diff mode only. When this job id was first seen across your runs. |
schemaVersion | number | The output-record schema version (currently 1). |
Per-ATS notes. Greenhouse — no remote flag (only true when the location says "remote") and no salary; company is usually the title-cased token. Lever — no update timestamp; remote from workplaceType; company is the title-cased slug. Ashby — remote is the explicit isRemote; salaryRaw from the compensation summary when present; company is the title-cased org slug. Workable — company is the account's real display name; remote is the telecommuting flag. Recruitee — explicit remote; company is company_name; salaryRaw from the structured salary object.
Limitations
- Public boards only. It reads the job data a company chooses to publish — not private/authenticated ATS data, internal reqs, or candidate information.
- Company discovery via bundled lists. No ATS endpoint enumerates every company and the actor doesn't crawl. The bundled lists give 1,925 verified boards; for anything else, read the token off the careers URL.
- No server-side search. Endpoints return the whole board;
keywords/locations/remoteOnly/postedAfterare applied over the whole board after fetching, and only then are the matches capped tomaxResultsPerSource— so the cap never hides a match. - Field coverage varies by ATS.
updatedAtandsalaryRaware oftennullbecause several endpoints don't expose them;remoteisnullwhen the source doesn't say. - Rate & politeness. Requests are capped at ~2/second with retries and backoff, so very large runs take proportionally longer.
- Endpoint drift. If a vendor changes a response shape, that ATS's normalizer may need an update. Failures are isolated per-source and listed in
DEGRADED_SOURCESrather than crashing the run.
FAQ
How do I estimate what a run will cost? Count the jobs and divide by 1,000: at $1 per 1,000, a run of N jobs runs about N ÷ 1,000 dollars — ~50 jobs ≈ $0.05, 25,000 jobs ≈ $25 at the ceiling. In diff mode only the first run bills the whole board; after that you pay for what changed.
Do I need proxies? No. These are public vendor APIs — the actor calls them directly, the same request a browser makes when it loads a careers page.
Is this allowed? It reads only the job data a company chooses to publish — the same public JSON feeds a careers page loads in your browser. No login, no authentication, no HTML scraping. How you use the results is on you (descriptions can include recruiter contact details — for hiring research, not spam). This is a factual description of what the actor does, not a legal or compliance guarantee.
What if a board token is wrong or dead? It's skipped and logged for that one source; the rest of your run finishes normally. You're never charged for a board that returned nothing.
How fresh is the bundled company list? Every board was verified live on 2026-07-15 (the date updates whenever the list is re-verified). A board that has since died returns zero jobs and is never charged — and you can re-verify any board yourself just by running it.
Use with AI agents (MCP)
This actor is callable as a tool by AI agents through Apify's hosted MCP server at mcp.apify.com — nothing to install or host on our side. Point your MCP client at Apify's server:
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com" } } }
That form uses OAuth sign-in; to pass a token instead, add a header "Authorization": "Bearer <YOUR_APIFY_TOKEN>". Then ask the agent to run wickfeed/ats-job-aggregator with your boards (or a preset), and set diffMode: true for a daily monitor. Output is flat, stable JSON with consistent field names and ISO-8601 dates. Agentic pay-per-event billing is enabled.
Integrations. Works with n8n, Make, and Zapier through Apify's native integrations — route the dataset into Slack, a webhook, a Google Sheet, or your own pipeline.
For engineers
The dataset holds job records only. A RUN_SUMMARY is written to the key-value store (not a dataset item), next to REJECTS (records that failed the schema check, with reasons — never silently dropped; only pushed records are charged). RUN_SUMMARY carries actorVersion, schemaVersion, a totals object, and a perSource row (pushed + any note).
- Degraded sources. If the run succeeded but one or more boards errored,
RUN_SUMMARYgains adegradedblock, the run status is set to aWARNING, andDEGRADED_SOURCESlists each failed board (ats,token,errorClass, rawerror, plain-Englishmeaning,retryadvice). - Resolution report. When you use
companies, a per-companyRESOLUTION_REPORTrecords each input asresolved(withmatchedBy/ats/token/careersUrl/confidence),ambiguous,unresolved(with areasonand pastehint), orskipped(overmaxCompanies). Resolution issues no charge. - Diff-mode summary.
totalsalso carriesnew/changed/unchanged/closed, andRUN_SUMMARYgains adiffblock. Removed jobs go toCLOSED_JOBSin the run's default key-value store; the baseline lives in the namedats-jobs-diff-statestore under your account. The baseline stores only hashes and labels (never job bodies) and shards by ATS if it grows past ~9 MB, so even an 80k-job watchlist stays lean. - Response size. Runs on a 512 MB floor. Greenhouse returns a whole board in one un-paginated response (biggest real boards ~35 MB), so its fetch is capped at 64 MB; other systems paginate and are capped at 30 MB (tunable via
ATS_MAX_RESPONSE_BYTES). An over-size response is refused for that one source, not the whole run.
Changelog
- 0.2.10 — 2026-07-16 — Added a public live-status link (real self-test results, no login).
- 0.2.9 — 2026-07-16 — Filter before capping, plus honesty fixes.
maxResultsPerSourcenow caps matching jobs, not raw rows: filters run over the whole board first, then the matches are capped — so a job that matches your keywords/location/date is never hidden past the cap (it previously could be). Per-board cost ceilings are unchanged (still at most the cap × $0.001 per board). In diff mode, closed-job detection now skips a board only when its matching jobs exceed the cap, so big boards whose matches fit under the cap get full closed detection. InvalidpostedAfterdates are rejected with a plain-English error instead of silently disabling the date filter. DistinctdiffStateKeyvalues can no longer collide onto one baseline (a key with special characters gets a short hash appended; plain keys are unchanged, so existing baselines keep resolving). Plus honest wording forschemaVersion(a breaking-contract version, not an exact-shape fingerprint) and provenance references. All backward-compatible for existing pipelines. - 0.2.8 — 2026-07-16 — Bare API
{}now runs the demo. An API call with nosources,companies, orpresetruns the 5 prefilled demo boards (up to $0.25 at the default 50-job cap), matching the Console's "press Start" demo, instead of failing with "no usable sources." An explicitsources: []still returns a clean error, and bad input still fails with the same messages. Billing note: a bare{}first run is now billable (worst case $0.25) rather than free. - 0.2.2 — 2026-07-16 — Three additive features. Company autodetect: optional
companiesinput resolves names/careers URLs to{ ats, token }sources (free; misses reported inRESOLUTION_REPORT; bounded bymaxCompanies). Schema-stability contract: existing output fields are never renamed/removed within a major version; every record now carriesschemaVersion(currently1), also inRUN_SUMMARY. Degradation warning: a run that succeeds with one or more board errors sets aWARNINGstatus and writesDEGRADED_SOURCES; a failed board is never treated as closed or charged. All additive — existing pipelines unaffected. - Diff mode — Optional
diffModereturns only new + changed jobs and charges only for those; addschangeType/firstSeenAt, aCLOSED_JOBSsummary, and a per-buyer private baseline in the namedats-jobs-diff-statekey-value store. Off by default; non-diff runs are unchanged. - 0.1.0 — Initial build. Five ATS normalizers, one normalized schema, per-source failure isolation, retries/backoff, rate limiting, validation with
REJECTS, run summary, bundled verified-live company presets, unit tests + live smoke test.
Need to find which companies use these hiring systems first? ATS Company Discovery returns verified-live companies with current job counts ($2/1k). If this actor saved you time, an honest review helps others find it.