Cara Pakai API Hari Libur Nasional untuk Validasi Cuti Karyawan

Ditulis oleh Rifaldy Elninoru·Ditinjau oleh ·10 Oktober 2026·Diperbarui 9 Oktober 2026·Dasar API & Integrasi
Bagikan:

Kamu lagi membangun form pengajuan cuti di aplikasi HR, dan ada satu pertanyaan yang bikin perhitungannya meleset: kalau karyawan ambil cuti 1 sampai 3 Januari, berapa hari yang sebetulnya memotong saldo cutinya? 1 Januari itu Tahun Baru, harusnya tidak ikut dihitung. API hari libur nasional dari api.co.id menjawab ini lewat satu api call ke GET https://use.api.co.id/holidays/indonesia/check/range dengan header x-api-co-id, dan gratis. Kamu tinggal mengirim rentang tanggal cuti yang diajukan, sistem akan mengembalikan setiap libur dalam rentang itu beserta type-nya, lalu kamu menandai tanggal ber-type Public Holiday atau Joint Holiday (plus akhir pekan) sebagai hari yang tidak memotong saldo. Satu hal yang perlu kamu tahu dari awal: jangan memutuskannya lewat field is_holiday, karena field itu juga bernilai true untuk hari peringatan yang sebenarnya tetap hari kerja.

Yang akan kamu bangun dengan API hari libur nasional: validasi cuti

Hasil akhir yang kita tuju sederhana: form cuti yang menampilkan “cuti ini memotong N hari saldo”, dengan N yang sudah mengecualikan libur nasional, cuti bersama, dan akhir pekan, semuanya dari satu API gratis. Semua panggilan memakai base URL https://use.api.co.id/holidays/indonesia dan header x-api-co-id berisi API key kamu. Tiap panggilan membalas dalam bentuk yang sama, jadi kode pembaca respons yang kamu tulis sekali bisa kamu pakai ulang untuk endpoint mana pun di modul ini. Endpoint-endpoint di modul ini mengikuti pola REST API yang sama, jadi begitu kamu paham satu, yang lain terasa familiar.

Empat jenis libur dan mana yang memotong saldo cuti

Supaya perhitungannya benar, kamu harus tahu bahwa tidak semua yang disebut “libur” berarti hari bebas kerja. API ini membedakan empat type, dan hanya dua di antaranya yang membebaskan karyawan dari potongan saldo. Dasar penetapannya mengikuti SKB 3 Menteri tentang hari libur nasional dan cuti bersama yang terbit tiap tahun.

type Arti Memotong saldo cuti?
Public Holiday Hari Libur Nasional Tidak, ini hari bebas kerja
Joint Holiday Cuti Bersama Tidak, ini hari bebas kerja
National Holiday Hari Peringatan Nasional Ya, tetap hari kerja
Observance Hari Peringatan Ya, tetap hari kerja

Jadi keputusannya jatuh pada type: Public Holiday dan Joint Holiday membebaskan saldo, sedangkan National Holiday dan Observance tetap dihitung hari kerja meski muncul di kalender sebagai peringatan. Gambar di bawah memetakan keempatnya ke keputusan itu, sekaligus menandai kenapa flag is_holiday tidak bisa dipakai sebagai penentu.

Pemetaan empat jenis libur ke keputusan memotong saldo cuti atau tetap hari kerja

Siapkan API key gratis

Sebelum memanggil apa pun, kamu butuh API key. Kamu bisa daftar gratis lewat halaman API Kalender Indonesia, lalu menyalin API key dari dashboard. Key itulah yang kamu pasang di header x-api-co-id pada setiap panggilan, jadi simpan nilainya di tempat yang aman dan jangan menaruhnya di kode front-end. Modul libur ini gratis, jadi kamu tidak perlu mengisi saldo untuk mulai mencoba.

Ambil hari libur di rentang cuti dengan /check/range

Begitu kamu punya tanggal mulai dan selesai cuti dari form, kamu kirim keduanya ke /check/range sebagai start_date dan end_date (format YYYY-MM-DD), dengan rentang yang tidak boleh lebih dari satu tahun. Contoh untuk pengajuan Budi, cuti 1 sampai 3 Januari 2025:

curl -H "x-api-co-id: YOUR_API_KEY" \
  "https://use.api.co.id/holidays/indonesia/check/range?start_date=2025-01-01&end_date=2025-01-03"

Balasannya memuat data berisi setiap libur yang jatuh di dalam rentang itu. Untuk rentang Budi, hanya ada satu:

