# EU Holidays Calendar (`vizellie/holidays-calendar-eu`) Actor

Public holidays for EU countries and Dutch school holidays by region. One row per holiday with the local and English name and whether it is a general day off. Optional .ics calendar file per country. $0.001 per holiday and $0.002 per calendar file.

- **URL**: https://apify.com/vizellie/holidays-calendar-eu.md
- **Developed by:** [Vi Zellie](https://apify.com/vizellie) (community)
- **Categories:** Business, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 holiday rows

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

## EU Holidays Calendar

Public holidays for EU countries plus the UK, Switzerland and Norway, and school holidays, in one dataset. Use it for payroll, rotas, bookings and shop calendars.

General information for planning. Confirm a day off before you lock payroll or a booking.

### Who it is for

HR and payroll teams, people who schedule shifts, booking desks, and shops that sell across the EU, the UK, Switzerland and Norway and need the next public holiday without copying it from a website.

### What you get

- One row per holiday. A single day has `date`, `startDate` and `endDate`. A school holiday that covers several days has `startDate` and `endDate`, and `date` is empty.
- The country, and the region or subdivision when the holiday is not nationwide.
- The local name and the English name, when the source has them.
- The type: `public`, `school`, `optional` or `bank`.
- Whether it is a national day off. A regional holiday, a half day, a school holiday and an optional day are not a national day off. In the Netherlands, Good Friday is an official public holiday and not a general day off. Liberation Day (5 May) is a national day off only in years divisible by 5. In Norway, 24 December (Julaften) stays a bank holiday and is not a national day off. The note on the row explains this.
- United Kingdom bank holidays as one row per division: `GB-ENG` for England and Wales, `GB-SCT` for Scotland and `GB-NIR` for Northern Ireland. Wales shares the England and Wales list, and the note on a `GB-ENG` row says so. `nationalDayOff` is true only when that date is a bank holiday in all three divisions. `UK` is accepted and stored as `GB`.
- Swiss public holidays that are not nationwide, with the canton code in `region`, for example `CH-ZH`. A district or municipality in the source is stored under its canton. `nationalDayOff` is true only when the source marks the holiday as nationwide. The English name for 1 August is Swiss National Day. The local name stays as the source gives it.
- Dutch school holidays for north (`noord`), middle (`midden`) and south (`zuid`). A holiday for the whole country has an empty region.
- School holidays for other countries when a list is published. German school holidays are one row per state code, such as `DE-BY`. Belgian school holidays are one row per community code: `BE-NL`, `BE-FR` or `BE-DE`. Switzerland and Norway are included only when a school holiday list is published for them.
- An optional `.ics` file per country in the key-value store. The output tab links those files. The run summary lists the keys, such as `ICS-NL`.
- A clear note in the run summary when a source does not respond. Rows from the source that did respond are still saved.

For Dutch school holidays, **Dates advisory** is true when the ministry publishes advice dates. A school may close on different days. Summer and Christmas dates are the fixed ones.

### Tutorial

1. Leave **Countries** as `NL`, or add the markets you plan for. Clear the list for the Netherlands, Belgium and Germany. Greece is `GR`. The UK is `GB` (`UK` is accepted). Switzerland is `CH`. Norway is `NO`. You can ask for up to 30 countries. An unsupported code is skipped. The summary gives the count and does not repeat the code.
2. Leave **Years** empty for this year, or set `2026` and `2027`. You can ask for up to 6 years.
3. Leave **Include school holidays** on. For the Netherlands, pick **Dutch school regions**, or leave all three selected.
4. Leave **Language** as `EN`. The row still keeps the local name. The calendar file uses the language you set for the event title.
5. Turn on **Save calendar files** if you want one `.ics` file per country.
6. Run the Actor. Open the Holidays view. The `OUTPUT` record says how many rows were saved, and lists the calendar keys when you asked for files.
7. Schedule it if you want a standing feed for the year ahead. Rows that were not saved are not charged.

### Example input

```json
{
  "countries": ["NL"],
  "years": ["2026"],
  "includeSchoolHolidays": true,
  "nlRegions": ["noord", "midden", "zuid"],
  "language": "EN",
  "saveIcs": true,
  "maxRows": 1000
}
```

### Example output

One public holiday:

```json
{
  "itemType": "holiday",
  "date": "2026-01-01",
  "startDate": "2026-01-01",
  "endDate": "2026-01-01",
  "country": "NL",
  "countryName": "Netherlands",
  "region": "",
  "nameLocal": "Nieuwjaarsdag",
  "nameEnglish": "New Year's Day",
  "nameChosen": "New Year's Day",
  "type": "public",
  "nationalDayOff": true,
  "note": "",
  "halfDay": false,
  "datesAdvisory": false,
  "source": "OpenHolidays API",
  "licence": "ODbL-1.0",
  "attribution": "Contains data from OpenHolidays API, made available under the Open Database License (ODbL) 1.0. A database derived from it must also be shared under the ODbL 1.0."
}
```

One Dutch school holiday:

```json
{
  "itemType": "holiday",
  "date": null,
  "startDate": "2026-10-10",
  "endDate": "2026-10-18",
  "country": "NL",
  "countryName": "Netherlands",
  "region": "noord",
  "nameLocal": "Herfstvakantie",
  "nameEnglish": "Autumn holiday",
  "type": "school",
  "nationalDayOff": false,
  "note": "",
  "datesAdvisory": true,
  "source": "Rijksoverheid",
  "licence": "CC0-1.0",
  "attribution": "Rijksoverheid, CC0 1.0."
}
```

A regional public holiday has the subdivision in `region`, for example `DE-BY` or `CH-ZH`, and `nationalDayOff` is false. A UK bank holiday uses `GB-ENG`, `GB-SCT` or `GB-NIR`.

### Pricing

You pay a small fee when the run starts, then a fee for each holiday row that is saved. A calendar file is a separate fee, and only when you turn **Save calendar files** on. The dataset itself is not charged again.

| What | Price |
|---|---|
| Run start | $0.00005 |
| Holiday row | $0.001 |
| Calendar file, one country | $0.002 |

Rows past **Max rows**, and rows a source did not return, are not charged. A calendar file that was not saved is not charged.

**Examples**

- Ten holiday rows: 10 × $0.001 = **$0.010**, plus the $0.00005 start fee.
- Three calendar files: 3 × $0.002 = **$0.006**, plus the start fee.
- A run that saves nothing: **$0.00005**.

A run for the Netherlands, Belgium and Germany, for one year, with school holidays, is usually a few hundred rows. At $0.001 a row, 200 rows are $0.200, plus the start fee. German school holidays are one row per state code, so that country adds more rows than a single national list.

Use **Max rows** and Apify's maximum cost per run to cap a single run. The pricing tab on the store is the price you are charged if it ever differs.

### Scheduling and integrations

Save a task and schedule it when you plan the next year. The dataset can go to Google Sheets, Slack, email, Make or Zapier, or you can read it from the Apify API. The calendar file can be imported into a calendar app. The rows are small enough to pass to an AI agent over MCP.

### Sources and licences

Public holidays are taken from the OpenHolidays API. That database is under the Open Database License (ODbL) 1.0. You may use it, including in a commercial product, if you keep the attribution on the row. If you publish a database derived from it, that database stays under the Open Database License (ODbL) 1.0.

Some public holiday rows come from Nager.Date, under the MIT licence. Copyright 2016 nager.at. The source column on each row says which.

United Kingdom bank holidays come from GOV.UK, under the Open Government Licence v3.0. The row source credits GOV.UK. England and Wales are `GB-ENG`. The note on those rows says that Wales shares the list. Scotland is `GB-SCT`. Northern Ireland is `GB-NIR`. A year that GOV.UK does not list yet is taken from Nager.Date. On that fallback list, St. Stephen's Day is stored as Boxing Day, and for Norway as Second Day of Christmas. Scotland's 2 January moves to the following Monday when it falls on a Saturday, and to the Tuesday when it falls on a Sunday. Other substitute days in a fallback year can still differ from the GOV.UK list.

Dutch school holidays come from the Dutch government (Rijksoverheid), under CC0 1.0. Attribution is not required. The row names the source anyway. School holidays for other countries, including Switzerland and Norway, come from the OpenHolidays API when it publishes them.

This Actor is not affiliated with those publishers.

### No personal data

This Actor does not collect personal data.

- It asks only for countries, years and a language. It does not request names, contact details or account numbers.
- Notes and comments that sometimes sit next to a holiday are not stored.
- Raw responses are not stored.
- Logs and error messages do not include personal data or the addresses that were called.

### FAQ

**Why does a school holiday have two dates?**
It runs from the start date through the end date, both inclusive. A one-day public holiday has the same start and end, and `date` is set.

**Why is a region filled in?**
Some public holidays apply only in part of a country. Dutch school holidays differ for north, middle and south. Swiss holidays are mostly cantonal, so the region is the canton code. UK bank holidays always name the division. A nationwide holiday outside the UK has an empty region. In the UK each division still has its own row, and `nationalDayOff` is true only when all three divisions share that date.

**What if a source is down?**
The run summary says which part failed. Rows from the part that responded are still saved. If a source fails and nothing could be saved, the run finishes with that note and no holiday rows are charged. An unsupported country code is skipped. The summary gives the count and does not repeat the code. If none of the codes are supported, the run finishes with a note and no holiday rows are charged.

**Are the Dutch autumn dates fixed?**
No. Autumn, spring and the extra May week are advice dates. `datesAdvisory` is true on those rows. Summer and Christmas are the compulsory dates.

**Is Good Friday a day off in the Netherlands?**
It is an official public holiday, and `nationalDayOff` is false. Most employees work unless a contract or collective agreement says otherwise. The note on the row says this.

**Is 5 May a day off in the Netherlands?**
Liberation Day is an official public holiday every year. `nationalDayOff` is true only in years divisible by 5, when many employers, including the government, give it as a paid day off. In other years it is false. The note on the row says which case applies.

**Where do the figures come from?**
See Sources and licences above. For a binding day off, use the official calendar for that country.

### Next additions

- More of the same kind.
- Broader coverage.
- Small follow-ups later.

### Feedback

Missing a country or a field? Open an issue on the Actor's Issues tab.

# Actor input Schema

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

Country codes for EU countries plus the UK, Switzerland and Norway, for example NL, BE, DE, GB, CH and NO. Leave empty for the Netherlands, Belgium and Germany. Greece is GR. EL is accepted as well. UK is stored as GB. At most 30.

## `years` (type: `array`):

Calendar years, for example 2026 and 2027. Leave empty for this year. From 2000 up to five years ahead, and at most 6 years.

## `includeSchoolHolidays` (type: `boolean`):

Also save school holidays. Dutch regions are north, middle and south. Other countries are included when a school holiday list is published for them.

## `nlRegions` (type: `array`):

Which Dutch school regions to keep. National Dutch school holidays are included with any choice. Leave empty for north, middle and south.

## `language` (type: `string`):

Language for the calendar title and the chosen-name column, for example EN, NL, DE or FR. English and the local name are always saved when the source has them.

## `saveIcs` (type: `boolean`):

Save one .ics file per country in the key-value store. The output tab links the files. Each file is charged once.

## `maxRows` (type: `integer`):

Most holiday rows saved in one run, from 1 to 5000. Default 2000. Rows past the cap are not charged.

## Actor input object example

```json
{
  "countries": [
    "NL",
    "BE",
    "DE"
  ],
  "years": [
    "2026",
    "2027"
  ],
  "includeSchoolHolidays": true,
  "nlRegions": [
    "noord",
    "midden",
    "zuid"
  ],
  "language": "EN",
  "saveIcs": false,
  "maxRows": 2000
}
```

# Actor output Schema

## `holidays` (type: `string`):

One row per holiday, with the date, country, region, names and type.

## `holidayDetails` (type: `string`):

The same rows, including the source, the licence and whether the dates are advice.

## `summary` (type: `string`):

The OUTPUT record in the default key-value store, including the calendar file keys.

## `calendars` (type: `string`):

One .ics file per country. Keys start with ICS-.

# 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 = {
    "countries": [
        "NL"
    ],
    "nlRegions": [
        "noord",
        "midden",
        "zuid"
    ],
    "language": "EN"
};

// Run the Actor and wait for it to finish
const run = await client.actor("vizellie/holidays-calendar-eu").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 = {
    "countries": ["NL"],
    "nlRegions": [
        "noord",
        "midden",
        "zuid",
    ],
    "language": "EN",
}

# Run the Actor and wait for it to finish
run = client.actor("vizellie/holidays-calendar-eu").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 '{
  "countries": [
    "NL"
  ],
  "nlRegions": [
    "noord",
    "midden",
    "zuid"
  ],
  "language": "EN"
}' |
apify call vizellie/holidays-calendar-eu --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vizellie/holidays-calendar-eu"
        }
    }
}
```

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/hnOx9oYmNEypwcAj1/builds/fQ77AwNJmmXPOn5r5/openapi.json
