{"openapi":"3.0.3","info":{"title":"Business Days & Holiday API","version":"1.0.0","description":"Public holidays and business-day arithmetic for 200+ countries and territories, with regional coverage: state, province and canton level holidays for 20 countries via ISO 3166-2 subdivision codes. Calendars are precomputed for 2000 through 2060 from curated open data. Every country in GET /countries carries a coverage flag (full or partial) so you can tell where the national list is known to be incomplete.","contact":{"name":"Business Days & Holiday API"}},"servers":[{"url":"https://api.polystash.com"}],"paths":{"/countries":{"get":{"summary":"List supported countries","operationId":"listCountries","responses":{"200":{"description":"One entry per supported country or territory: code, name (currently equal to the code), regionCount (how many ISO 3166-2 subdivision codes that country accepts in the region query parameter; 0 means national holidays only) and coverage.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryIndexEntry"}},"example":[{"code":"DE","name":"DE","regionCount":16,"coverage":"full"},{"code":"IN","name":"IN","regionCount":35,"coverage":"partial"},{"code":"US","name":"US","regionCount":37,"coverage":"full"}]}}}}}},"/v1/holidays/{country}/{year}":{"get":{"summary":"Holidays for a country and year","operationId":"getHolidays","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string"},"example":"US"},{"name":"year","in":"path","required":true,"schema":{"type":"integer"},"example":2026},{"name":"region","in":"query","schema":{"type":"string"},"description":"ISO 3166-2 subdivision code, e.g. US-TX","example":"US-TX"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Comma-separated holiday types: public,bank,school,authorities,optional,observance. Matches any requested type (OR); whitespace is trimmed. Takes precedence over types when both are supplied.","example":"public,optional"},{"name":"types","in":"query","schema":{"type":"string"},"description":"Alias for type: comma-separated holiday types with OR semantics. Used only when type is absent."},{"name":"lang","in":"query","schema":{"type":"string"},"description":"Preferred name language (falls back to English)","example":"local"}],"responses":{"200":{"description":"Holiday list sorted by date"},"400":{"description":"Invalid parameters"},"404":{"description":"Unknown country or region"}}}},"/v1/holidays/{country}/{year}.ics":{"get":{"summary":"iCalendar holidays for a country and year","operationId":"getHolidayCalendarYear","description":"RFC 5545 VCALENDAR with one all-day VEVENT per holiday on its observed date. English SUMMARY, local name and types in DESCRIPTION, exclusive next-day DTEND, and UID <id>@polystash.com. Uses CRLF and UTF-8 lines folded at 75 octets.","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string"},"example":"DE"},{"name":"year","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9]{4}$"},"example":"2027"},{"name":"region","in":"query","schema":{"type":"string"},"description":"ISO 3166-2 subdivision code; includes nationwide holidays","example":"DE-BY"}],"responses":{"200":{"$ref":"#/components/responses/HolidayCalendar"},"400":{"description":"INVALID_YEAR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"$ref":"#/components/responses/UnknownCountryOrRegion"}}}},"/v1/holidays/{country}.ics":{"get":{"summary":"iCalendar holidays over a range of years","operationId":"getHolidayCalendarRange","description":"Same all-day VEVENT format as the year feed. Defaults to the current UTC year through current year + 2. The range is inclusive and may contain at most five years. Years absent from the country data contribute no events.","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string"},"example":"US"},{"name":"from","in":"query","schema":{"type":"string","pattern":"^[0-9]{4}$"},"description":"First year, inclusive; defaults to the current UTC year","example":"2027"},{"name":"to","in":"query","schema":{"type":"string","pattern":"^[0-9]{4}$"},"description":"Last year, inclusive; defaults to current UTC year + 2","example":"2029"},{"name":"region","in":"query","schema":{"type":"string"},"description":"ISO 3166-2 subdivision code; includes nationwide holidays","example":"US-TX"}],"responses":{"200":{"$ref":"#/components/responses/HolidayCalendar"},"400":{"description":"INVALID_YEAR, INVALID_RANGE (from > to), or RANGE_TOO_LARGE (more than five inclusive years)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"$ref":"#/components/responses/UnknownCountryOrRegion"}}}},"/v1/businessdays/sla":{"get":{"summary":"Calculate an SLA deadline in business days or working hours","operationId":"calculateSlaDeadline","description":"All arithmetic uses local wall-clock dates in start's fixed offset; no DST adjustment. Uses the country's weekend and country/region holidays. For days, first roll a non-business start to the next business day at dayStart, then advance offset business days, preserving time. For hours, snap to a working period and count only within [dayStart, dayEnd), carrying remainder forward; a deadline may equal dayEnd. Missing calendar years have no known holidays.","parameters":[{"name":"country","in":"query","required":true,"schema":{"type":"string"},"example":"DE"},{"name":"region","in":"query","schema":{"type":"string"},"example":"DE-BY"},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date-time"},"description":"ISO 8601 YYYY-MM-DDTHH:MM[:SS[.sss]] followed by Z or +/-HH:MM. Seconds are optional; up to three fractional digits. Encode a positive offset's + as %2B.","example":"2027-03-05T16:40:00+01:00"},{"name":"offset","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":9007199254740991},"description":"Positive safe integer in decimal digits. Deadlines beyond ISO year 9999 return INVALID_OFFSET.","example":2},{"name":"unit","in":"query","required":true,"schema":{"type":"string","enum":["days","hours"]},"example":"hours"},{"name":"dayStart","in":"query","schema":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]$","default":"09:00"},"description":"Opening time; must precede dayEnd"},{"name":"dayEnd","in":"query","schema":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]$","default":"17:00"},"description":"Exclusive closing time; overnight windows are not supported"}],"responses":{"200":{"description":"Deadline in the same fixed offset plus business-day and skip counters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlaDeadline"}}}},"400":{"description":"INVALID_START, INVALID_OFFSET, INVALID_UNIT, or INVALID_TIME","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"$ref":"#/components/responses/UnknownCountryOrRegion"}}}},"/v1/businessdays/add":{"get":{"summary":"Add N business days to a date","operationId":"addBusinessDays","parameters":[{"name":"country","in":"query","required":true,"schema":{"type":"string"},"example":"US"},{"name":"date","in":"query","required":true,"schema":{"type":"string","format":"date"},"example":"2026-07-02"},{"name":"days","in":"query","required":true,"schema":{"type":"integer"},"description":"Positive or negative, non-zero","example":10},{"name":"region","in":"query","schema":{"type":"string"},"example":"US-TX"}],"responses":{"200":{"description":"Resulting date plus skip breakdown: weekendDaysSkipped includes holidays falling on weekends; holidaysSkipped counts only holidays on otherwise working days."},"400":{"description":"Invalid parameters"},"404":{"description":"Unknown country or region"}}}},"/v1/businessdays/between":{"get":{"summary":"Count business days between two dates","operationId":"businessDaysBetween","parameters":[{"name":"country","in":"query","required":true,"schema":{"type":"string"},"example":"DE"},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date"},"example":"2026-12-20"},{"name":"end","in":"query","required":true,"schema":{"type":"string","format":"date"},"example":"2027-01-10"},{"name":"region","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Counts over [start, end): businessDays, weekendCount (including holidays falling on weekends), and holidayCount (holidays on otherwise working days). These counts sum to totalDays."},"400":{"description":"Invalid parameters"},"404":{"description":"Unknown country or region"}}}}},"components":{"schemas":{"CountryIndexEntry":{"type":"object","required":["code","name","regionCount","coverage"],"properties":{"code":{"type":"string","description":"ISO 3166-1 alpha-2 code","example":"US"},"name":{"type":"string","description":"Display name; currently equal to the code","example":"US"},"regionCount":{"type":"integer","minimum":0,"description":"Number of ISO 3166-2 subdivision codes accepted in the region query parameter for this country. 0 means the country has national holidays only.","example":37},"coverage":{"type":"string","enum":["full","partial"],"description":"full: the national holiday list is complete and reviewed for every generated year (2000-2060). partial: the national list is known to be incomplete, or lunar-calendar holidays are missing for some years. Check this before relying on a country for payroll or legal deadlines.","example":"full"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"SlaDeadline":{"type":"object","required":["country","start","offset","unit","deadline","businessDaysUsed","holidaysSkipped","weekendDaysSkipped","dayStart","dayEnd"],"properties":{"country":{"type":"string","example":"DE"},"region":{"type":"string","example":"DE-BY"},"start":{"type":"string","description":"Original start query value","example":"2027-03-05T16:40:00+01:00"},"offset":{"type":"integer","minimum":1},"unit":{"type":"string","enum":["days","hours"]},"deadline":{"type":"string","format":"date-time","example":"2027-03-08T10:40:00+01:00"},"businessDaysUsed":{"type":"integer","minimum":1,"description":"For days: offset, excluding any initial roll. For hours: distinct business dates on which working time was consumed."},"holidaysSkipped":{"type":"integer","minimum":0,"description":"Holidays on otherwise working days skipped, including during initial rolling. Holidays on weekends count only as weekends."},"weekendDaysSkipped":{"type":"integer","minimum":0,"description":"Weekend dates skipped, including holidays on weekends and initial rolling."},"dayStart":{"type":"string","example":"09:00"},"dayEnd":{"type":"string","example":"17:00"}}}},"responses":{"HolidayCalendar":{"description":"RFC 5545 calendar; Content-Type: text/calendar; charset=utf-8. PRODID: -//Polystash//Business Days API//EN","content":{"text/calendar":{"schema":{"type":"string"}}}},"UnknownCountryOrRegion":{"description":"COUNTRY_NOT_FOUND or REGION_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}