NewConnect Claude, Gemini, ChatGPT, and other AI agents to API Ninjas via our MCP server →

How to Get Public Holidays in Python

Holidays APIUpdated October 10, 2026
Create a free API key and it will be pre-filled into every code sample on this page. No credit card required.
Getting public holidays in Python takes one GET request to the Holidays API — a country code in, the year's holiday calendar out. This guide covers the request, filtering by holiday type, and the thing holiday data is usually for: knowing whether a given date is a business day.

Prerequisites

You need three things:

  • Python 3.8 or newer.
  • The requests library.
  • A free API Ninjas API key — issued instantly, no credit card. If you already have an account, it's on your profile page.
shell
pip install requests

Step 1: Fetch a year of holidays

The endpoint is /v2/holidays. It takes a country (two-letter ISO code) and an optional type filter; here, public_holiday for national days off. Without a year you get the current year, which works on the Free plan. Other years (2005 to 2039) need a premium plan:

holidays.py
import requests response = requests.get( 'https://api.api-ninjas.com/v2/holidays', params={'country': 'US', 'type': 'public_holiday'}, headers={'X-Api-Key': 'YOUR_API_KEY'}, timeout=10, ) response.raise_for_status() holidays = response.json() for h in holidays[:3]: print(f"{h['date']} {h['name']}")

The request on the wire and the start of the response:

api.api-ninjas.com
GET/v2/holidays?country=US&type=public_holiday
200 OKapplication/json
[ { "country": "United States", "iso": "US", "year": 2026, "date": "2026-01-01", "day": "Thursday", "name": "New Year's Day", "type": "PUBLIC_HOLIDAY" }, { "country": "United States", "iso": "US", "year": 2026, "date": "2026-01-19", "day": "Monday", "name": "Martin Luther King Jr. Day", "type": "PUBLIC_HOLIDAY" } ]

Each entry carries an ISO date, the weekday in day, the holiday name, the country name and its iso code, and a type that classifies it.

Step 2: Filter by holiday type

Not every calendar entry is a day off. The type field separates PUBLIC_HOLIDAY (a national day off) from regional days such as STATE_HOLIDAY and from OBSERVANCE and SEASON entries. Types come back in upper case, and the type filter accepts any case. This small client keeps the year and type optional:

holidays_client.py
import os from typing import Optional import requests API_URL = 'https://api.api-ninjas.com/v2/holidays' session = requests.Session() session.headers['X-Api-Key'] = os.environ.get('API_NINJAS_KEY', 'YOUR_API_KEY') def get_holidays(country: str, year: Optional[int] = None, kind: Optional[str] = None) -> list: """Return one country's holidays for a year (default: the current year), optionally only one type.""" params = {'country': country} if year is not None: params['year'] = year if kind: params['type'] = kind response = session.get(API_URL, params=params, timeout=10) response.raise_for_status() return response.json() for h in get_holidays('US', kind='public_holiday'): print(f"{h['date']} {h['day']:9} {h['name']}")

Step 3: Find upcoming holidays

Dates arrive as ISO strings, so date.fromisoformat() turns the list into something you can compare against today:

upcoming.py
from datetime import date today = date.today() holidays = get_holidays('US', kind='public_holiday') # the current year upcoming = [h for h in holidays if date.fromisoformat(h['date']) >= today] print('Next 5 public holidays:') for h in upcoming[:5]: print(f" {h['date']} {h['name']}")

Step 4: Build a business-day check

The most common production use of holiday data is one boolean: does this date count? Load the public holidays into a set once, and the check is two conditions:

business_day.py
from datetime import date YEAR = date.today().year PUBLIC_HOLIDAYS = { date.fromisoformat(h['date']) for h in get_holidays('US', YEAR, kind='public_holiday') } def is_business_day(d: date) -> bool: return d.weekday() < 5 and d not in PUBLIC_HOLIDAYS print(is_business_day(date(YEAR, 12, 25))) # False: Christmas Day print(is_business_day(date.today())) # True on a weekday that isn't a holiday

From here, “add three business days” is a small loop — walk forward one day at a time, counting only dates that pass is_business_day().

Step 5: Handle errors

Failures are the usual three. A 400 carries an error message that says what was wrong, such as an unknown country. Note the caching advice in the 429 branch: a country-year of holidays is a fixed list, so you should rarely request the same one twice:

errors.py
from requests.exceptions import HTTPError, RequestException try: holidays = get_holidays('US') except HTTPError as error: status = error.response.status_code if status == 400: # Unknown country or type, or a year your plan doesn't include print('Bad request:', error.response.json().get('error')) elif status == 401: print('Missing or invalid API key') elif status == 429: print('Rate limit exceeded — cache results, holidays rarely change') else: print(f'HTTP {status}: {error.response.text}') except RequestException as error: print(f'Network error: {error}')

Where to go from here

If business-day math is the end goal, the Working Days API computes it directly. The Country API pairs well when you need metadata about the countries whose calendars you're fetching. The complete script is below.

holidays.py

The complete script from this guide: country, optional year, and optional type filter from the command line.

Frequently asked questions

What countries does the API cover?

Over 230 countries and territories, from 2005 to 2039. Pass the two-letter ISO 3166-1 code (US, GB, DE, JP, and so on) as the country parameter; three-letter codes and exact English country names also work. An unknown country returns a 400 error.

How do I get only public holidays?

Pass type=public_holiday. PUBLIC_HOLIDAY entries are national days off, including national holidays with a religious origin, such as Good Friday in Germany. Other types cover regional holidays, observances, religious dates that are not national days off, and more.

What date format does the API return?

ISO 8601 (YYYY-MM-DD), plus a day field with the weekday name. Python parses the date directly with date.fromisoformat().

Can I query other years?

Yes. Pass year (2005 to 2039) to get that calendar year, including future ones, which is exactly what deadline and scheduling logic needs. On the Free plan, omit year or pass the current year; other years need a premium plan.

Should I call the API on every request?

No — fetch each country-year once and cache it. A year of holidays is a fixed list, so a dictionary in memory or one small database table is all you need.