# EURES Jobs Scraper – 2M EU & Swiss Job Vacancies (`gazidev/eures-jobs`) Actor

Search ~2 million job vacancies from European public employment services on EURES (ELA), incl. 45,000+ Swiss jobs: keyword, country/NUTS region, ESCO occupation, contract type, date. Employer, salary, skills, apply link, only-new alerts. $0.80 per 1,000 jobs.

- **URL**: https://apify.com/gazidev/eures-jobs.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 job vacancies

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## EURES Jobs Scraper – 2M EU Job Vacancies, 30 Countries

Search **about 2 million job vacancies from 30 European countries** on **EURES**, the European Job Mobility Portal run by the European Labour Authority (ELA). EURES collects the vacancies of the national public employment services – Bundesagentur für Arbeit (Germany), France Travail, UWV / werk.nl (Netherlands), AMS (Austria), Arbetsförmedlingen (Sweden), and the services of the other EU/EEA countries and Switzerland. **One Actor replaces a separate scraper for each country.**

Filter by **keyword, country or NUTS region, ESCO occupation, working time, contract type, experience, education, required language, publication date** and the **EURES flag** (employers that want applicants from other EU countries). Each row has the job title, employer, employer website, country and region, dates, number of posts, contract type, ESCO occupation codes, description and the vacancy link. Turn on **full details** for salary, city and postal code, start date, application deadline, skills, languages, application instructions, the apply URL and the source employment service.

- **30 countries, one schema.** The same fields for every country.
- **ESCO occupations.** Type "truck driver" or "nurse" in English and get matching vacancies in every language, because EURES tags vacancies with ESCO codes.
- **Only-new alerts.** Schedule the Actor and get only vacancies you have not seen before. Seen vacancies are free.
- **$0.80 per 1,000 vacancies.** No browser, no proxy, no login.

### What can I use it for?

- **Recruiters and staffing agencies:** source vacancies and hiring employers across the EU, e.g. all care jobs in Austria with the EURES flag.
- **Job boards and aggregators:** feed fresh vacancies from 30 countries into your site by occupation or region.
- **Labour-market analysis:** count vacancies by country, NUTS region, ESCO occupation or contract type.
- **Relocation, visa and language-school services:** find employers that actively recruit abroad.

### Input

```json
{
  "keywords": ["software developer"],
  "keywordIn": "title",
  "countries": ["de", "nl", "fr10"],
  "occupations": ["nurse"],
  "publicationPeriod": "7d",
  "positionSchedule": ["fulltime"],
  "positionOffering": ["directhire"],
  "euresFlagOnly": false,
  "includeDetails": false,
  "maxItems": 500
}
```

| Field | What it does |
|---|---|
| `keywords` + `keywordIn` | Each keyword is one search, in the job title (default), everywhere, the description or the employer name. Vacancies are in the local language, so add local terms (e.g. "Softwareentwickler") for wider coverage |
| `countries` | ISO codes (`de`, `fr`, `nl`, `el` for Greece), country names, or NUTS-1/NUTS-2 region codes (`dea`, `fr10`, `nl32`). Empty = all countries |
| `occupations` | English occupation names resolved to ESCO, or ESCO occupation URIs |
| `publicationPeriod` | Last 24 hours, 3 days, week or month |
| `positionSchedule`, `positionOffering`, `requiredExperience`, `education`, `requiredLanguages` | EURES filters |
| `euresFlagOnly` | Only employers that want EU-mobile applicants |
| `includeDetails` + `maxDetailedItems` | Full vacancy record for the first N vacancies (one extra request each, ~10 s per vacancy) |
| `includeContacts` | Recruiter name, email and phone when published (needs `includeDetails`) |
| `onlyNew` + `stateKey` | Output only vacancies not returned in earlier runs |

#### Speed (10-second crawl delay)

EURES asks robots to wait 10 seconds between requests (`Crawl-delay: 10` in europa.eu/robots.txt), and this Actor follows that rule for every request. Each search request returns 50 vacancies, the largest page the API allows:

| Run | Requests | Time |
|---|---|---|
| 50 vacancies, search fields | 1 | ~5 s |
| 1,000 vacancies, search fields | 20 | ~3.5 min |
| 10,000 vacancies, search fields | 200 | ~35 min |
| 30 vacancies **with full details** | 1 + 30 | ~5 min |

