Dev.to WebDev 🛠 Dev 👁 0 📖 3 min read

Japanese holidays are harder than you think — so I built a free API for them (no key, CORS open)

If you have ever built an app for the Japanese market, you have probably hit this wall: "Is today a business day in Japan?" It sounds like a weekend check. It is not. Japan has: Holidays that move (the 2nd Monday of

If you have ever built an app for the Japanese market, you have probably hit this wall:

"Is today a business day in Japan?"

It sounds like a weekend check. It is not. Japan has:

  • Holidays that move (the 2nd Monday of January, the 3rd Monday of September…)
  • Equinox days decided by an astronomical formula
  • Substitute holidays — if a holiday falls on a Sunday, the next available weekday becomes a holiday too
  • Citizen's holidays — if a plain weekday gets sandwiched between two holidays, it becomes a holiday as well. This is how "Silver Week" happens: in September 2026, Respect for the Aged Day (Sep 21) and the Autumnal Equinox (Sep 23) turn Tuesday, Sep 22 into a holiday out of nowhere

And that is before you get to era names (wareki), where 2026 is "Reiwa 8", or converting kana text to romaji for search and forms.

I kept re-implementing this logic, so I turned it into one small API and made it free for everyone.

Japan Toolkit API

1. Holidays & business days

curl "https://m-japan-api.sannon2026.workers.dev/v1/is-business-day?date=2026-09-22"
{
  "date": "2026-09-22",
  "day_of_week": "Tuesday",
  "is_weekend": false,
  "is_holiday": true,
  "holiday": {
    "date": "2026-09-22",
    "name": "Citizen's Holiday",
    "name_ja": "国民の休日"
  },
  "is_business_day": false
}

A Tuesday that is not a business day — exactly the case a hard-coded list from the internet tends to get wrong a year later, because these dates are calculated, not just listed.

More endpoints:

# All holidays for a year (English + Japanese names)
GET /v1/holidays?year=2026

# When is the next day off?
GET /v1/holidays/next
# → 2026-11-23, Labor Thanksgiving Day (勤労感謝の日)

# How many business days in January 2026? → 20
GET /v1/business-days?from=2026-01-01&to=2026-01-31

Holiday rules are implemented for 2020–2030, including substitute and citizen's holidays and the equinox formula.

2. Era (wareki) conversion

const r = await fetch("https://m-japan-api.sannon2026.workers.dev/v1/era?date=2026-11-10");
console.log(await r.json());
// {
//   "era": "Reiwa", "era_ja": "令和", "year": 8,
//   "formatted": "Reiwa 8", "formatted_ja": "令和8年"
// }

It also works in reverse: GET /v1/era?era=Reiwa&year=8 → Gregorian year 2026. Useful for forms, invoices, and anything that has to interoperate with Japanese paperwork.

3. Kana → romaji (and back)

curl "https://m-japan-api.sannon2026.workers.dev/v1/convert?text=がっこう&to=romaji"
# → { "input": "がっこう", "to": "romaji", "result": "gakkou" }

to can be romaji, hiragana, or katakana. Sokuon (っ) doubling and digraphs (きゃ → kya) are handled.

4. Fake Japanese users for testing

Testing i18n with "John Smith" tells you nothing about how your UI handles real Japanese names. So:

curl "https://m-japan-api.sannon2026.workers.dev/v1/fake/users?count=1&seed=42"
{
  "users": [
    {
      "name": "佐藤 蓮",
      "name_kana": "さとう れん",
      "name_romaji": "Sato Ren",
      "email": "[email protected]",
      "prefecture": "静岡県",
      "city": "静岡市"
    }
  ]
}

Pass a seed and you get the same users every time — deterministic fixtures for tests and demos. All emails use example.com, and all users are fictional.

How it is built

The whole thing is a single-file Cloudflare Worker — no database, no dependencies. Holidays are computed from the official rules (fixed dates, happy-Monday rules, the equinox approximation, then substitute/citizen's holiday passes), which means it stays correct for future years instead of rotting like a static JSON list. The source is on GitHub under MIT if you want to self-host it or check the logic.

Try it / break it

I am a student programmer in Japan, and this is my first API aimed at developers outside Japan. If you build something with it, or find a date it gets wrong, I would genuinely love to hear about it — here in the comments, or on Bluesky: @reodesuxz.bsky.social.

What Japan-specific data would you want next — postal codes, prefecture data, train holidays calendars? Tell me and I will add it.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.