Public Holidays Scraper — Any Country, Any Year, Next Holidays
Pricing
from $0.35 / 1,000 result items
Public Holidays Scraper — Any Country, Any Year, Next Holidays
Public holidays for 204 countries: full year or multi-year calendars, upcoming holidays, is-today-a-holiday checks, long weekends with bridge days, school holidays (36 countries), regional filters. Local + English names, weekday, days-from-now. No API key.
Pricing
from $0.35 / 1,000 result items
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
Public holiday calendars for 204 countries as clean JSON: a full year or several years, the holidays coming up in the next N days, "is this date a holiday?" checks, long weekends with bridge days, regional (state-level) filtering, and school holidays for 36 countries. Local and English names, weekday, days-from-now and stable ids on every row. Built for scheduling agents, HR, logistics and market research. No API key, no proxy, no browser — data comes from the public Nager.Date and OpenHolidays APIs.
Use cases
- Delivery & SLA planning — skip non-working days when computing lead times or SLA deadlines per country (
mode: next,skipWeekendHolidays). - Scheduling agents — before booking a call or sending a campaign, ask
isHolidayfor the counterparty's country and get the next holiday too. - HR / payroll — annual calendars for every office country with state-level rules (
subdivision: "DE-BY",types: ["Public"]). - Travel & hospitality demand — long weekends and bridge days per country/year (
longWeekends), school holidays by German/Austrian/Swiss state (school). - Retail & ads calendars — multi-year, multi-country holiday lists to align promotions and budgets (
range,layout: perCountry). - Support staffing — one summary row per country with weekday-vs-weekend holiday counts and by-month distribution.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
countries | string[] | — (needed in every mode except nextWorldwide; Console prefill KZ, US, DE) | ISO 3166-1 alpha-2 codes; English names and aliases (Germany, UK, USA) also work, in any letter case. 204 codes in the Reference below. Optional for nextWorldwide (acts as a filter there). An unknown value is skipped and named in the status with a suggestion ("Germny" (did you mean DE?)); if none of the values can be read, the run stops with that message instead of returning every country. |
mode | enum | year | year, range, next, isHoliday, longWeekends, school, countryInfo, nextWorldwide — see table below. |
year | integer | current year (no stored default: an empty field always means the year of the run) | For year, longWeekends, countryInfo. Nager.Date supports roughly 1975–2100, varies by country (KZ starts later; an unsupported year is reported in SUMMARY.errors). |
yearFrom / yearTo | integer | year, else current year / yearFrom | Year span for range (max 10 years per run). |
startDate / endDate | YYYY-MM-DD | — | Inclusive date window. Post-filter in every calendar mode; in range/school also decides which years to fetch. |
nextDays | integer 1–730 | 365 | Horizon for next. |
date | YYYY-MM-DD | today | Day to check in isHoliday. |
utcOffsetHours | integer −12…14 | 0 | Which calendar date counts as "today" (5 = Kazakhstan, −5 = New York). Affects next, isHoliday, daysFromNow. |
types | string[] | all | Public, Bank, School, Authorities, Optional, Observance (Nager); BackToSchool, EndOfLessons (OpenHolidays school calendar). |
nationalOnly | boolean | false | Drop regional holidays (limited to certain states/counties). |
subdivision | string | — | ISO 3166-2 code (DE-BY, US-CA, ES-CT; prefix optional for single-country runs). Keeps nationwide + that region's holidays; long weekends then count that region's holidays too, and school calendars are read for it. |
skipWeekendHolidays | boolean | false | Keep only holidays that fall Mon–Fri (the ones that cost a working day). |
source | enum | auto | auto (Nager.Date, OpenHolidays fallback), nager, openholidays. school always uses OpenHolidays. |
language | ISO 639-1 | EN (when empty) | Name language for OpenHolidays requests (DE, FR, ES…). |
availableBridgeDays | integer 1–3 | 1 | longWeekends: vacation days an employee may spend on each side of a holiday to join it to a weekend. |
layout | enum | rows | rows = one row per holiday; perCountry = one row per country with counts + embedded holidays[]. |
dedupe | boolean | true | Drop repeated rows with the same country + states/regions (subdivisions) + start/end date + name. Rows for different states are never merged, so school holidays stay one row per state. |
fields | string[] | all columns | Keep only these columns, in this order; countryCode always comes first unless you list it elsewhere. Letter case is forgiven. Unknown names (with a suggestion) and columns of another mode are named in the status; a list with no column of this mode's rows stops the run and lists the valid ones. Columns per row type: Output below. |
maxItems | integer | 5000 | Cost cap. A country-year is ~10–20 rows. |
Original inputs countries, year, mode (year/next/longWeekends) keep their meaning. mode, source, layout and types are fixed lists: Apify refuses any other value before the run starts and shows the allowed ones (listed in this README).
Modes
mode | Rows | Source | Typical question |
|---|---|---|---|
year | holiday | Nager (OH fallback) | "All 2026 holidays in KZ, US, DE" |
range | holiday | Nager / OH | "Holidays 2026–2028" or "between 2026-11-01 and 2027-01-15" |
next | holiday | Nager / OH | "What is coming in the next 90 days?" |
isHoliday | dayCheck | Nager / OH | "Is 2026-10-25 a day off in Kazakhstan? When is the next one?" |
longWeekends | longWeekend | Nager (computed by the actor with subdivision or 2–3 bridge days, see FAQ) | "Long weekends in 2027 if I can take 2 bridge days" |
school | holiday (School, BackToSchool, EndOfLessons) | OpenHolidays (36 countries) | "Bavarian school holidays 2026/27" |
countryInfo | countryInfo | Nager | Names, region, borders, holidays per year |
nextWorldwide | holiday | Nager | "Every public holiday worldwide in the coming days" (Nager's global feed, ~1 week ahead) |
Reference
Countries (204, Nager.Date). † = also in OpenHolidays (school holidays, localized names, half-day flags)
| Code | Country | Code | Country | Code | Country | Code | Country |
|---|---|---|---|---|---|---|---|
AD † | Andorra | DM | Dominica | KY | Cayman Islands | RO † | Romania |
AG | Antigua and Barbuda | DO | Dominican Republic | KZ | Kazakhstan | RS † | Serbia |
AI | Anguilla | DZ | Algeria | LC | Saint Lucia | RU | Russia |
AL † | Albania | EC | Ecuador | LI † | Liechtenstein | RW | Rwanda |
AM | Armenia | EE † | Estonia | LR | Liberia | SB | Solomon Islands |
AO | Angola | EG | Egypt | LS | Lesotho | SC | Seychelles |
AR | Argentina | ER | Eritrea | LT † | Lithuania | SD | Sudan |
AT † | Austria | ES † | Spain | LU † | Luxembourg | SE † | Sweden |
AU | Australia | ET | Ethiopia | LV † | Latvia | SG | Singapore |
AW | Aruba | FI | Finland | LY | Libya | SH | Saint Helena, Ascension and Tristan da Cunha |
AX | Åland Islands | FK | Falkland Islands | MA | Morocco | SI † | Slovenia |
BA | Bosnia and Herzegovina | FM | Micronesia | MC † | Monaco | SJ | Svalbard and Jan Mayen |
BB | Barbados | FO | Faroe Islands | MD † | Moldova | SK † | Slovakia |
BD | Bangladesh | FR † | France | ME | Montenegro | SL | Sierra Leone |
BE † | Belgium | GA | Gabon | MF | Saint Martin | SM † | San Marino |
BF | Burkina Faso | GB | United Kingdom | MG | Madagascar | SN | Senegal |
BG † | Bulgaria | GD | Grenada | MH | Marshall Islands | SO | Somalia |
BH | Bahrain | GE | Georgia | MK | North Macedonia | SR | Suriname |
BI | Burundi | GF | French Guiana | ML | Mali | SS | South Sudan |
BJ | Benin | GG | Guernsey | MN | Mongolia | ST | São Tomé and Príncipe |
BL | Saint Barthélemy | GH | Ghana | MP | Northern Mariana Islands | SV | El Salvador |
BM | Bermuda | GI | Gibraltar | MQ | Martinique | SX | Sint Maarten |
BO | Bolivia | GL | Greenland | MR | Mauritania | SY | Syria |
BQ | Caribbean Netherlands | GM | Gambia | MS | Montserrat | SZ | Eswatini |
BR † | Brazil | GN | Guinea | MT † | Malta | TC | Turks and Caicos Islands |
BS | Bahamas | GP | Guadeloupe | MW | Malawi | TD | Chad |
BW | Botswana | GQ | Equatorial Guinea | MX † | Mexico | TG | Togo |
BY † | Belarus | GR | Greece | MZ | Mozambique | TK | Tokelau |
BZ | Belize | GT | Guatemala | NA | Namibia | TN | Tunisia |
CA | Canada | GW | Guinea-Bissau | NC | New Caledonia | TO | Tonga |
CC | Cocos (Keeling) Islands | GY | Guyana | NE | Niger | TR | Türkiye |
CD | DR Congo | HK | Hong Kong | NF | Norfolk Island | TT | Trinidad and Tobago |
CF | Central African Republic | HN | Honduras | NG | Nigeria | TV | Tuvalu |
CG | Congo | HR † | Croatia | NI | Nicaragua | TZ | Tanzania |
CH † | Switzerland | HT | Haiti | NL † | Netherlands | UA | Ukraine |
CI | Ivory Coast | HU † | Hungary | NO | Norway | UG | Uganda |
CK | Cook Islands | ID | Indonesia | NR | Nauru | US | United States |
CL | Chile | IE † | Ireland | NU | Niue | UY | Uruguay |
CM | Cameroon | IM | Isle of Man | NZ | New Zealand | VA † | Vatican City |
CN | China | IQ | Iraq | PA | Panama | VC | Saint Vincent and the Grenadines |
CO | Colombia | IS | Iceland | PE | Peru | VE | Venezuela |
CR | Costa Rica | IT † | Italy | PF | French Polynesia | VG | British Virgin Islands |
CU | Cuba | JE | Jersey | PG | Papua New Guinea | VI | United States Virgin Islands |
CV | Cape Verde | JM | Jamaica | PH | Philippines | VN | Vietnam |
CW | Curaçao | JP | Japan | PL † | Poland | VU | Vanuatu |
CX | Christmas Island | KE | Kenya | PM | Saint Pierre and Miquelon | WF | Wallis and Futuna |
CY | Cyprus | KH | Cambodia | PN | Pitcairn Islands | WS | Samoa |
CZ † | Czechia | KI | Kiribati | PR | Puerto Rico | YE | Yemen |
DE † | Germany | KM | Comoros | PT † | Portugal | ZA † | South Africa |
DJ | Djibouti | KN | Saint Kitts and Nevis | PW | Palau | ZM | Zambia |
DK | Denmark | KR | South Korea | PY | Paraguay | ZW | Zimbabwe |
Live lists: Nager.Date AvailableCountries, OpenHolidays Countries and Subdivisions (state codes for subdivision).
Holiday types
| Type | Meaning | Source |
|---|---|---|
Public | Official public holiday, day off | both |
Bank | Banks and offices closed | both |
School | Schools closed (Nager) / school vacation period (OpenHolidays, has endDate) | both |
Authorities | Government offices closed | Nager |
Optional | Most people take the day off | both |
Observance | Observed, not a day off | Nager |
BackToSchool / EndOfLessons | First / last school day | OpenHolidays (school) |
Most countries only carry Public; US, CA, GB, AU, DE, AT, CH and a few others also list Bank/School/Observance/Optional entries.
Subdivision codes (examples)
DE-BW DE-BY DE-BE DE-BB DE-HB DE-HH DE-HE DE-MV DE-NI DE-NW DE-RP DE-SL DE-SN DE-ST DE-SH DE-TH · US-CA US-NY US-TX … · AT-1…AT-9 · CH-ZH CH-BE … · ES-CT ES-MD … · KZ-75 (Almaty). Nager returns them in subdivisions; OpenHolidays lists them per country at /Subdivisions.
Examples
Annual calendar for all office countries, official days off only
{ "countries": ["KZ", "DE", "PL", "US"], "year": 2026, "types": ["Public"], "nationalOnly": true }
Upcoming non-working days for delivery planning (Kazakhstan time)
{ "countries": ["KZ", "RU", "UZ", "CN"], "mode": "next", "nextDays": 60, "skipWeekendHolidays": true, "utcOffsetHours": 5 }
Is it a holiday there? (scheduling agent)
{ "countries": ["DE", "GB", "US"], "mode": "isHoliday", "date": "2026-10-03", "subdivision": "DE-BY" }
Long weekends 2027 with up to 2 bridge days (travel offers)
{ "countries": ["DE", "AT", "CH", "NL"], "mode": "longWeekends", "year": 2027, "availableBridgeDays": 2 }
Bavarian school holidays for the 2026/27 school year, German names
{ "countries": ["DE"], "mode": "school", "subdivision": "DE-BY", "startDate": "2026-09-01", "endDate": "2027-08-31", "language": "DE" }
Three-year multi-country planning table, one row per country
{ "countries": ["FR", "IT", "ES", "PT"], "mode": "range", "yearFrom": 2026, "yearTo": 2028, "types": ["Public"], "layout": "perCountry" }
Output
Holiday row (modes year, range, next, school, nextWorldwide):
{"id": "DE:2026-01-06:epiphany","type": "holiday","countryCode": "DE","country": "Germany","date": "2026-01-06","endDate": "2026-01-06","name": "Epiphany","localName": "Heilige Drei Könige","year": 2026,"month": 1,"weekday": "Tuesday","isWeekend": false,"daysFromNow": -250,"holidayTypes": ["Public"],"national": false,"subdivisions": ["DE-BW", "DE-BY", "DE-ST"],"regionalScope": "Regional","temporalScope": null,"fixed": false,"launchYear": null,"source": "nager","sourceUrl": "https://date.nager.at/api/v3/PublicHolidays/2026/DE","fetchedAt": "2026-09-13T08:02:48.049Z"}
| Field | Description |
|---|---|
id | Stable CC:date:slug(name) — safe for diffing across runs; regional rows (school holidays, state holidays from OpenHolidays) can share an id across states, so key them by id + subdivisions |
type | holiday, dayCheck, longWeekend, countrySummary or countryInfo |
date / endDate | Same day for holidays; school vacations span several days |
name / localName | English (or language) name / name in the country's language |
weekday, isWeekend, daysFromNow | Computed vs. "today" in utcOffsetHours (negative = past) |
holidayTypes | See Holiday types |
national / subdivisions | Nationwide flag; ISO 3166-2 codes when regional |
regionalScope / temporalScope | National/Regional/Local; FullDay/HalfDay (OpenHolidays only) |
fixed, launchYear | Fixed calendar date; year the holiday was introduced (Nager only) |
source, sourceUrl, fetchedAt | Provenance |
Other row types:
dayCheck(isHoliday):date,weekday,isWeekend,isPublicHoliday,isHoliday,isWorkingDay,holidays[](name, localName, types, national, subdivisions),nextHoliday {date, name, localName, weekday, daysUntil, national}.longWeekend:startDate,endDate,startWeekday,endWeekday,dayCount,needBridgeDay,bridgeDays[],daysFromNow.countrySummary(layout: perCountry):years,total,publicHolidays,national,regional,onWeekdays,onWeekends,byMonth,byType,nextHoliday,holidays[].countryInfo:officialName,nativeName,region,borders[],borderNames[],publicHolidaysInYear(null when that year's calendar could not be read),openHolidaysCoverage.- Countries that fail (unsupported year, source cannot serve the country, API error) are not rows and are not charged: they are listed in
SUMMARY.errors({ country, error }, pluserrorCount) and in the run's status message. The run continues with the other countries and fails only when nothing at all could be fetched.
Columns per row type, in output order (for fields):
| Row type | Columns |
|---|---|
holiday | id, type, countryCode, country, date, endDate, name, localName, year, month, weekday, isWeekend, daysFromNow, holidayTypes, national, subdivisions, regionalScope, temporalScope, fixed, launchYear, source, sourceUrl, fetchedAt |
dayCheck | type, countryCode, country, date, weekday, isWeekend, isPublicHoliday, isHoliday, isWorkingDay, holidays, nextHoliday, source, fetchedAt |
longWeekend | id, type, countryCode, country, year, startDate, endDate, startWeekday, endWeekday, dayCount, needBridgeDay, bridgeDays, daysFromNow, source, sourceUrl, fetchedAt |
countrySummary | type, countryCode, country, years, from, to, total, publicHolidays, national, regional, onWeekdays, onWeekends, byMonth, byType, nextHoliday, holidays, source, fetchedAt |
countryInfo | type, countryCode, country, officialName, nativeName, region, borders, borderNames, year, publicHolidaysInYear, openHolidaysCoverage, source, sourceUrl, fetchedAt |
The dataset has a view per row type (Holidays, Is it a holiday?, Long weekends, Per country, Country info).
The run's status message says how many rows were saved and names failed, unknown and unfetched countries. The key-value store record SUMMARY holds mode, countries, unknown inputs with suggestions, how free-text countries were read, years, window, sources used, fields, item count (items, delivered), per-country errors and errorCount, countriesNotFetched, and stoppedBy (limit, timeout or null).
Use it from code / agents
curl -X POST "https://api.apify.com/v2/acts/yadroo~public-holidays/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"countries":["KZ","DE"],"mode":"next","nextDays":90,"skipWeekendHolidays":true}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/public-holidays').call({ countries: ['US'], mode: 'isHoliday', date: '2026-11-26', utcOffsetHours: -5 });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0].isWorkingDay, items[0].nextHoliday);
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("yadroo/public-holidays").call(run_input={"countries": ["DE", "AT", "CH"], "mode": "longWeekends", "year": 2027, "availableBridgeDays": 2})items = client.dataset(run["defaultDatasetId"]).list_items().items
MCP: connect https://mcp.apify.com and call the yadroo/public-holidays tool with the same JSON — the input schema is self-describing, so an agent can pick mode and filters on its own.
Pricing
Pay per event: $0.001 per run start + $0.0005 per dataset row. Store discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the row price; the start event is the same on every plan; platform usage is included. Typical runs: 3 countries × 1 year ≈ 45 rows ≈ $0.02; an isHoliday check for 10 countries = 10 rows ≈ $0.006; 4 countries × 3 years ≈ 180 rows ≈ $0.09 (or 4 rows with layout: perCountry). Failed countries produce no rows and cost nothing beyond the start.
Your maximum cost per run is respected: the run stores only the rows it pays for, then ends with the status "Stopped at your spending limit: N rows delivered". maxItems caps the rows as well.
Limits & FAQ
- Coverage. Nager.Date: 204 countries, English + local names, years roughly 1975–2100 (per-country; e.g. KZ starts in the 1990s — unsupported years are listed in
SUMMARY.errorswith the API message). OpenHolidays: 36 countries (see †), 2020–2030, names in every official language, half-day flags, school calendars. - Substitute days. Sources list the official holiday date; "Monday in lieu" days are included only where the source provides them (GB, AU, US mostly; KZ/RU government-decreed transfers are often missing). For payroll-grade accuracy verify against the local gazette.
- Rate limits and run length. Both APIs are free, CDN-cached and unauthenticated; the actor spaces requests ~120 ms apart and retries 429/5xx with backoff. One country-year takes about 0.2–0.4 s with its rows saved (measured 03.10.2026), so a few hundred country-years finish in one to two minutes and the widest run (204 countries × 10 years, with
maxItemsraised) in about 12 minutes, inside the default 15-minute timeout. A run that nears its timeout stops starting new countries, keeps every row already saved and ends with "Stopped before the run timeout: N rows saved". - Long weekends with a state or more bridge days. Nager.Date's long-weekend endpoint answers only the default question (1 bridge day, nationwide holidays): on 03.10.2026 it returned the same list for 1, 2 and 3 bridge days and for
DEvsDE-BY. So withsubdivisionor 2–3 bridge days the actor computes long weekends itself from the Nager.Date calendar, with Nager's rules and each country's weekend days (Friday–Saturday in Egypt or Bahrain, Sunday only in Mexico or the Philippines). For the default question the two give identical results on 16 countries × 2 years. Those rows carry the calendar's URL insourceUrl. - Freshness. Nager.Date responses are cached up to 7 days on their CDN; holidays announced at short notice may lag.
namevslocalNamewith OpenHolidays. The API returns only the requestedlanguage; ask forEN(default) to get English names, or setlanguageto the local code and both fields carry the local name.- Errors. Unknown country strings are skipped and named in the status with a suggestion; when none can be read the run stops with that message. Countries a source cannot serve are listed in
SUMMARY.errors(no row, not charged); the run fails only when no country produced data. - Restarts. If Apify migrates or restarts the run, rows already saved are not saved or charged again.
- Roadmap. Working-day counters between two dates, ICS export, holiday diffs between runs.
Made by Yadroo · Sibling actors: open-meteo-weather · osm-geocode · world-bank-indicators · fx-rates · ip-intel