{
  "is_success": true,
  "message": "Success",
  "data": [
    {
      "id": 1,
      "date": "2025-01-01",
      "date_formatted": "1 Januari 2025",
      "day_of_week": "Rabu",
      "name": "Tahun Baru Masehi",
      "type": "Public Holiday",
      "year": 2025,
      "is_today": false,
      "is_upcoming": true,
      "days_until": 44,
      "is_holiday": true,
      "is_joint_holiday": false,
      "is_observance": false
    }
  ]
}

Field yang kamu butuhkan untuk perhitungan cuti ada dua: date dan type. Sisanya cukup kamu teruskan apa adanya untuk ditampilkan ke pengguna. Kalau kamu cuma ingin menyaring cuti bersama saja, kamu bisa menambahkan parameter type, tapi parameter itu cocok persis satu nilai, jadi untuk Public dan Joint sekaligus lebih mudah menyaringnya di sisi kode seperti di bawah.

Tentukan tanggal yang tidak memotong saldo

Di sini banyak yang keliru: gampang berasumsi kalau is_holiday true berarti libur kerja, padahal tidak selalu. Pada objek libur, is_holiday bernilai true untuk Public Holiday maupun National Holiday, padahal National Holiday tetap hari kerja. Di endpoint /check/date, is_holiday tingkat atas bahkan bernilai true begitu ada libur apa pun pada tanggal itu, termasuk Observance yang juga tetap hari kerja. Penentu yang bisa kamu percaya adalah type. Bentuk himpunan tanggal libur kerja dari type Public Holiday dan Joint Holiday, lalu pakai himpunan itu untuk menghitung potongan:

const liburKerja = new Set(["Public Holiday", "Joint Holiday"]);
const tanggalLibur = new Set(
  body.data
    .filter((h) => liburKerja.has(h.type))
    .map((h) => h.date)
);

function hitungHariDipotong(startDate, endDate, tanggalLibur) {
  let potong = 0;
  for (let d = new Date(startDate); d <= new Date(endDate); d.setDate(d.getDate() + 1)) {
    const hari = d.getDay();                 // 0 = Minggu, 6 = Sabtu
    const iso = d.toISOString().slice(0, 10);
    if (hari === 0 || hari === 6) continue;  // akhir pekan tidak memotong
    if (tanggalLibur.has(iso)) continue;     // libur kerja tidak memotong
    potong++;
  }
  return potong;
}

Yang perlu kamu perhatikan: akhir pekan dan libur kerja ditangani di dua baris continue yang terpisah, sehingga karyawan tidak kehilangan jatah cuti karena Sabtu, Minggu, atau tanggal merah yang kebetulan masuk rentang. Kalau zona waktu jadi isu di sisimu, ganti toISOString dengan format tanggal lokal supaya pergeseran hari tidak terjadi.

Contoh lengkap: hitung potongan cuti Budi 1-3 Januari 2025

Kita satukan semuanya dengan nilai yang sama dari awal. Budi mengajukan cuti 1 sampai 3 Januari 2025 (Rabu sampai Jumat), yang menurut kalender biasa terhitung tiga hari kerja. Setelah respons /check/range di atas kembali, kamu tinggal memanggil fungsinya:

const dipotong = hitungHariDipotong("2025-01-01", "2025-01-03", tanggalLibur);
// tanggalLibur = { "2025-01-01" }
// 1 Jan (Rabu)  -> ada di tanggalLibur, tidak memotong
// 2 Jan (Kamis) -> memotong
// 3 Jan (Jumat) -> memotong
console.log(dipotong); // 2

Hasilnya saldo yang dipotong jadi 2 hari, sedangkan kalender polos menghitung 3. Selisih satu hari itu datang dari 1 Januari yang bertype Public Holiday. Angka itu yang kamu tampilkan di form cuti sebagai "cuti ini memotong 2 hari saldo". Nama dan tanggal di sini adalah nilai contoh dari dokumentasi; di produksi pakai apa yang dikembalikan API untuk tahun yang berjalan.

Galat yang akan kamu temui

Kalau requestmu salah, API membalas dengan is_success bernilai false dan data bernilai null, beserta pesan yang persis seperti ini, jadi kamu bisa meneruskannya langsung ke pengguna tanpa menebak-nebak:

{ "is_success": false, "message": "date range cannot exceed 1 year", "data": null }

