Korean Holidays iCal (.ics) Feed API
by KunStudio · free to evaluate · no API key on origin

Korean Holidays iCal (.ics) Feed API

Letting users subscribe to Korean public holidays in Google Calendar, Apple Calendar or Outlook means serving an iCalendar (.ics) feed. The hard part isn't the file format — it's having correct holiday dates, including the substitute holidays (대체공휴일) that generic worldwide lists miss. This API supplies those dates; you wrap them in a few lines of VEVENT and serve the .ics.

There is no .ics endpoint here on purpose — an iCal feed is trivial to assemble once you have correct dates, and keeping it in your code lets you brand the calendar name, pick the timezone, and add your own reminders. The pattern: fetch /v1/holidays?year=YYYY (loop a few years so the subscription stays populated), then emit one all-day VEVENT per holiday inside a VCALENDAR wrapper. Because the dataset already includes substitute holidays flagged with substitute: true, your feed is correct on exactly the cases naive holiday calendars get wrong.

Endpoints

GET /v1/holidays?year=2026 All Korean public holidays for a year (incl. 대체공휴일) — the source rows you turn into VEVENTs. Loop a few years to populate a rolling subscription.
GET /v1/holidays/is?date=2026-09-25 Optional: check a single date when you only need one VEVENT or want to verify a feed entry.

Example request & response

# Fetch a year of holidays, then emit an .ics feed from the rows in your own code.
curl "https://korea-calendar-api.kunstudio.workers.dev/v1/holidays?year=2026"
// API response (excerpt)
{
  "year": 2026,
  "count": 19,
  "holidays": [
    { "date": "2026-09-25", "name": "추석", "name_en": "Chuseok (Korean Thanksgiving)", "substitute": false }
    // ... more
  ]
}

// Build one all-day VEVENT per holiday (JS). DTEND is the day AFTER (exclusive).
// function toICS(holidays) {
//   const lines = [
//     "BEGIN:VCALENDAR", "VERSION:2.0",
//     "PRODID:-//YourApp//Korea Holidays//EN", "CALSCALE:GREGORIAN",
//     "X-WR-CALNAME:Korean Public Holidays"
//   ];
//   for (const h of holidays) {
//     const start = h.date.replace(/-/g, "");                 // 20260925
//     const d = new Date(h.date + "T00:00:00Z");
//     d.setUTCDate(d.getUTCDate() + 1);
//     const end = d.toISOString().slice(0,10).replace(/-/g, ""); // next day
//     lines.push(
//       "BEGIN:VEVENT",
//       "UID:" + h.date + "-kr-holiday@yourapp",
//       "DTSTART;VALUE=DATE:" + start,
//       "DTEND;VALUE=DATE:" + end,
//       "SUMMARY:" + h.name + " (" + h.name_en + ")",
//       "TRANSP:TRANSPARENT",
//       "END:VEVENT"
//     );
//   }
//   lines.push("END:VCALENDAR");
//   return lines.join("\r\n");
// }
//
// Serve that string with Content-Type: text/calendar; charset=utf-8

No API key is needed on the origin to try this — it is rate-limited for fair evaluation. See the OpenAPI spec for the full schema.

Good to know

Related

Building a Korean fortune (사주/saju) app? Pair this with the KunStudio Saju API for a full four-pillars reading over REST.