Full details need one extra request per vacancy, so they are slow (about 10 s per vacancy). They are off by default and capped by `maxDetailedItems` (default 30, max 1,000). For large exports, keep details off. For daily alerts, use `publicationPeriod: "1d"` with `onlyNew`.

The EURES search shows at most 10,000 results per query. When a search has more and you want more, the Actor splits it by country and NUTS-2 region automatically.

### Output

```json
{
  "id": "MTc0MDE0MDggNDM",
  "title": "Pflegefachassistentin bzw. Pflegefachassistent für die Interne Station B",
  "employerName": "siehe Beschreibung",
  "country": "at",
  "nutsRegions": ["AT126"],
  "creationDate": "2026-10-27T21:45:04+00:00",
  "numberOfPosts": 1,
  "positionSchedule": ["parttime", "flextime", "fulltime"],
  "positionOffering": "contracttohire",
  "escoOccupationUris": ["http://data.europa.eu/esco/occupation/18e14e61-495b-44cc-a7c6-df4c625934ba"],
  "euresFlag": true,
  "languages": ["de"],
  "description": "Die NÖ Landesgesundheitsagentur ist das gemeinsame Dach für alle NÖ Klinikstandorte ...",
  "url": "https://europa.eu/eures/portal/jv-se/jv-details/MTc0MDE0MDggNDM?lang=en",
  "sourcePes": "PES Austria",
  "employerSize": "largeenterprise",
  "salaryMin": 3299.0,
  "salaryCurrency": "EUR",
  "salaryInterval": "month",
  "startDate": "2026-10-27T00:00:00+00:00",
  "applyInstructions": ["Schriftliche Bewerbung"],
  "source": "EURES - European Labour Authority (ELA)",
  "sourceUrl": "https://europa.eu/eures",
  "fetchedAt": "2026-10-29T07:59:21+00:00"
}
```

Fields from `sourcePes` onwards (plus `city`, `postalCode`, `applicationDeadline`, `requiredSkills`, `requiredLanguages`, `applyUrl`, `sectorCodes`, `employerSize` and more) come with `includeDetails`. The search result's description can be shortened for some countries; `includeDetails` gives the full text.

### Pricing

Pay per event: **$0.0008 per vacancy** ($0.80 per 1,000) + $0.0005 per vacancy for full details (optional) + $0.00005 per run. Duplicates and vacancies seen in earlier runs are free.

| Actor (Apify Store, Oct 2026) | Price per 1,000 jobs | Start fee |
|---|---|---|
| **EURES Jobs Scraper (this Actor)** | **$0.80** (+ $0.50 with full details) | $0.00005 |
| shahidirfan/eures-job-scraper | $0.99 | $0.0005 |
| dadhalfdev/eures-jobs-scraper | $2.00 | – |
| easyapi/eures-job-scraper | $3.00 | $0.09 |

### FAQ

**Where does the data come from?** From the public job search of the EURES portal (europa.eu/eures), which the European Labour Authority runs with the national public employment services. Only published vacancies are read; nothing behind a login. The Actor follows the europa.eu robots.txt, including its 10-second crawl delay: never more than one request every 10 seconds, and every request identifies the Actor.

**Can I re-use the data?** The EURES legal notice says: "Copyright © ... European Labour Authority (ELA). Re-use is authorised, provided that ELA is acknowledged as the source of the material." Every row therefore carries `source` and `sourceUrl`; keep that credit when you publish the data. Do not use the EURES/ELA logo. Individual vacancies stay the property of their employers.

**Is the UK included?** No. The UK left EURES in 2021. EU countries, Iceland, Liechtenstein, Norway and Switzerland are covered.

**Why are some titles in German or French?** Vacancies are published in the employer's language. Use ESCO `occupations` to search across languages.

**Personal data?** Recruiter contacts are only returned with `includeContacts: true`. You are responsible for a lawful GDPR basis when you process them.

### Use with AI agents / Apify MCP

Add the Actor to the Apify MCP server (`mcp.apify.com`) and ask: *"find nursing vacancies in Austria and the Netherlands published this week whose employers recruit from abroad"*.

### Related Actors