Pesan lain yang muncul dari /check/range: start_date and end_date are required, invalid start_date format: use YYYY-MM-DD, invalid end_date format: use YYYY-MM-DD, dan end_date must be after start_date kalau rentangnya terbalik. Semuanya datang dengan status 400. Kalau header x-api-co-id hilang atau salah, kamu dapat 401; kalau batas laju terlampaui, 429; dan untuk error di sisi server, 500. Saat salah satu dari ini muncul, tahan dulu pemrosesan saldo dan tampilkan pesannya, supaya form tidak mengurangi jatah cuti dari data yang gagal diambil.

Endpoint lain yang tersedia

Pekerjaan validasi cuti cukup dengan /check/range. Kalau kamu butuh yang lain di modul yang sama, ini ringkasannya:

Endpoint Kegunaan
GET / List libur dengan filter year, month, type, name, start_date/end_date, upcoming, page, size
GET /:id Satu libur berdasarkan id
GET /check/date Cek satu tanggal, mengembalikan is_weekend dan holidays[]
GET /next Libur terdekat berikutnya
GET /upcoming Daftar libur mendatang (limit default 10, maks 100)
GET /stats Statistik libur per tahun
GET /calendar Kalender libur per tahun atau bulan
GET /years Daftar tahun yang tersedia
GET /types Daftar jenis libur

Harga, batas laju, dan cakupan tahun sebelum produksi

Modul ini gratis. Yang perlu kamu jaga cuma batas lajunya: 1.000 request per jam dan 10.000 request per hari per API key, dan lewat batas itu kamu dapat 429. Datanya mencakup tahun 2022 sampai 2026. Daftar libur satu tahun jarang berubah, jadi cara aman untuk tetap jauh di bawah batas adalah menyimpan hasil /check/range per tahun di cache sisimu dan memanggil API hanya saat tahunnya belum ada. Rincian tiap endpoint bisa kamu cek di dokumentasi resmi holidays.

Langkah berikutnya

Begitu validasi cuti jalan, backend HR yang sama bisa kamu sambungkan ke sistem absensi karyawan, supaya pengajuan cuti dan catatan kehadiran memakai kalender libur yang konsisten. Kalau produkmu soal pengiriman, kamu bisa memadukan kalender ini dengan data wilayah Indonesia dan perhitungan estimasi pengiriman untuk membuat kalkulator tanggal kirim yang otomatis melompati libur nasional. Data Indonesia lain seperti API kode pos juga jalan di gateway yang sama dengan satu API key.

Pertanyaan yang sering muncul

Apakah day_of_week selalu berbahasa Indonesia?

Di setiap objek libur dalam data[] atau holidays[], day_of_week berbahasa Indonesia seperti "Rabu". Khusus di /check/date, day_of_week tingkat atas berbahasa Inggris seperti "Wednesday", jadi perhatikan kamu membaca yang mana saat menampilkannya.

Kalau cuma perlu mengecek satu tanggal, endpoint mana yang dipakai?

Pakai GET /check/date?date=YYYY-MM-DD. Ia mengembalikan is_weekend dan array holidays[] untuk tanggal itu. Untuk keputusan memotong saldo, periksa type di dalam holidays[]; flag is_holiday di tingkat atas tidak bisa dipakai sebagai penentu.

Ditulis oleh

Rifaldy Elninoru

Founder Api.co.id dan Principal Engineer di PT Akselerasi Platform Indonesia. Membangun platform API serbaguna untuk developer dan perusahaan di Indonesia, mulai dari OCR, data regional, sampai validasi rekening bank. Founding Engineer Lumen Trade di Gotrade (YC S19), merancang mesin trading futures real time berikut integrasi MT4, MT5, dan protokol FIX. Sebelumnya Backend Engineer di Bank Rakyat Indonesia menggarap sistem Ceria dengan Go dan Node.js, serta Web Developer di Direktorat Jenderal Pendidikan Tinggi Kemdikbudristek.

Lihat semua artikel →
Ditinjau oleh

Roni Eka SetiawanExpert Reviewer

CTO Api.co.id. Menangani arsitektur produk, infrastruktur, penetapan harga, dan pengalaman developer untuk API verifikasi identitas, OCR, data keuangan, logistik, geolokasi, data regional, dan AI. Sebelumnya tiga tahun sebagai Web Platform Engineer di Bank Rakyat Indonesia, membangun API pencairan dana real time dengan Go, PostgreSQL, dan Kafka, serta modul KYC, QRIS, dan alur persetujuan pelunasan. Pernah menangani deteksi fraud dan integrasi payment gateway di Airpaz, dan live streaming latensi rendah di Kompas Gramedia. Alumni Bangkit Academy jalur Cloud Computing.

Lihat konten yang ditinjau →
Scroll to Top