Ashby Jobs API & Workable Jobs Scraper (Unofficial)
Pricing
from $2.00 / 1,000 jobs
Ashby Jobs API & Workable Jobs Scraper (Unofficial)
Ashby jobs and Workable jobs from public ATS job boards and careers pages in one schema. Each run flags new, changed and closed jobs; output only the changes. Ashby salary ranges. Filter by title, location, department and remote. Job board API, no login. Not affiliated with Ashby or Workable.
Pricing
from $2.00 / 1,000 jobs
Rating
0.0
(0)
Developer
Gray Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Get jobs from public Ashby job boards and Workable careers pages (ATS job boards) in one clean schema, and see what changed since your last run. Every row is marked new, changed or unchanged, and jobs that were taken down are reported once as closed.
Give it a list of companies (a board name or the careers page URL), then schedule it. No account, login or API key is needed.
- Change tracking built in. Turn on
onlyChangesto get only the new, changed and closed jobs each day. Skipped unchanged jobs are not charged. - Pay ranges from Ashby when a company shows them on its postings (
salaryMin,salaryMax,salaryCurrency,salaryInterval). - Filters: title keywords, location, department or team, and workplace type (remote, hybrid, on-site).
- A bad board never fails the run. It is listed in
RUN_SUMMARYwith a plain-language reason, and every other board is still saved. - Company and job data only. No recruiter or hiring-manager fields. Full descriptions are off by default; when you turn them on, emails, phone numbers, profile links and cued names are removed.
Unofficial. Not affiliated with, endorsed by or sponsored by Ashby, Inc. or Workable Technology Limited.
What data can you extract?
Company and job fields only. There are no recruiter, hiring-manager or other person fields.
| Field | What it is |
|---|---|
jobKey | Stable unique key: ashby:<board>:<id> or workable:<account>:<shortcode> |
source, sourceName, board | ashby or workable, the source's name, and the board or account name |
companyName | Company name as shown on the Workable account (Ashby's job board API does not provide one) |
jobId, requisitionId | The posting's id and, where published, the company's requisition code (Workable) |
title, departments, team | Job title, department and team (team: Ashby) |
location, allLocations, country | Location text, all listed locations, country code (Workable) |
workplaceType, isRemote | remote, hybrid or on-site (Ashby); Workable flags remote jobs only |
employmentType | e.g. Full-time, Contract |
salaryMin, salaryMax, salaryCurrency, salaryInterval | Pay range when the company shows one on its Ashby postings |
postedAt | When the job was (last) published, as given by the source |
updatedAt, applicationDeadline, language | Kept for a stable schema; neither source publishes them, so they are null |
jobUrl, applyUrl | Link to the original job page and the application page |
description, descriptionRedactions | Full description, only when Include full job descriptions is on (otherwise null), with personal details removed (see Privacy), and how many were removed |
changeStatus, firstSeenAt, lastSeenAt, closedAt | Change tracking (see below) |
retrievedAt | When this run read the job |
Change tracking
With trackChanges on (default), the Actor remembers each board's jobs in a named key-value store in your account (ats-jobs-feed-state). History is kept per feed, so separate feeds never interfere:
- Run from a saved task: the task is the feed. Two tasks that watch the same board each get every job as
newthe first time, and each keeps its own history. - Run directly (API or Console, no task): the feed is the combination of boards and filters (keywords, locations, departments, workplace types; order and letter case don't matter). Changing the boards or filters starts a new feed, whose first run reports every job as
new. ChangingonlyChanges,includeClosed,includeDescriptions,maxJobsormaxRequestskeeps the history.
RUN_SUMMARY.stateFeedId shows which feed a run used. On the next run of the same feed:
new: the job was not on the board last time.changed: title, location, department, pay or another job field changed (Ashby: also the description).unchanged: same as last time (skip these withonlyChanges; skipped rows are not charged).closed: the job was on the board last time and is gone now. It is reported once with its last known details andclosedAt, then forgotten.
Safety rules:
- A board that fails in a run never marks its jobs as closed.
- A board whose rows were not all saved (for example because
maxJobsor your maximum cost per run was reached) keeps its previous state, so nothing is missed next time. - A posting that is still listed but can't be read this run (for example a missing title) is not reported as closed. If a posting has no readable id at all, no job on that board is marked closed in that run.
firstSeenAtis the first run of the feed that saw the job.
Reliability
- Each board is fetched and processed in isolation. Errors are recorded per board in
RUN_SUMMARYwith a reason such as "says this board does not exist (HTTP 404)". - The run only fails if every board fails. If some fail, the run succeeds with status
partial. - Temporary errors (timeouts, 5xx) are retried with exponential backoff. HTTP 429 waits for the time the API asks for.
- Requests are paced per source (Ashby: at least 0.5 seconds apart; Workable: at least 1.5 seconds apart).
maxRequestscaps HTTP calls per run, retries included;maxJobscaps saved rows.- Every row is validated against the output schema; postings without a title or link are skipped and counted.
Use cases
- Daily feed of new openings at a list of startups and scale-ups, for a job board, newsletter or community.
- Labour-market and hiring-trend research: how many roles a set of companies opens and closes per week, by department or location.
- Tracking published pay ranges for a role across companies (Ashby boards).
- Keeping your own careers aggregator in sync, including removing closed roles.
How to use it
- Add companies under Ashby job boards (e.g.
acmeorjobs.ashbyhq.com/acme) and/or Workable accounts (e.g.acme,apply.workable.com/acmeoracme.workable.com). - Optionally filter by title keywords, locations, departments or workplace type.
- Run it. Schedule it daily and turn on Only output changes for a change feed.
- Read the jobs from the dataset and the per-board results from
RUN_SUMMARY.
Finding the board name: open the company's careers page. If job links go to jobs.ashbyhq.com/<name> or apply.workable.com/<name>, that <name> is what you enter. You can also paste the URL.
Input examples
These are also in the examples/ folder.
Daily change feed for a few companies (schedule it daily; only new, changed and closed jobs are saved) (examples/daily-change-feed.json):
{"ashbyBoards": ["linear", "ramp", "jobs.ashbyhq.com/notion", "supabase"],"workableAccounts": ["huggingface", "apply.workable.com/getresponse"],"onlyChanges": true,"maxJobs": 2000}
Remote engineering roles at a few companies (examples/remote-engineering.json):
{"ashbyBoards": ["linear", "supabase"],"workableAccounts": ["huggingface"],"keywords": ["engineer", "developer", "sre"],"workplaceTypes": ["remote"],"maxJobs": 500}
One company's engineering roles in one city, with full descriptions, without change tracking (examples/one-company-with-descriptions.json):
{"ashbyBoards": ["openai"],"keywords": ["engineer"],"locations": ["San Francisco"],"includeDescriptions": true,"trackChanges": false,"maxJobs": 100}
Output example
Real sample: 3 rows from a test run on October 25, 2026, with the default input and change tracking off (links shown without the protocol; the dataset has full links; one long location list shortened). With Include full job descriptions on, description holds the cleaned text, for example "Hi 👋 I’m [name removed] [profile link removed] Head of EMEA Engineering. ..." (from a real Ashby posting), and descriptionRedactions counts the removals.
[{"jobKey": "workable:huggingface:81B46579FE","source": "workable","sourceName": "Workable public jobs","board": "huggingface","companyName": "Hugging Face","jobId": "81B46579FE","title": "Open-Source Machine Learning Engineer - EMEA Remote","departments": ["Open Source"],"team": null,"location": "Paris, Île-de-France, France","allLocations": ["Paris, Île-de-France, France"],"country": "FR","workplaceType": "remote","isRemote": true,"employmentType": "Full-time","salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryInterval": null,"requisitionId": null,"language": null,"postedAt": "2026-05-29T00:00:00.000Z","updatedAt": null,"applicationDeadline": null,"jobUrl": "apply.workable.com/j/81B46579FE","applyUrl": "apply.workable.com/j/81B46579FE/apply","description": null,"descriptionRedactions": null,"changeStatus": null,"firstSeenAt": null,"lastSeenAt": null,"closedAt": null,"retrievedAt": "2026-10-25T15:41:49.321Z"},{"jobKey": "ashby:ashby:7458d4e9-da2e-47bd-98cb-adfda43d42b2","source": "ashby","sourceName": "Ashby public job board","board": "ashby","companyName": null,"jobId": "7458d4e9-da2e-47bd-98cb-adfda43d42b2","title": "Engineering Manager - EU","departments": ["Engineering"],"team": "EMEA Engineering","location": "Remote - European Union","allLocations": ["Remote - European Union", "Spain", "Italy", "Germany", "…"],"country": null,"workplaceType": "remote","isRemote": true,"employmentType": "Full-time","salaryMin": 150000,"salaryMax": 250000,"salaryCurrency": "EUR","salaryInterval": "1 YEAR","requisitionId": null,"language": null,"postedAt": "2024-03-04T14:29:08.532+00:00","updatedAt": null,"applicationDeadline": null,"jobUrl": "jobs.ashbyhq.com/ashby/7458d4e9-da2e-47bd-98cb-adfda43d42b2","applyUrl": "jobs.ashbyhq.com/ashby/7458d4e9-da2e-47bd-98cb-adfda43d42b2/application","description": null,"descriptionRedactions": null,"changeStatus": null,"firstSeenAt": null,"lastSeenAt": null,"closedAt": null,"retrievedAt": "2026-10-25T15:41:49.592Z"},{"jobKey": "ashby:ashby:86a60834-ba64-484d-9658-afa1bc97a957","source": "ashby","sourceName": "Ashby public job board","board": "ashby","companyName": null,"jobId": "86a60834-ba64-484d-9658-afa1bc97a957","title": "Mid Market Account Executive - EMEA (French Speaking)","departments": ["Sales"],"team": "Sales","location": "France","allLocations": ["France","United Kingdom","Belgium","Germany","Switzerland","Ireland","Austria","Spain","Stuttgart","Berlin"],"country": null,"workplaceType": "remote","isRemote": true,"employmentType": "Full-time","salaryMin": 110000,"salaryMax": 195500,"salaryCurrency": "EUR","salaryInterval": "1 YEAR","requisitionId": null,"language": null,"postedAt": "2026-09-08T16:27:26.694+00:00","updatedAt": null,"applicationDeadline": null,"jobUrl": "jobs.ashbyhq.com/ashby/86a60834-ba64-484d-9658-afa1bc97a957","applyUrl": "jobs.ashbyhq.com/ashby/86a60834-ba64-484d-9658-afa1bc97a957/application","description": null,"descriptionRedactions": null,"changeStatus": null,"firstSeenAt": null,"lastSeenAt": null,"closedAt": null,"retrievedAt": "2026-10-25T15:41:49.592Z"}]
How much does it cost?
Pay per event, with no subscription:
- $0.01 per run start,
- $2.00 per 1,000 jobs saved ($0.002 per row,
closedrows included; unchanged rows skipped byonlyChangesare free). Failed boards cost nothing.
Example: a full run that saves 1,000 jobs costs $0.01 + $2.00 = $2.01. A daily onlyChanges run usually costs much less than a full run, because only changes are saved. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.
Privacy: company and job data only
- The output has no person fields. Any other fields in the source data are dropped.
- Full job descriptions are off by default. Rows still have the title, company, location, department, links and dates. Descriptions are each employer's own text; turn them on only if you need them.
- With Include full job descriptions on, descriptions are plain text with email addresses, phone numbers, profile links (LinkedIn, Calendly, X/Twitter), names right before a profile link, and names after cues such as "contact", "recruiter", "hiring manager", "reports to", "created by", "I'm" or "my name is" replaced with placeholders like
[name removed]. - Limits: a name written with no such cue (for example a bare "Alex will onboard you") can't be told apart from other capitalised words and may remain. Leave Include full job descriptions off (the default) if you need zero free text.
- Ashby postings that a company marks as not listed (reachable by direct link only) are left out.
- Use the data for job-related purposes. Don't use it to contact people. Workable's robots.txt asks that its content not be used to train AI models; please respect that.
Limits
- Ashby's job board API does not include the company name, so
companyNameis empty for Ashby rows (boardholds the company's Ashby name). - Neither endpoint supports server-side filtering, so filters are applied after download: each board is still read in full.
- Workplace type: Ashby gives remote, hybrid or on-site. Workable's public endpoint only says whether a job is remote, so non-remote Workable jobs have
workplaceTypenullandisRemotefalse. - Workable descriptions are only downloaded when Include full job descriptions is on, so a Workable job whose description alone was edited is not marked
changed. Ashby description edits are detected either way. - The sources do not publish rate limits for these endpoints. The Actor paces itself and stops a board after repeated rate-limit responses.
- Change tracking remembers up to 100,000 jobs per board per feed. Very large boards (several thousand jobs with long descriptions) may need more memory than the 256 MB default.
Integrations and API
Use the Apify API, webhooks, or integrations (Zapier, Make, Google Sheets, Slack and others) to send each run's new and changed jobs wherever you need them. The per-board results are in the RUN_SUMMARY record of the run's default key-value store.
FAQ
Does it need an Ashby or Workable account? No. It reads public job board data that needs no login or key.
Why did a board fail? See RUN_SUMMARY.boards. The most common reason is a wrong board name or a company that no longer uses that job board (HTTP 404).
How do I reset change tracking? Delete the ats-jobs-feed-state key-value store in your account (this resets every feed), or start a new task.
Is it official? No. It is an independent tool, not affiliated with Ashby or Workable.
How do I find a company's Ashby board name? Open its careers page. If job links go to jobs.ashbyhq.com/<name>, enter <name> or paste the URL. For Workable, it's apply.workable.com/<name> or <name>.workable.com.
Does it show salaries? Yes for Ashby, when the company publishes a pay range on the posting. Workable's public endpoint has no pay fields.
Does it cover SmartRecruiters, Greenhouse or Lever? Not SmartRecruiters. Greenhouse and Lever are covered by our separate Greenhouse Jobs API & Lever Jobs Scraper actor on the Apify Store.
Why is companyName empty on Ashby rows? Ashby's job board API doesn't return a company name. board holds the company's Ashby name.
What does it cost? $0.01 per run plus $0.002 per saved job ($2.00 per 1,000). Closed-job rows count as saved; unchanged jobs skipped with onlyChanges are free.
How do I get only new jobs each day? Turn on onlyChanges and schedule the Actor daily. You get new, changed and closed jobs; unchanged jobs are skipped and not charged.