# EURES Jobs Scraper — EU-Wide Vacancies, 30+ Countries (`studio-amba/eures-scraper`) Actor

Scrape job vacancies from EURES, the official EU job mobility portal covering 30+ European countries. Search by keyword, country or region, and publication date. Get titles, employers, locations, full descriptions, and dates. No login, no cookies. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/studio-amba/eures-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## EURES Jobs Scraper

Scrape job vacancies from [EURES](https://europa.eu/eures/portal/jv-se/search), the official EU job mobility portal run by the European Commission and the European Labour Authority. EURES aggregates the public employment service feeds of 30+ European countries (VDAB, Forem, Actiris, Bundesagentur für Arbeit, UWV, and many more) into one searchable index of roughly 3 million live vacancies.

One actor, one input format, jobs from the whole EU plus EEA countries. No login, no cookies.

### What you get

- **Job title and full description** in the original posting language, HTML stripped to plain text
- **Employer name** when the source feed provides it
- **Locations** as country + NUTS region codes, plus city and postal code with detail enrichment
- **Employment type** (fulltime, parttime) and contract type (directhire, contract, temporary...)
- **Publication and modification dates** as ISO 8601 timestamps
- **Application deadline, apply URL, and source feed** with detail enrichment
- **Direct link** to the job page on the EURES portal

### Why EURES

Most job scrapers cover one board in one country. EURES is the official aggregator: national public employment services push their vacancies into it, so a single query reaches Belgium, Germany, France, the Netherlands, Spain, Italy, Poland, the Nordics, and the rest of the EU/EEA at once. That makes it a practical base layer for cross-border recruiting, labour market research, and job aggregation products.

### How to scrape EURES data

1. Open the actor and set a **Search Query** (any language works: `software engineer`, `verpleegkundige`, `Krankenpfleger`)
2. Optionally add **Location Codes**: lowercase ISO2 country codes (`be`, `de`, `nl`) or NUTS region codes (`be2` for Flanders, `de21` for Upper Bavaria)
3. Optionally set a **Publication Period** (last 24 hours, last week, last month)
4. Set **Max Results** and run
5. Export the dataset as JSON, CSV, or Excel from the Storage tab

Turn on **Fetch Details** when you need city, postal code, apply URL, source feed, or application deadline. This costs one extra request per job, so a 100-job run stays quick but a 5,000-job run takes noticeably longer.

### Input example

```json
{
    "searchQuery": "verpleegkundige",
    "locationCodes": ["be", "nl"],
    "publicationPeriod": "LAST_MONTH",
    "fetchDetails": true,
    "maxResults": 100,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output example

```json
{
    "id": "NTg1NDQxMSAy",
    "title": "VERPLEEGKUNDIGE (V/M/X) M/V/X",
    "employer": "CARITAS INTERNATIONAL",
    "locations": [
        {
            "country": "BE",
            "regionCodes": ["BE211"],
            "city": "Borgerhout",
            "postalCode": "2140"
        }
    ],
    "description": "WERKEN BIJ ONS, DAT IS...\neen job uitoefenen die zin heeft én voldoening geeft. Omdat je, samen met je collega's, een stukje bijdraagt aan een meer rechtvaardige, meer solidaire wereld...",
    "employmentType": "fulltime",
    "contractType": "directhire",
    "numberOfPosts": 1,
    "publicationDate": "2026-06-08T06:33:01.973Z",
    "lastModificationDate": "2026-06-30T09:30:26.997Z",
    "expirationDate": "2026-07-31T00:00:00.000Z",
    "euresFlag": false,
    "language": "fr",
    "city": "Borgerhout",
    "postalCode": "2140",
    "source": "Actiris",
    "applyUrl": "https://caritasint.portal.carerix.com/jobportal/vacature/37",
    "detailUrl": "https://europa.eu/eures/portal/jv-se/jv-details/NTg1NDQxMSAy?lang=en",
    "scrapedAt": "2026-07-11T18:53:55.907Z"
}
```

Fields `city`, `postalCode`, `source`, `applyUrl`, and `expirationDate` are filled when **Fetch Details** is on. Without it you still get country and NUTS region codes for every job.

### Location codes

| Code | Coverage |
|------|----------|
| `be` | Belgium |
| `be2` | Flanders (NUTS1) |
| `de` | Germany |
| `de21` | Upper Bavaria (NUTS2) |
| `fr` | France |
| `nl` | Netherlands |
| `es` | Spain |
| `it` | Italy |
| `pl` | Poland |
| `se`, `dk`, `no`, `fi` | Nordics |

Any lowercase ISO2 country code of an EU/EEA member works, and NUTS1/NUTS2 codes narrow down to regions. Leave the list empty to search all countries at once.

### Use cases

- **Cross-border recruiting**: find candidates' target vacancies in several countries with one query
- **Labour market research**: track vacancy volumes per country, region, or occupation over time
- **Job board aggregation**: one feed instead of 30 national integrations
- **Lead generation**: employers actively hiring in a region, with apply links via detail enrichment
- **Salary and demand analysis**: full description text supports downstream extraction

### Practical notes

- A single query returns at most 10,000 results (API limit). Split by country or publication period to go deeper.
- Jobs come back in their original posting language. Search keywords match across all languages, so `nurse`, `verpleegkundige`, and `Krankenpfleger` return different (national) subsets.
- Descriptions are capped at 3,000 characters of plain text.
- The scraper deduplicates by vacancy ID, so items are unique within a run.
- Datacenter proxies are sufficient. The default proxy setting works as-is.

### Related scrapers

More European job scrapers from Studio AMBA:

- [Arbeitsagentur Scraper](https://apify.com/studio-amba/arbeitsagentur-scraper) — Germany's Federal Employment Agency job board
- [HelloWork Scraper](https://apify.com/studio-amba/hellowork-scraper) — France's biggest job site
- [IrishJobs Scraper](https://apify.com/studio-amba/irishjobs-scraper) — Ireland's leading job board
- [Jobindex Scraper](https://apify.com/studio-amba/jobindex-scraper) — Denmark's largest job database
- [StepStone Scraper](https://apify.com/studio-amba/stepstone-scraper) — Major European job platform

### FAQ

**Do I need an account or API key?**
No. The EURES search API is public.

**Which countries are covered?**
All EU member states plus EEA countries (Norway, Iceland, Liechtenstein) and Switzerland, wherever the national employment service publishes to EURES. Around 3 million vacancies are live at any time.

**How fresh is the data?**
National feeds push updates continuously. Use the publication period filter to get only recent postings.

**Can I filter by occupation or education level?**
Not yet in this version. Keyword search plus location and publication period covers most needs. Open an issue on the actor page if you need more filters.

**Is scraping EURES legal?**
The actor only reads publicly available vacancy data published by government employment services for the explicit purpose of job matching. Always review how you use and share scraped data.

# Actor input Schema

## `searchQuery` (type: `string`):

Keyword(s) to search for, matched everywhere (title, description, employer). Any language works because jobs are indexed in their original posting language. Examples: 'software engineer', 'verpleegkundige', 'chauffeur', 'Krankenpfleger'.

## `locationCodes` (type: `array`):

Filter by country or region. Lowercase ISO2 country codes ('be', 'de', 'fr', 'nl', 'es', 'it', 'pl'...) or NUTS1/NUTS2 region codes ('be2' = Flanders, 'de21' = Upper Bavaria). Leave empty to search all 30+ EURES countries.

## `publicationPeriod` (type: `string`):

Only return vacancies published within this period. Leave empty for all.

## `fetchDetails` (type: `boolean`):

Enrich each job with city, postal code, apply URL, source feed, and application deadline from the detail API. Costs one extra request per job: 100 jobs is quick, but 5,000 jobs means 5,000 extra requests and a noticeably longer run. Leave off for fast keyword searches.

## `maxResults` (type: `integer`):

Maximum number of vacancies to return. The EURES API caps any single query at 10,000 results; narrow with locationCodes or publicationPeriod to go deeper.

## `proxyConfiguration` (type: `object`):

Proxy settings. The EURES API is public and open, so Apify datacenter proxies work well.

## Actor input object example

```json
{
  "searchQuery": "software engineer",
  "fetchDetails": false,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "software engineer",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/eures-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "software engineer",
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/eures-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "software engineer",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/eures-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/eures-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/t1viCfc9exJG6Tswf/builds/hd3pVxQSaknf0y5In/openapi.json
