The holiday moved and the JSON says so
The substitute field identifies an observed holiday that moved from its usual date, while regions tells you where it applies.
A calendar can get the holiday right and still get the day off wrong. In 2026, July 12 falls on a Sunday, so the Battle of the Boyne bank holiday in Northern Ireland is observed on Monday, July 13.
GET /holiday/GB/2026-07-13 includes this holiday record, with unrelated fields omitted:
{
"country": "GB",
"date": "2026-07-13",
"holiday": {
"date": "2026-07-13",
"name": "Battle of the Boyne (Orangemen's Day)",
"type": "public",
"regions": ["NIR"],
"substitute": true
}
}
The date is the observed day in the published calendar. substitute: true explains that it stands in for the holiday's usual date. Your application doesn't have to notice the Sunday and invent its own rule for moving it.
The other fields matter just as much. regions: ["NIR"] limits this entry to Northern Ireland. It isn't a day off across the whole UK. type: "public" distinguishes it from an observance that appears on a calendar without being a public holiday.
For a working-day calculation, combine the published date and relevant region with the weekend and working-hours rules for the calendar you're building. The observed holiday is already on the right date, so you don't need another weekend-shifting rule on top of it.