Schedule meetings and releases away from holidays in several countries

Request each country's holiday list for the year, collect the closed dates in one map, and read off the weekdays on which nobody is closed. The API has one holiday endpoint per country and year, so a team across four countries makes four requests and gets the clear days from one loop.

Ask when a country is next closed

GET /v1/calendars/holidays/{country}/next returns the first holiday on or after from_date. This request asks for Japan from 9 November 2026.

curl, the next holiday in Japan
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/calendars/holidays/JPN/next?from_date=2026-11-09"
Response
{
  "country": "JPN",
  "coverage": [
    {
      "scope": "national_public",
      "subdivision_codes": []
    }
  ],
  "holiday": {
    "date": "2026-11-23",
    "name": "Labor Thanksgiving Day",
    "holiday_key": "labor_thanksgiving_day",
    "local_name": "勤労感謝の日",
    "scope": "national_public",
    "subdivision_codes": []
  }
}

The holiday is Labor Thanksgiving Day on 23 November, with scope national_public. local_name carries the Japanese name and holiday_key is the stable key for the kind of day. For a single country this answers the planning question in one call. For several countries, ask each one and keep the earliest answer, or read the whole year as the next section does.

Find the clear days across countries in one pass

  1. Get an API key Get an API key at signup and keep it in NARWHAL_API_KEY.
  2. List the countries and the window The script uses USA, DEU, JPN and IDN, from 9 to 30 November, and looks for 3 clear business days in a row. Three days is an example, so use the length your release or maintenance window needs. Change the list and the dates for your own teams.
  3. Collect the closed dates One request per country returns the year's holidays. The script stores each date in a map from the date to the set of countries that are closed. A date shared by two countries holds both codes.
  4. Walk the weekdays and report The script lists the weekdays with at least one closure and then finds the first run of clear business days.
    Python, closed days and the first clear run
    import os
    from collections import defaultdict
    from datetime import date, timedelta
    import requests
    
    HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}
    COUNTRIES = ["USA", "DEU", "JPN", "IDN"]
    START, END, NEED = date(2026, 11, 9), date(2026, 11, 30), 3
    
    closed = defaultdict(set)  # date -> countries closed that day
    for country in COUNTRIES:
        r = requests.get(
            f"https://api.narwhalapi.com/v1/calendars/holidays/{country}/{START.year}",
            headers=HEADERS,
            timeout=10,
        )
        r.raise_for_status()
        for h in r.json()["holidays"]:
            closed[h["date"]].add(country)
    
    days, day = [], START
    while day <= END:
        if day.weekday() < 5:
            days.append((day, sorted(closed.get(day.isoformat(), []))))
        day += timedelta(1)
    
    for day, who in days:
        if who:
            print(day.strftime("%a %d %b"), "closed:", ", ".join(who))
    
    for i in range(len(days) - NEED + 1):
        if all(not who for _, who in days[i:i + NEED]):
            print(f"first {NEED} clear business days in a row start:", days[i][0].strftime("%a %d %b"))
            break
Output of the script
Wed 11 Nov closed: USA
Mon 23 Nov closed: JPN
Thu 26 Nov closed: USA
first 3 clear business days in a row start: Thu 12 Nov

Among the 16 weekdays between 9 and 30 November, 3 have a closure and 13 are clear in all four countries. The first run of 3 clear business days begins on Thursday 12 November. The script uses no scope filter, so Indonesia's collective leave days would count as closed. Add scope=national_public to that country's request to leave them out.

The closed days to keep out of the plan

DateCountryHoliday
Wed 11 NovUSAVeterans Day
Mon 23 NovJPNLabor Thanksgiving Day
Thu 26 NovUSAThanksgiving Day

A release set for Wednesday 11 November would meet a closed United States office. The two Thanksgiving days are different holidays in different countries, with the holiday_key values labor_thanksgiving_day and thanksgiving_day, and each closes only its own country. Matching on the key rather than the name keeps them apart.

To put the closed days in front of the people who schedule work, create a calendar feed with include_holidays true and include_releases false through POST /v1/calendars/subscriptions. The calendar subscriptions documentation describes the request. This page leaves it unrun because the call creates a feed.

What each scope covers in this comparison

CountryWhat the list holdsEffect on the schedule
USAThe federal_government scopeVeterans Day and Thanksgiving appear as closed
JPNThe national_public scopeLabor Thanksgiving Day appears as closed
DEUThe national_public scopeNo closure in this window
IDNnational_public and collective_leaveNo closure in this window

Read coverage in each response before you rely on a list. It names the scopes and the subdivisions the calendar covers, and the scopes differ by country. A country whose entries carry subdivision codes, such as the United Kingdom, needs one more check: keep an entry when its list is empty or holds the office's region.

Do weekend holidays matter for scheduling?

Not for the weekday walk. A holiday on a Saturday or Sunday is skipped because the script only looks at Monday to Friday. Some countries move the day to a weekday and mark the new entry observed, and that entry has a weekday date, so it appears as a closure.

What if my team works in a country with regional holidays?

Filter by subdivision_codes in your code, because the year endpoint has no region parameter. An empty list means the holiday is nationwide. For the United Kingdom each bank holiday appears once per group of nations, so one date can have several entries.

How many requests does a window across years need?

One request per country and year. A window that crosses 31 December needs the next year's list for each country as well, and a year with no published calendar returns a 404 with the code calendar_not_published. Plan for that response in a long-range schedule, and keep each year's list in a cache so repeated runs do not ask again.

Published .

Next steps