UK & EU Company Job Feeds (ATS Jobs API)
Pricing
from $1.50 / 1,000 job returneds
UK & EU Company Job Feeds (ATS Jobs API)
Pull live jobs from Greenhouse, Lever, Ashby, Workable, Teamtailor, Personio and Recruitee boards. UK/EU filters, salaries, remote flags and only-new-jobs mode.
Pricing
from $1.50 / 1,000 job returneds
Rating
0.0
(0)
Developer
Musson Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
UK & EU Company Job Feeds: Greenhouse, Lever, Ashby, Workable, Teamtailor, Personio, Recruitee jobs API
Get every open job straight from company career boards. Give it a list of companies and you get clean, normalised job data in one schema, whatever applicant tracking system (ATS) each company uses: Greenhouse, Lever, Ashby, Workable, Teamtailor, Personio or Recruitee. Each job comes with its city and country, a remote flag, salary when published, posted and updated dates, the apply link and the description as Markdown and plain text. It's built for UK and EU job data. You can filter by country (UK+EU, DACH, Nordics and more), keywords, remote, employment type and date, and incremental mode returns only the jobs that are new since your last run.
- 🏢 7 ATSs, one schema. It reads Greenhouse, Lever (US and EU), Ashby, Workable, Teamtailor (including custom career domains), Personio (.de/.com) and Recruitee (including custom domains).
- 🔎 Auto-detects the ATS. Paste a board URL, the company's own careers page (for example
monzo.com/careers),ats:slug, or just a slug. - 🌍 Parsed locations. Each location has
city,region,countryand an ISOcountry_code, plusremote.workplace_typeis remote, hybrid or onsite. - 💷 Salary when published. It comes from the ATS's pay fields (Greenhouse pay transparency, Lever, Ashby, Recruitee) or, as a fallback, from a £/€/$ range in the description. The
salary.sourcefield tells you which. - 🆕 Incremental mode (
onlyNewJobs). Schedule it daily and you get (and pay for) only jobs you haven't seen before. - 🧾 Descriptions ready for LLMs. You get Markdown and/or plain text.
content_is_untrusted: truereminds AI pipelines to treat job text as data. - 💸 Failed boards are free. A wrong slug, a removed board or an undetectable page is listed in the
SUMMARYrecord with an error code, and you're never charged for it. - 🤝 Polite and compliant. It only uses the official public job-board endpoints that these ATSs publish for embedding job listings. It needs no logins, no proxies and no scraping of HTML job pages. It respects robots.txt, including crawl-delay, spaces out requests and only fetches public internet addresses (SSRF-safe).
Who it's for
- Job boards and aggregators building niche UK and EU feeds (tech, fintech, climate, remote-in-Europe).
- Recruiters and agencies watching target companies for new roles every morning.
- Sales and market intelligence teams, where hiring is a buying signal. You can track which companies are hiring for which teams, and where.
- Job seekers and AI agents that want a clean, deduplicated list of real openings straight from the source, with apply links.
- Researchers studying salaries, remote work and hiring trends in the UK and Europe.
Supported ATSs and what to paste
| ATS | Board URL example | Or use |
|---|---|---|
| Greenhouse | https://job-boards.greenhouse.io/monzo | greenhouse:monzo |
| Lever (US/EU) | https://jobs.lever.co/palantir, https://jobs.eu.lever.co/… | lever:palantir |
| Ashby | https://jobs.ashbyhq.com/synthesia | ashby:synthesia |
| Workable | https://apply.workable.com/blueground/ | workable:blueground |
| Teamtailor | https://tibber.teamtailor.com or a custom domain such as https://jobs.tibber.com | teamtailor:tibber |
| Personio | https://ottonova.jobs.personio.de | personio:ottonova |
| Recruitee | https://bunq.recruitee.com or a custom domain such as careers.bunq.com | recruitee:bunq |
You can also paste a company's own careers page. The Actor finds the embedded or linked ATS board on it, for example https://monzo.com/careers → Greenhouse monzo. A bare slug such as monzo is tried against every ATS, and the board with jobs wins.
SmartRecruiters isn't supported, because its API host's robots.txt disallows automated access, and we respect that. Workday and other ATSs that have no public job-board API aren't supported either.
Input
| Field | Default | Description |
|---|---|---|
companies | – | Board URLs, careers pages, ats:slug or slugs (up to 500). |
keywords | – | Keep jobs whose title, department or team contains any of these (word prefix, so engineer matches engineering). |
excludeKeywords | – | Drop matching titles, e.g. intern, principal. |
searchDescriptions | false | Also match keywords against the description. |
departments | – | Department or team contains any of these. |
countries | – | ISO codes or names, or groups: UK+EU, EU, EEA, Europe, DACH, Nordics, Benelux. |
includeRegionalRemote | true | With European countries selected, also keep remote jobs listed as "Europe", "EMEA" or "Worldwide". |
locations | – | Location text contains, e.g. London, Manchester, Berlin. |
remoteOnly | false | Remote jobs only. |
employmentTypes | – | full_time, part_time, contract, temporary, internship, apprenticeship, working_student. |
postedSince | – | 2026-10-01, 24 hours, 7 days, 1 month. |
onlyNewJobs | false | Incremental mode (see below). |
stateKey | auto | The name of the incremental memory, so you can keep separate searches apart. |
descriptionFormat | markdown_and_text | markdown_and_text, markdown, text or none. |
maxJobsPerCompany | 0 | 0 = no limit. Newest jobs come first. |
maxJobs | 0 | 0 = no limit. You can also cap spend with the run's maximum cost. |
personioLanguage | – | Language code (en, de…) for Personio feeds. |
maxConcurrency | 4 | Boards fetched in parallel. |
{"companies": ["https://monzo.com/careers","https://jobs.lever.co/palantir","ashby:synthesia","https://tibber.teamtailor.com","https://bunq.recruitee.com"],"countries": ["UK+EU"],"keywords": ["engineer", "data"],"excludeKeywords": ["intern"],"postedSince": "14 days","descriptionFormat": "markdown"}
Output
One dataset item per job, shown here shortened:
{"company": "GoCardless","company_slug": "gocardless","ats": "greenhouse","job_id": "8305812","job_key": "greenhouse:gocardless:8305812","title": "Product Manager","department": "Product Development","team": null,"locations": [{ "raw": "Lisbon, Portugal", "city": "Lisbon", "region": null, "country": "Portugal", "country_code": "PT", "remote": false }],"location_text": "Lisbon, Portugal","remote": false,"workplace_type": null,"employment_type": null,"employment_type_raw": null,"seniority": null,"salary": { "min": 46400, "max": 69600, "currency": "EUR", "interval": "year", "interval_inferred": true, "text": "€46,400 - €69,600", "source": "description" },"posted_at": "2026-10-21T13:14:15Z","updated_at": "2026-10-26T15:03:11Z","job_url": "https://job-boards.greenhouse.io/gocardless/jobs/8305812","apply_url": "https://job-boards.greenhouse.io/gocardless/jobs/8305812","description_markdown": "## About us\n\nGoCardless is a global payments company…","description_text": "About us\nGoCardless is a global payments company…","fetched_at": "2026-10-26T16:58:04Z","content_is_untrusted": true}
employment_typeis normalised.employment_type_rawkeeps the ATS's own wording.workplace_typeandemployment_typearenullwhen the ATS doesn't publish them.posted_atandupdated_atare UTC.- Use
job_key(ats:slug:job_id) as a stable ID for deduplication.
The dataset has three views. Overview shows one row per job. Locations shows one row per job location. Descriptions shows the job descriptions.
A SUMMARY record in the run's key-value store lists every input with:
- the ATS and slug detected
- jobs found, matched and returned
- an error code for any board that failed:
NOT_FOUND,ATS_NOT_DETECTED,URL_NOT_ALLOWED,ROBOTS_DISALLOWED,FETCH_FAILED,INVALID_FEED,RESPONSE_TOO_LARGEorINVALID_INPUT
Incremental mode: only new jobs
Turn on onlyNewJobs and schedule the Actor, for example daily.
- The first run returns all matching jobs. That's your baseline.
- Later runs return only jobs that weren't returned before under the same
stateKey, and you only pay for those new jobs. - Seen jobs are stored in your own named key-value store,
job-feeds-state, which keeps up to 300,000 job keys. - If a run stops early because of its budget, any jobs it didn't return stay "new" for the next run.
Pricing (pay per event)
- $0.0015 per job returned, which is $1.50 per 1,000 jobs, after your filters.
- Failed or empty boards cost nothing. Jobs your filters drop, or that incremental mode skips, aren't charged.
- The run respects your maximum cost per run and stops cleanly when it's reached.
Example: 50 UK/EU tech companies with about 40 matching roles each, run daily in incremental mode. The baseline costs about $3, and a typical day after that (about 30 new jobs) costs about $0.05.
Use it from code, agents and MCP
curl -X POST "https://api.apify.com/v2/acts/dear_enstatite~job-feeds/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"companies":["https://monzo.com/careers"],"countries":["GB"],"descriptionFormat":"none"}'
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("dear_enstatite/job-feeds").call(run_input={"companies": ["greenhouse:monzo", "lever:palantir"], "countries": ["UK+EU"], "onlyNewJobs": True})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["company"], job["title"], job["location_text"], job["apply_url"])
MCP (Claude, Cursor, ChatGPT and other AI agents): add https://mcp.apify.com/?tools=dear_enstatite/job-feeds as an MCP server.
Tips
- Not sure which ATS a company uses? Paste its careers page URL and check the
SUMMARYrecord. - For a "remote in Europe" feed, use
countries: ["Europe"]andremoteOnly: true. KeepincludeRegionalRemoteon. - Use
descriptionFormat: "none"for quick, small monitoring runs, and full descriptions for LLM enrichment. - Location parsing is rule-based and tuned for the UK and Europe. Always keep
location_textfor display.
Limitations
- Only companies whose ATS has a public job-board feed are supported (see the table above). Career pages built entirely in JavaScript may not reveal their ATS. In that case, pass
ats:slug. - Teamtailor and Personio feeds don't include salary or employment details beyond what's published there. Workable's public widget has no salary.
- EU-hosted Greenhouse boards (
job-boards.eu.greenhouse.io) aren't supported yet. - Job data belongs to the companies that publish it. Use it in line with their terms and applicable law, such as the UK GDPR for any personal data in descriptions.
Related
- Any Document to Markdown for RAG: turn PDFs, DOCX, PPTX and web pages into Markdown chunks.
- PDF for RAG: fast page-aware text extraction from PDFs.