Calendar — entry 017 of 17

UK Bank Holidays

Verified Jul 2026

The UK government publishes England & Wales, Scotland, and Northern Ireland bank holidays as a single static JSON file at gov.uk, listing each holiday's date, title, and whether it's a “substitute day” moved from a weekend. It's official, authoritative, and requires nothing beyond an HTTP GET — no key, no rate limit, and it's licensed under the Open Government Licence for reuse including commercially.

The UK government publishes bank holidays for England & Wales, Scotland, and Northern Ireland as static JSON, licensed under the Open Government Licence. A live GET this run returned all three divisions in one 22,207-byte response spanning 2019-01-01 through 2028-12-26 (83 England & Wales events, 94 Scotland, 103 Northern Ireland), and each division is also served on its own path -- a live `GET /bank-holidays/scotland.json` this run returned just that division's 94 events in 7,390 bytes. There's no per-year route, though: every response covers the full 2019-2028 span.

holidaysukgovernment-datakeylessopen-data
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreeNo paid tier — free for the documented use case.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score74out of 100
Authentication25/25No authentication required
Pricing20/20Free to use
Docs0/20No docs or spec available
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 74 on greatapis.com
<a href="https://greatapis.com/api/uk-bank-holidays/"><img src="https://greatapis.com/badge/uk-bank-holidays.svg" alt="Scored 74 on greatapis.com"></a>

Auth quickstart

  1. No API key, signup, or credit card required. A live GET this run confirmed both the combined file and each per-division path answer keyless with `access-control-allow-origin: *` and no rate-limit headers of any kind -- it's a static document served off gov.uk's CDN, reusable under the Open Government Licence including commercially.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Fetch all UK bank holidays (all three divisions)

GEThttps://www.gov.uk/bank-holidays.json

200 application/json; charset=utf-8

{"england-and-wales": {"division": "england-and-wales", "events": [{"title": "New Year’s Day", "date": "2019-01-01", "notes": "", "bunting": true}, {"title": "Boxing Day", "date": "2026-12-28", "notes": "Substitute day", "bunting": true}, {"...": "81 more events, same shape, spanning 2019-01-01 to 2028-12-26"}]}, "scotland": {"division": "scotland", "events": [{"...": "94 events total, same shape as england-and-wales"}]}, "northern-ireland": {"division": "northern-ireland", "events": [{"title": "Battle of the Boyne (Orangemen’s Day)", "date": "2026-07-13", "notes": "Substitute day", "bunting": false}, {"...": "102 more events total, same shape"}]}}

Try it

Developer reference

Base URLhttps://www.gov.uk
Key endpoints
  • GET/bank-holidays.json
  • GET/bank-holidays/{division}.json
  • GET/bank-holidays/scotland.json

Gotchas & limits

  • The two routes wrap their payload differently, so code can't share one parser: the combined file nests each division under its own top-level key (`{"england-and-wales": {"division": ..., "events": [...]}, "scotland": {...}, "northern-ireland": {...}}`), while a live `GET /bank-holidays/scotland.json` this run returned that division object unwrapped at the top level (`{"division": "scotland", "events": [...]}`). Either way there's no combined or deduplicated list, so a holiday observed in multiple nations (e.g. Christmas Day) appears once per division.
  • The per-division split is a path, not a query parameter, and picking the wrong idiom fails silently: a live GET this run against `/bank-holidays.json?division=scotland` returned HTTP 200 and valid JSON, but the identical full 22,207-byte all-three-divisions document rather than a filtered one -- nothing signals the parameter was ignored. The route that actually filters is `/bank-holidays/scotland.json` (7,390 bytes, 94 events). That path is exact: live probes this run got a 404 for `/bank-holidays/scotland` without the `.json` extension, and for `/bank-holidays/wales.json` -- only the three documented divisions exist.
  • "Substitute day" entries are real, distinct events with their own date, not annotations on the original holiday -- a live GET this run found Northern Ireland's Battle of the Boyne substitute landing on 2026-07-13 (`"notes":"Substitute day"`) as its own array entry, separate from the nominal 2026-07-12 date.
  • The dataset spans nearly a decade (2019-2028 in this run's response) rather than just the current year, so code that assumes "the next N entries are upcoming" must filter by today's date itself -- the API does no date filtering for you.