UK & EU Company Job Feeds (ATS Jobs API) avatar

UK & EU Company Job Feeds (ATS Jobs API)

Pricing

from $1.50 / 1,000 job returneds

Go to Apify Store
UK & EU Company Job Feeds (ATS Jobs API)

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

Musson Tools

Maintained by Community

Actor 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, country and an ISO country_code, plus remote. workplace_type is 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.source field 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: true reminds 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 SUMMARY record 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

ATSBoard URL exampleOr use
Greenhousehttps://job-boards.greenhouse.io/monzogreenhouse:monzo
Lever (US/EU)https://jobs.lever.co/palantir, https://jobs.eu.lever.co/…lever:palantir
Ashbyhttps://jobs.ashbyhq.com/synthesiaashby:synthesia
Workablehttps://apply.workable.com/blueground/workable:blueground
Teamtailorhttps://tibber.teamtailor.com or a custom domain such as https://jobs.tibber.comteamtailor:tibber
Personiohttps://ottonova.jobs.personio.depersonio:ottonova
Recruiteehttps://bunq.recruitee.com or a custom domain such as careers.bunq.comrecruitee: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

FieldDefaultDescription
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.
searchDescriptionsfalseAlso 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.
includeRegionalRemotetrueWith European countries selected, also keep remote jobs listed as "Europe", "EMEA" or "Worldwide".
locations–Location text contains, e.g. London, Manchester, Berlin.
remoteOnlyfalseRemote jobs only.
employmentTypes–full_time, part_time, contract, temporary, internship, apprenticeship, working_student.
postedSince–2026-10-01, 24 hours, 7 days, 1 month.
onlyNewJobsfalseIncremental mode (see below).
stateKeyautoThe name of the incremental memory, so you can keep separate searches apart.
descriptionFormatmarkdown_and_textmarkdown_and_text, markdown, text or none.
maxJobsPerCompany00 = no limit. Newest jobs come first.
maxJobs00 = no limit. You can also cap spend with the run's maximum cost.
personioLanguage–Language code (en, de…) for Personio feeds.
maxConcurrency4Boards 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_type is normalised. employment_type_raw keeps the ATS's own wording.
  • workplace_type and employment_type are null when the ATS doesn't publish them.
  • posted_at and updated_at are 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_LARGE or INVALID_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 ApifyClient
client = 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 SUMMARY record.
  • For a "remote in Europe" feed, use countries: ["Europe"] and remoteOnly: true. Keep includeRegionalRemote on.
  • 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_text for 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.