Indonesia Public Holidays API: National Holiday Integration for HR, Payroll, and Apps
Fetch national holidays, religious observances, and collective leave through a REST API based on SKB 3 Menteri. Count effective working days without yearly manual updates.

Every start of the year, HR teams and internal app developers run the same ritual: copy the list of tanggal merah (public holidays) from the news, type it into a spreadsheet or a database table, then pray nothing was mistyped. The problem: SKB 3 Menteri (the joint ministerial decree) can be issued late, cuti bersama (collective leave) can change, and one missed date is enough to break a payroll calculation or an SLA schedule.
The Indonesia Calendar API from API Indonesia solves this: a list of national holidays, religious observances, and collective leave sourced from SKB 3 Menteri, accessed over a REST API. No more manual updates every year.
Endpoints Used
Base URL: https://use.apiindonesia.id/api/v1/libur
| Method | Endpoint | Parameters | Description |
|---|---|---|---|
| GET | / |
tahun, bulan (two digits) |
List of holidays, filterable by year and month |
| GET | /upcoming |
no parameters | Up to 10 upcoming holidays from today |
| GET | /:id |
holiday ID | Details for one holiday, for example hol_2026_014 |
Important fields in the response: date, name, type (for example nasional), and is_joint_leave, which marks collective leave.
Sample Request and Response
Fetch every holiday in 2026:
curl "https://use.apiindonesia.id/api/v1/libur?tahun=2026" \
-H "x-api-key: aip_li...x"
Response:
{
"data": [
{
"id": "hol_2026_001",
"date": "2026-01-01",
"name": "Tahun Baru 2026 Masehi",
"type": "nasional",
"is_joint_leave": 0,
"source": "SKB 3 Menteri"
}
]
}
For a "next holiday" banner on the employee dashboard:
curl "https://use.apiindonesia.id/api/v1/libur/upcoming" \
-H "x-api-key: aip_li...x"
Integrating with HR/Payroll Systems
The most common case: counting effective working days in a month for salary proration, leave allowance, or ticket SLAs.
import requests
from datetime import date, timedelta
def working_days(api_key: str, year: int, month: int) -> int:
r = requests.get(
"https://use.apiindonesia.id/api/v1/libur",
params={"tahun": year, "bulan": f"{month:02d}"},
headers={"x-api-key": api_key},
)
r.raise_for_status()
holidays = {row["date"] for row in r.json()["data"]}
first = date(year, month, 1)
if month == 12:
nxt = date(year + 1, 1, 1)
else:
nxt = date(year, month + 1, 1)
count = 0
d = first
while d < nxt:
if d.weekday() < 5 and d.isoformat() not in holidays:
count += 1
d += timedelta(days=1)
return count
print(working_days("aip_live_xxx", 2026, 6))
A JavaScript version for a Node app:
async function isWorkingDay(dateStr) {
const url = `https://use.apiindonesia.id/api/v1/libur?tahun=${dateStr.slice(0, 4)}&bulan=${dateStr.slice(5, 7)}`;
const res = await fetch(url, {
headers: { "x-api-key": process.env.API_INDONESIA_KEY },
});
const { data } = await res.json();
const day = new Date(dateStr + "T00:00:00+07:00").getDay();
const isWeekend = day === 0 || day === 6;
const isHoliday = data.some((h) => h.date === dateStr);
return !isWeekend && !isHoliday;
}
Common Patterns
- Payroll: count effective working days to prorate the salary of employees who join or leave mid-month.
- HR-tech: validate leave requests, and reject dates that fall on a holiday or on collective leave.
- Logistics and SLAs: compute due dates while accounting for public holidays, instead of assuming a flat 30 days.
- Calendar apps: sync holidays to the user's calendar with a daily job that calls
/upcoming. If your app serves Muslim users, pair it with the Prayer Times API for 514 kabupaten/kota (regencies and cities) so worship reminders also respect religious observances.
Technical Notes
- Auth uses the
x-api-keyheader, the same as the other API Indonesia products. - Store the
sourcefrom the response in your logs for auditing; the source is SKB 3 Menteri. - Cache responses per year, holidays rarely change once the decree is issued. Still refresh periodically to catch revisions to collective leave.
- The
is_joint_leavefield is 1 for collective leave; some companies treat it differently from a pure national holiday.
FAQ
Does it cover collective leave? Yes, flagged through the is_joint_leave field.
Which years are supported? It follows the issuance of SKB 3 Menteri; the tahun filter covers whatever is in the dataset, for example 2026.
How much does it cost? There is no monthly free allowance. New accounts get a one-time 3,000 credit bonus (Rp3,000) after email verification, and a successful request costs 2 credits, which is plenty to build and test a daily sync.
Start Now
Read the parameter details on the Holiday API product page, get a free API key at dashboard.apiindonesia.id/register, and see the full reference at docs.apiindonesia.id.