- [Arbeitsagentur Jobs](https://apify.com/gazidev/arbeitsagentur-jobs) – the German Federal Employment Agency job search.
- [Workable Jobs Scraper](https://apify.com/gazidev/workable-jobs), [Greenhouse Jobs](https://apify.com/gazidev/greenhouse-jobs), [Lever Jobs](https://apify.com/gazidev/lever-jobs) – company job boards.

***

Source: EURES, the European Job Mobility Portal – © European Labour Authority (ELA). This Actor is not affiliated with or endorsed by ELA or the European Commission.

# Actor input Schema

## `keywords` (type: `array`):

Job title, skill or employer words, e.g. "nurse", "software developer", "Krankenpfleger". Each keyword is a separate search. Vacancies are in the employer's language, so add local-language terms for better coverage. Leave empty to list all vacancies matching the filters.

## `keywordIn` (type: `string`):

Where the keyword must appear. 'Job title' gives the most precise results; 'Everywhere' matches any of the words anywhere in the vacancy (use with 'Best match' sorting).

## `countries` (type: `array`):

ISO country codes (de, fr, nl, at, se, es, it, pl, ... - Greece is el) or country names, or NUTS-1/NUTS-2 region codes (e.g. dea = Nordrhein-Westfalen, fr10 = Ile-de-France, nl32 = Noord-Holland). Empty = all 30 EURES countries.

## `occupations` (type: `array`):

Free-text occupation in English (e.g. "nurse", "truck driver") resolved to the best ESCO occupation, or ESCO occupation URIs (http://data.europa.eu/esco/occupation/...). Works across all languages because vacancies are tagged with ESCO codes.

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

Only vacancies published in this period.

## `positionSchedule` (type: `array`):

Full-time, part-time or flexible. Empty = any.

## `positionOffering` (type: `array`):

Empty = any.

## `requiredExperience` (type: `array`):

Empty = any. Most vacancies do not state experience, so this filter narrows results strongly.

## `education` (type: `array`):

Empty = any.

## `requiredLanguages` (type: `array`):

ISO language codes (e.g. en). Only vacancies that list this language as a requirement.

## `euresFlagOnly` (type: `boolean`):

Only vacancies where the employer explicitly wants applicants from other EU/EEA countries.

## `sortBy` (type: `string`):

Order of results.

## `includeDetails` (type: `boolean`):

SLOW: one extra request per vacancy, and EURES asks for 10 seconds between requests (robots.txt Crawl-delay), so details take about 10 s per vacancy (30 vacancies = 5 min). Adds full description, city and postal code, salary, start date, application deadline, required skills and languages, application instructions, apply URL and the source employment service. Charged as an extra 'job-details' event.

## `includeContacts` (type: `boolean`):

With full details: recruiter name, email and phone when the vacancy publishes them. Personal data - you are responsible for a lawful GDPR basis for processing it.

## `maxDetailedItems` (type: `integer`):

Only the first N vacancies get full details (about 10 s each); the rest are saved with the search fields only. Max 1,000 (about 3 hours).

## `maxItems` (type: `integer`):

Stop after this many vacancies. 0 = no limit. Speed: 50 vacancies per request, one request every 10 s (EURES crawl-delay) = about 300 vacancies per minute without details. Searches over 10,000 results are split by region automatically.

## `onlyNew` (type: `boolean`):

Remembers vacancies already returned (named key-value store 'eures-jobs-state') and outputs only new ones. Ideal for scheduled job alerts. Seen vacancies are free.

## `stateKey` (type: `string`):

Separate 'already seen' lists for different monitors.

## Actor input object example

```json
{
  "keywords": [
    "software developer"
  ],
  "keywordIn": "title",
  "countries": [
    "de",
    "nl"
  ],
  "publicationPeriod": "any",
  "euresFlagOnly": false,
  "sortBy": "newest",
  "includeDetails": false,
  "includeContacts": false,
  "maxDetailedItems": 30,
  "maxItems": 50,
  "onlyNew": false,
  "stateKey": "default"
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `employers` (type: `string`):

No description

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

No description

## `summary` (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 = {
    "keywords": [
        "software developer"
    ],
    "countries": [
        "de",
        "nl"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/eures-jobs").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 = {
    "keywords": ["software developer"],
    "countries": [
        "de",
        "nl",
    ],
    "maxItems": 50,
}

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

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "software developer"
  ],
  "countries": [
    "de",
    "nl"
  ],
  "maxItems": 50
}' |
apify call gazidev/eures-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/eures-jobs"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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