BYTETOOLS

OpenHolidays API

Free European holidays API with no key: public and school holidays for 25+ countries including regional variations, in multiple languages. Tested example.

No API key requiredHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-19

What is the OpenHolidays API?

OpenHolidays is a free, key-free API providing public holidays and school holidays for more than 25 European countries, including regional subdivisions and localised holiday names in several languages.

OpenHolidays covers something most holiday APIs miss entirely: school holidays. That is a genuinely different dataset from public holidays and matters for travel, childcare, staffing and demand forecasting.

Regional handling is thorough. Many European countries set school holidays at state or province level, and the API models that properly with a `subdivisions` field rather than flattening everything to a national calendar.

Quick facts

Base URL
https://openholidaysapi.org
Authentication
No API key required.
Rate limit
No published limit; fair use expected.
Pricing
Free open data.
CORS
Not enabled — call it from your server
Official docs
Read the docs

How to use the OpenHolidays API

Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.

1. Public holidays for a country and year

GET https://openholidaysapi.org/PublicHolidays?countryIsoCode=DE&languageIsoCode=EN&validFrom=2026-01-01&validTo=2026-12-31

curl
curl 'https://openholidaysapi.org/PublicHolidays?countryIsoCode=DE&languageIsoCode=EN&validFrom=2026-01-01&validTo=2026-12-31'
JavaScript (fetch)
const res = await fetch("https://openholidaysapi.org/PublicHolidays?countryIsoCode=DE&languageIsoCode=EN&validFrom=2026-01-01&validTo=2026-12-31");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://openholidaysapi.org/PublicHolidays?countryIsoCode=DE&languageIsoCode=EN&validFrom=2026-01-01&validTo=2026-12-31", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
[
  {
    "id": "9ac6fd8b-aec4-41f0-916b-f03af58ecdab",
    "startDate": "2026-01-01",
    "endDate": "2026-01-01",
    "type": "Public",
    "name": [
      {
        "language": "EN",
        "text": "New Year's Day"
      }
    ],
    "regionalScope": "Regional",
    "temporalScope": "FullDay",
    "nationwide": true
  },
  {
    "id": "7f99caaa-1eb2-4564-a6e8-13844634c929",
    "startDate": "2026-01-06",
    "endDate": "2026-01-06",
    "type": "Public",
    "name": [
      {
        "language": "EN",
        "text": "Epiphany"
      }
    ],
    "regionalScope": "Regional",
    "temporalScope": "FullDay",
    "nationwide": false,
    "subdivisions": [
      {
        "code": "DE-ST",
        "shortName": "ST"
      },
      {
        "code": "DE-BW",
        "shortName": "BW"
      },
      {
        "code": "DE-BY",
        "shortName": "BY"
      }
    ]
  },
  {
    "id": "f66c8c81-2ea3-43b4-8398-f3dc4ef0f62a",
    "startDate": "2026-03-08",
    "endDate": "2026-03-08",
    "type": "Public",
    "name": [
      {
        "language": "EN",
        "text": "International Women's Day"
      }
    ],
    "regionalScope": "Regional",
    "temporalScope": "FullDay",
    "nationwide": false,
    "subdivisions": [
      {
        "code": "DE-BE",
        "shortName": "BE"
      },
      {
        "code": "DE-MV",
        "shortName": "MV"
      }
    ]
  },
  {
    "id": "f80fd9dc-41b4-4203-8fea-2cf36d365fbb",
    "startDate": "2026-04-03",
    "endDate": "2026-04-03",
    "type": "Public",
    "name": [
      {
        "language": "EN",
        "text": "Good Friday"

Parameters

ParameterTypeRequiredDescription
countryIsoCodestringRequiredISO 3166-1 alpha-2 country code. DE
languageIsoCodestringRequiredLanguage for holiday names. EN
validFrom / validTostringRequiredDate range as YYYY-MM-DD. 2026-01-01
subdivisionCodestringOptionalRestrict to a state or region. DE-BY

Response fields

idstring
Holiday UUID.
startDate / endDatestring
Holiday period — school holidays span multiple days.
typestring
Public or School.
namearray
Localised names, each with language and text.
regionalScopestring
National or Regional.
subdivisionsarray
Regions the holiday applies to when regionally scoped.

What you can build with the OpenHolidays API

  • Plan staffing and delivery schedules around school holidays
  • Forecast travel and retail demand across European markets
  • Build a multi-country office closure calendar
  • Show regional holiday differences within a country

Common errors and how to fix them

400

Missing a required parameter.

Fix: countryIsoCode, languageIsoCode, validFrom and validTo are all mandatory.

Empty array

No holidays in that window, or the country is not covered.

Fix: Coverage is European; check the /Countries endpoint for supported codes.

Name is an array, not a string

Names are localised per language.

Fix: Read name[0].text, or find the entry matching your requested language.

OpenHolidays API — frequently asked questions

Is OpenHolidays free?

Yes, completely free open data with no API key required.

Does it include school holidays?

Yes, and that is its main advantage over other holiday APIs. Set the type filter or read the `type` field to distinguish Public from School holidays.

Which countries are covered?

More than 25, focused on Europe including Germany, France, Italy, Spain, Poland and the Nordics. Use the /Countries endpoint for the current list.

How does it handle regional holidays?

Properly — the `regionalScope` field and `subdivisions` array identify holidays that apply only in particular states or provinces, which matters a great deal for German and Swiss school calendars.

Tools that pair with this API

OpenHolidays is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.