🇪🇺 EURES European Jobs Scraper — 2M+ Jobs, 31 Countries
Pricing
from $2.30 / 1,000 job results
🇪🇺 EURES European Jobs Scraper — 2M+ Jobs, 31 Countries
Scrape 2M+ live vacancies from EURES, the EU's official job portal covering 31 European countries — no login, no cookies, no proxies. Filter by keyword, country, contract type, working time, education & experience. Clean JSON with employer, apply URL, dates. Delta mode for job alerts.
Search 2M+ live vacancies on EURES, the European Commission's official job-mobility portal covering 31 European countries (EU + EEA + Switzerland), via its public jv-search REST API.
- No login, no cookies, no proxies — reads the official public API directly
- Server-side filters — keyword, country/NUTS region, contract type, working time, education, experience, posting age
- Clean, flat JSON — employer, apply URL, posted date, ESCO occupation categories
- Delta mode — scheduled runs emit only postings not seen before, so job-alert pipelines pay only for new results
What EURES jobs data does this scraper extract?
Each result is one flat JSON record per job posting:
| Field | Meaning |
|---|---|
id | Stable source-side identifier |
title | Job title as posted |
company | Hiring company / organisation (null if EURES doesn't disclose one) |
country | ISO country code(s) the vacancy is located in (e.g. "DE", or "DE, FR" for multi-country postings). EURES exposes country + NUTS-region codes, not free-text city names, so this is code data, not a street address |
location | Deprecated alias of country — identical value, kept for backward compatibility. New integrations should read country |
url | Direct link to the posting on the EURES portal |
postedAt | Posting date (YYYY-MM-DD), or null if EURES didn't supply a valid creation date |
lastModifiedAt | Date the posting was last updated (YYYY-MM-DD), or null |
contractType | Contract type code, e.g. directhire (permanent), temporary, internship, apprenticeship, seasonal, selfemployed… (null if unspecified) |
workingTime | Working-time codes, e.g. ["fulltime"], ["parttime"], ["flextime"] (null if unspecified) |
jobCategories | ESCO occupation URIs the vacancy is classified under (null if unclassified) |
languages | ISO 639-1 codes the vacancy is advertised in, e.g. ["en", "fr"] (null if none) |
numberOfPosts | How many positions this vacancy is hiring for (null if not stated) |
euresFlag | true when flagged as a cross-border / EURES-network opportunity |
employerWebsite | Employer website URL when disclosed (often null — EURES rarely populates it) |
employerSector | NACE economic-sector codes for the employer (often null) |
snippet | Short plain-text description excerpt (HTML stripped) |
source | Always "eures" |
How to scrape EURES jobs with this Actor
- Click Try for free / Run — no login to the target site, no cookies, no proxies to configure.
- Adjust the input (keyword, filters,
maxItems) or keep the defaults. - Run it and export the dataset as JSON, CSV or Excel, or read it over the API.
Run it from your own code:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nomad-agent/eures-scraper").call(run_input={"maxItems": 50})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], "—", item["company"], item["url"])
Or a single HTTP call that runs the Actor and returns items in one response:
curl -X POST \"https://api.apify.com/v2/acts/nomad-agent~eures-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"maxItems": 50}'
Input
| Field | Type | Default | Notes |
|---|---|---|---|
keywords | array | (built-in seeds) | One or more search terms. The scraper fans one API call per keyword and deduplicates results. Leave empty to use a built-in set of professional role seeds. |
locationCodes | array | (all EU) | Restrict results to specific EU countries or NUTS regions. Use ISO 3166-1 alpha-2 country codes (e.g. "de", "es", "fr") or NUTS codes. Leave empty to search all EU member states. |
publishedWithin | string (day|week|month) | week | Only fetch vacancies EURES marks as posted within this window (filtered server-side by the EURES API). week matches this Actor's previous fixed behaviour. |
contractType | array (multi-select) | (all) | Server-side filter: keep only vacancies offering one of these contract types (directhire, temporary, temporarytohire, contracttohire, contract, apprenticeship, internship, seasonal, selfemployed, oncall, volunteer, recruitmentreserve). |
workingTime | array (multi-select) | (all) | Server-side filter: keep only vacancies with one of these working-time patterns (fulltime, parttime, flextime). |
educationLevel | array (multi-select) | (all) | Server-side filter: keep only vacancies requiring one of these education levels (basic, medium, tertiary, bachelor, master, doctoral). |
experienceLevel | array (multi-select) | (all) | Server-side filter: keep only vacancies requiring one of these experience bands (none_required, up_to_1_year, between_1_and_2_years, between_2_and_5_years, more_than_5_years). |
titleExclude | array of strings | [] | Skip listings whose title contains any of these case-insensitive terms. |
companyExclude | array of strings | [] | Skip listings whose company name contains any of these case-insensitive terms. |
onlyNewSinceLastRun | boolean | false | Delta / incremental mode: remember every vacancy id returned on previous runs and emit only postings not seen before. Ideal for scheduled runs / job-alert bots — you pay only for genuinely new vacancies. State persists in a named key-value store across runs. |
maxItems | integer | 50 (max 5000) | Maximum number of vacancies to return across all keyword queries. Combined with deduplication, this is a hard cap on pushed records. Each result returned is billed — see Pricing below. |
timeoutSeconds (Advanced) | integer | 20 | How long to wait for a reply from the EURES API before giving up on that request, in seconds. |
cacheTtlSeconds (Advanced) | integer | 1800 | Reuse a search's results for this many seconds instead of asking EURES again, so quick repeat runs are faster and cheaper. Set 0 to always fetch fresh results. |
Output example
{"id": "8823771","title": "Mechatronics Technician","company": "Siemens AG","country": "DE","location": "DE","url": "https://europa.eu/eures/portal/jv-se/jv-details/8823771","postedAt": "2026-06-30","lastModifiedAt": "2026-07-01","contractType": "directhire","workingTime": ["fulltime"],"jobCategories": ["http://data.europa.eu/esco/occupation/1234abcd-..."],"languages": ["de", "en"],"numberOfPosts": 1,"euresFlag": false,"employerWebsite": null,"employerSector": null,"snippet": "Siemens is hiring a mechatronics technician...","source": "eures"}
Integrations
Export the dataset as JSON, CSV or Excel from the Console, pull it over the Apify API (e.g. run-sync-get-dataset-items for a single blocking call), wire it into Make/Zapier/n8n, or call it as a tool from AI agents via the Apify MCP server.
Pricing
Pay per event: $0.005 per Actor start and $0.003 per job returned. 100 jobs ≈ $0.305. No subscription, no rental — you pay only for what you fetch.
Use cases
- Pan-EU job boards and relocation services
- Cross-border labour-market research
- Job-alert bots for EU-wide searches
- Feeding matching engines with EU-wide supply
How this EURES scraper compares
| This Actor | Typical alternatives | |
|---|---|---|
| Data source | Official EURES public REST API — no headless browser, so runs finish in seconds | HTML scraping or browser automation |
| Delta mode | ✅ onlyNewSinceLastRun remembers past results across runs — scheduled alerts pay only for new postings | ❌ every run re-bills the same postings |
| Server-side filters | Contract type (12 values), working time, education, experience, country/NUTS region, posting age — filtered by EURES itself, so you're never billed for records you'd discard | usually keyword + country only |
| Login / cookies / proxies | None needed | often required |
| Failure handling | Fail-open: bounded retries with backoff; unexpected errors end the run SUCCEEDED with an uncharged diagnostic row, so scheduled pipelines never break | hard failures |
FAQ
Is it legal to scrape EURES jobs? This Actor reads only publicly available job postings — data any visitor can see without logging in. No personal data behind authentication is touched. Review the target site's terms and your local regulations for your specific use case.
Do I need an account on the target site? No. Postings are fetched from public pages/APIs — no login, cookies or session tokens.
How fresh is the data?
Every run fetches live listings, filtered server-side by EURES to postings from the last day/week/month via the publishedWithin input (default: last week). Within that, results are cached for cacheTtlSeconds (default 30 min, set 0 to always hit the source live).
How many jobs can I get?
maxItems caps the run (default 50, maximum 5000). Results are sorted by keyword-match relevance, not strictly newest-first. For very large pulls, add more keywords so the fan-out reaches distinct postings, and raise the run's timeout if needed.
Can I filter by contract type, hours or education?
Yes — contractType, workingTime, educationLevel and experienceLevel are applied server-side by EURES itself, so filtered runs fetch (and bill) only matching vacancies. Combine them with keywords, locationCodes and publishedWithin.
Can I fetch only new jobs on a schedule?
Set onlyNewSinceLastRun: true. The Actor remembers vacancy ids across runs in a named key-value store and emits only postings it hasn't seen before — perfect for daily job-alert bots, and you only pay for genuinely new vacancies.
Does it return salary data?
The EURES public jv-search API returns no structured salary field — verified directly against the live response, which carries no salary/compensation attribute on the vacancy or employer object. Where an employer states pay, it appears only inside the free-text snippet/description. This Actor deliberately emits no salary field rather than an always-empty or guessed one.
Is scraping EURES allowed? EURES data comes from its public API. Per the portal's terms it is intended for personal / link-back use — review the EURES terms for your use case.
How reliable are the runs? The Actor is built fail-open: transient EURES/API hiccups are retried with backoff, and any unexpected error ends the run SUCCEEDED with a single uncharged diagnostic row rather than a hard failure — so scheduled pipelines never break on a blip and you are never billed for a non-result.
Something broken or missing? Open an issue on the Actor's Issues tab — it is monitored and reliability fixes ship fast.
Is this Actor useful to you? A quick ⭐ review on the Actor's Reviews tab helps other EU job seekers find it — and tells us what to build next.
Related Actors
- Europe Jobs Scraper — 14 Sources in One — this Actor plus 13 more European job boards in a single run
- Research & Academic Jobs Scraper — 12 Sources
- InfoJobs Scraper — Ofertas de Trabajo y Empleo España — AI skill tags, structured salary, delta mode
- Tecnoempleo Scraper — Spain IT & Tech Jobs
- LinkedIn Jobs Scraper — No Login, No Cookies
From the maker of Oink — an open-source, AI-powered job-search bot for Telegram that runs on these Actors. Try the free bot, get a managed instance at oinkjobsearch.com, or browse the full catalog of 50+ Actors.