holidays.rest Ruby SDK

Test Publish Codacy Badge Codacy Badge

Official Ruby SDK for the holidays.rest API.

Requirements

  • Ruby 3.2+
  • Zero runtime dependencies — uses only the standard library (net/http, json, uri)

Installation

gem install holidays-rest

Or in your Gemfile:

gem "holidays-rest"

Quick Start

require "holidays_rest"

client = HolidaysRest::Client.new(api_key: "YOUR_API_KEY")

holidays = client.holidays(country: "US", year: 2024)
holidays.each { |h| puts "#{h.date}#{h.name}" }

Get an API key at holidays.rest/dashboard.


API

HolidaysRest::Client.new

client = HolidaysRest::Client.new(
  api_key:      "YOUR_API_KEY",   # required
  open_timeout: 5,                # optional, default 5s
  read_timeout: 15,               # optional, default 15s
  base_url:     "https://..."     # optional, override for testing
)

client.holidays(...)Array<Holiday>

Parameter Type Required Description
country String yes ISO 3166 alpha-2 code (e.g. "US")
year `Integer \ String` yes
month `Integer \ String` no
day `Integer \ String` no
type `String \ Array` no
religion `Integer \ Array` no
region `String \ Array` no
lang `String \ Array` no
response String no "json" (default) \
# All US holidays in 2024
client.holidays(country: "US", year: 2024)

# National holidays only
client.holidays(country: "DE", year: 2024, type: "national")

# Multiple types
client.holidays(country: "TR", year: 2024, type: ["national", "religious"])

# Filter by month and day
client.holidays(country: "GB", year: 2024, month: 12, day: 25)

# Specific region
client.holidays(country: "US", year: 2024, region: "US-CA")

# Multiple regions
client.holidays(country: "US", year: 2024, region: ["US-CA", "US-NY"])

client.countriesArray<Country>

client.countries.each { |c| puts "#{c.alpha2}#{c.name}" }

client.country(country_code)Country

Returns country details including subdivision codes usable as region: filters.

us = client.country("US")
us.subdivisions.each { |s| puts "#{s.code}#{s.name}" }

client.languagesArray<Language>

client.languages.each { |l| puts "#{l.code}#{l.name}" }

Models

All responses are deserialized into immutable Data objects.

Holiday
  .country_code   # String   — ISO 3166 alpha-2, e.g. "DE"
  .country_name   # String   — e.g. "Germany"
  .date           # String   — ISO 8601, e.g. "2026-01-01"
  .name           # Hash     — language code => name, e.g. { "en" => "New Year's Day" }
  .is_national    # Boolean
  .is_religious   # Boolean
  .is_local       # Boolean
  .is_estimate    # Boolean
  .day            # HolidayDay
  .religion       # String   — e.g. "Christianity", or "" if not applicable
  .regions        # Array<String> — subdivision codes, e.g. ["BW", "BY"]

HolidayDay
  .actual         # String   — day of week the holiday actually falls on
  .observed       # String   — day of week the holiday is observed

Country         # .name, .alpha2, .subdivisions → Array<Subdivision>
Subdivision     # .code, .name
Language        # .code, .name

Error Handling

Non-2xx responses raise HolidaysRest::ApiError:

begin
  client.holidays(country: "US", year: 2024)
rescue HolidaysRest::ApiError => e
  puts e.status_code   # HTTP status code (Integer)
  puts e.message       # Error message (String)
  puts e.body          # Raw response body (String)
end
Status Meaning
400 Bad request
401 Invalid API key
404 Not found
500 Server error
503 Service unavailable

License

MIT