Legal
Dokumentasi API
Terakhir diperbarui: 16 Agustus 2026
Kalau kamu ingin membangun halaman undangan sendiri — dengan desain, domain, dan kode kamu — tapi tetap memakai data yang sudah kamu isi di DenganRestu, halaman ini caranya. Daftar acara, hitung mundur, kisah, foto, sampai status RSVP bisa diambil dari satu alamat. Datanya tetap satu: yang kamu ubah di aplikasi langsung ikut berubah di halamanmu.
Menerbitkan kunci
Buka Undangan Digital → Akses API di aplikasi. Ada dua jenis kunci, dan bedanya penting:
- Kunci publik (
drpk_…) — boleh dipasang di halaman undanganmu. Siapa pun yang membuka halamanmu bisa membacanya, dan itu tidak apa-apa: ia hanya bisa membaca undangan dan mengirim RSVP, persis seperti tamu yang membuka halaman kami. - Kunci rahasia (
drsk_…) — untuk server sendiri. Ia membuka daftar tamu. Jangan pernah menaruhnya di kode yang dikirim ke peramban; kami akan menolaknya kalau terdeteksi dipakai dari sana.
Kunci ditampilkan sekali. Kami hanya menyimpan sidik jarinya, jadi kalau hilang, terbitkan yang baru lalu cabut yang lama. Maksimal 4 kunci publik dan 3 kunci rahasia aktif per akun — cukup untuk berganti kunci tanpa halamanmu mati di tengah pergantian.
Memakainya
Kunci dikirim lewat header, tidak pernah lewat alamat. Alamat tercatat di log dan ikut terkirim ke situs lain lewat header Referer; header tidak.
const r = await fetch(
"https://www.denganrestu.com/api/v1/undangan/SLUG-UNDANGANMU",
{ headers: { Authorization: "Bearer drpk_xxxxx" } }
);
const { ok, data } = await r.json();
console.log(data.mempelai.label, data.tanggalTampil, data.acara);SLUG-UNDANGANMU adalah bagian akhir link undanganmu — sama dengan yang ada di denganrestu.com/rsvp/….
Memeriksa kunci
Sebelum menulis kode lain, pastikan kuncimu terbaca: GET /api/v1/ping. Ia menjawab kelas dan izin kuncimu, dan tak menyentuh data apa pun.
Yang dikembalikan
GET /api/v1/undangan/<slug> mengembalikan isi undangan yang sudah terlihat oleh siapa pun yang membuka halaman undanganmu: nama mempelai, tanggal, rangkaian acara, kisah, blok keluarga, foto, video, status RSVP, dan apakah amplop digital menyala.
Yang tidak akan pernah keluar lewat kunci publik: nomor HP tamu, catatan internalmu di rangkaian acara, daftar tamu, catatan amplop, dan nomor rekening pencairan. Batasnya satu kalimat — kunci publik tak membuka apa pun yang belum terbuka di halaman undanganmu.
Daftar alamat
Semua diawali https://www.denganrestu.com/api/v1.
Kunci publik — boleh dipanggil dari halamanmu
GET /undangan/<slug>— isi undangan. Kunci opsional: kalau salah tempel, halamanmu tetap dapat data.GET /undangan/<slug>/ucapan— dinding Doa & Restu. Hanya ucapan yang sudah kamu setujui, dan hanya kalau dindingnya kamu nyalakan.GET /undangan/<slug>/meja?q=nama— Cari Mejamu. Minimal 4 huruf, maksimal 3 hasil; batas itu yang menahan orang memanen daftar tamumu.GET /undangan/<slug>/kiriman— ambilkirimanIdsebelum mengirim RSVP. Kunci wajib.POST /undangan/<slug>/rsvp— kirim jawaban tamu. Kunci wajib.GET /undangan/<slug>/tamu/<tamuSlug>— data tamu dari link personal (?tamu=), untuk menyapa namanya dan memuat jawaban sebelumnya. Nomor teleponnya sendiri tidak ikut.GET /undangan/<slug>/kanal— metode pembayaran yang aktif, batas nominal, dan kalimat pengungkapan biaya layanan. Hanya bila amplop digital kamu nyalakan.POST /undangan/<slug>/amplop— kirim amplop. PerlukirimanId, sama seperti RSVP.GET /ping— memeriksa kuncimu, tanpa menyentuh data.
Kunci rahasia — hanya dari server sendiri
GET /tamu?limit=&cursor=— daftar tamu lengkap. Pakaiberikutnyadari respons sebagaicursorberikutnya;nullberarti habis.GET /acara?termasuk=catatan— rangkaian acara, TERMASUK yang kamu sembunyikan dari undangan. Catatan internalmu hanya ikut kalau kamu memintanya dengan?termasuk=catatan— bawaannya sengaja lebih ketat daripada ekspor, karena halaman yang kamu bangun cenderung merender apa pun yang datang. Gerbang yang sama berlaku saat MENULISNYA.POST /acara·PATCH /acara/<id>·DELETE /acara/<id>·POST /acara/<id>/utama— menambah, mengubah, menghapus acara, dan menandai Hari Utama. Butuh kunci ber-izin mengubah. Baca peringatannya di bawah sebelum memakaiDELETE.POST /tamu·PATCH /tamu/<id>·DELETE /tamu/<id>— menambah, mengubah, menghapus. Butuh kunci ber-izin mengubah (dicentang saat kunci diterbitkan); kunci biasa hanya membaca.GET /undangan·PATCH /undangan— membaca dan mengubah isi undangan itu sendiri: tampilan, kisah cinta, register keluarga, video, batas RSVP, dinding ucapan, template WhatsApp, dan info untuk tamu. Tanpa/<slug>— kuncimu sudah menentukan undangan mana.PATCHbutuh kunci ber-izin mengubah.GET /amplop?status=&cursor=&termasuk=pesan— buku amplop digital: siapa mengirim, berapa ditagih, berapa diterima. Pesan dari pengirim hanya ikut kalau kamu memintanya, seperti catatan acara.GET /amplop/saldo— berapa yang masuk, berapa yang sudah kamu minta cairkan, dan riwayat pencairannya. Untuk papan tampilan; beri jeda minimal 30 detik antar-panggilan.GET /ringkasan— angka saja (berapa hadir, berapa belum menjawab). Pakai ini untuk papan tampilan, jangan/tamu: mengambil seluruh daftar tiap menit berarti nomor telepon tamumu dikirim berulang-ulang ke tempat yang tak membutuhkannya.
Mengirim RSVP
Dua langkah, dan langkah pertama tidak bisa dilewati. Ambil kirimanId lebih dulu, lalu kirimkan bersama jawabannya:
const key = { Authorization: "Bearer drpk_xxxxx" };
const base = "https://www.denganrestu.com/api/v1/undangan/SLUG";
const { data } = await (await fetch(base + "/kiriman", { headers: key })).json();
await fetch(base + "/rsvp", {
method: "POST",
headers: { ...key, "Content-Type": "application/json" },
body: JSON.stringify({
kirimanId: data.kirimanId,
nama: "Ni Kadek Sari",
hadir: "ya", // "ya" | "mungkin" | "tidak"
dewasa: 2,
anak: 1,
ucapan: "Selamat berbahagia!",
}),
});Kenapa dua langkah. kirimanId kami yang menerbitkan dan kami yang tandatangani. Kalau tamu menekan kirim dua kali — hal yang biasa terjadi di venue dengan sinyal jelek — kiriman kedua memperbarui baris yang sama alih-alih membuat tamu ganda. Kunci buatanmu sendiri tidak bisa kami verifikasi, jadi header Idempotency-Key kami tolak: menerimanya justru akan menghasilkan baris ganda diam-diam.
Ambil kirimanId baru untuk setiap tamu. Memakai satu kirimanId untuk dua orang berbeda akan menimpa jawaban yang pertama.
Mengubah daftar tamu
PATCH hanya menyentuh field yang kamu KIRIM. Field yang tidak kamu sebut dibiarkan apa adanya — jadi kamu tak perlu mengirim seluruh data tamu hanya untuk mengubah satu hal, dan tak ada yang terhapus karena lupa disertakan. Untuk mengosongkan sebuah field, kirim null secara eksplisit.
// hanya rsvp yang berubah; nama, jumlah, kelompok tetap
await fetch(base + "/tamu/" + id, {
method: "PATCH",
headers: { ...key, "Content-Type": "application/json" },
body: JSON.stringify({ rsvp: "Hadir" }),
});
// kosongkan nomor meja
body: JSON.stringify({ meja: null })Untuk POST /tamu kamu BOLEH mengirim header Idempotency-Key berisi nilai apa pun yang kamu pilih — berguna saat mengimpor daftar panjang: kalau skripmu putus di tengah dan kamu ulang, baris yang sudah masuk tak akan terbuat dua kali. (Di jalur RSVP dan amplop, header itu justru kami tolak — di sana kuncinya harus kami yang terbitkan supaya bisa diverifikasi.)
Menghapus tamu juga menghapus nomor mejanya di denah dan penandaan acaranya. Tak ada konfirmasi di API — pemanggilnya skrip — jadi pastikan kamu benar-benar bermaksud menghapus.
Mengubah isi undangan
Aturannya sama dengan tamu: hanya field yang kamu kirim yang tersentuh. Yang tak kamu sebut dibiarkan apa adanya, dan null berarti kosongkan. Bedanya, di sini objek bersarang ikut di-merge sampai ke dalam — mengirim satu nama ayah tidak menghapus pihak mempelai yang lain.
const api = "https://www.denganrestu.com/api/v1/undangan";
const key = { Authorization: "Bearer drsk_…", "Content-Type": "application/json" };
// hanya nama ayah pihak pria; salam, kalimat pengundang,
// dan SELURUH pihak wanita tidak tersentuh
await fetch(api, {
method: "PATCH",
headers: key,
body: JSON.stringify({
keluarga: { groom: { father: "I Wayan Sudira" } },
}),
});
// beberapa bagian sekaligus
body: JSON.stringify({
tampilan: { warna: "batu-lumut" }, // gaya & struktur tak disebut → tak berubah
rsvp: { batas: "2026-08-20" },
infoTamu: { dressCode: "Kebaya / safari", parking: null },
})Responsnya membawa diubah — daftar field yang benar-benar kamu minta ubah, sampai ke tingkat terdalam (keluarga.groom.father, bukan keluarga) — beserta undangan versi terbarunya. Pakai diubah untuk memastikan yang berubah memang yang kamu maksud.
Undangan yang sudah kamu sebar berubah seketika. Tidak ada langkah konfirmasi di API — pemanggilnya skrip. Kalau kamu sedang menyusunnya lewat aplikasi juga, buka Undangan Digital: di sana ada keterangan kapan terakhir diubah lewat API, karena menekan simpan pada sebuah kartu akan menimpa perubahan API pada kartu itu.
Yang tidak bisa diubah dari API
Alamat undangan (slug), status terbit, foto, musik latar, dan sakelar amplop digital sengaja hanya bisa diubah dari aplikasi. Semuanya punya akibat yang harus terlihat sebelum ditekan: mengganti alamat mematikan setiap link personal tamu yang sudah tersebar, menutup undangan mematikan RSVP dan Cari Mejamu sekaligus, dan amplop menyangkut uang. Kalau kamu mengirimnya, kami menolak dengan pesan yang menyebut alasannya — bukan mengabaikannya diam-diam.
Kalau dua orang menulis bersamaan
Ambil versi dari respons GET, lalu sertakan di PATCH berikutnya. Kalau undangan sudah berubah sejak itu, kami menjawab 412 dan tak menulis apa pun — ambil ulang, gabungkan, kirim lagi. Ini opsional; tanpa versi tulisanmu tetap diterapkan di atas keadaan terbaru.
412 berarti jangan diulang begitu saja. 409 berarti sebaliknya: dua penulisan berpapasan dan kamu tak salah apa-apa — kirim ulang badan yang sama. Karena itu jangan menjalankan beberapa PATCH ke satu undangan secara bersamaan; jalankan berurutan.
Mengubah rangkaian acara
Aturan merge-nya sama: hanya field yang kamu kirim yang tersentuh. Ada empat hal yang khas di sini, dan semuanya punya alasan yang sama — acara bukan sekadar baris, ia menyetir apa yang dilihat tamu dan apa yang dihitung aplikasi.
const api = "https://www.denganrestu.com/api/v1/acara";
const key = { Authorization: "Bearer drsk_…", "Content-Type": "application/json" };
// MEMBUAT: tampilDiUndangan WAJIB disebut — tak ada bawaan
await fetch(api, {
method: "POST", headers: key,
body: JSON.stringify({
label: "Mebat", tampilDiUndangan: false, // prosesi internal, tamu tak melihat
tanggal: "2026-08-20", jam: "06:00", banjar: "Banjar Tegal",
}),
});
// MENGUBAH: hanya jam
await fetch(api + "/" + id, { method: "PATCH", headers: key,
body: JSON.stringify({ jam: "07:30" }) });
// HARI UTAMA: endpoint sendiri, badan kosong
await fetch(api + "/" + id + "/utama", { method: "POST", headers: key });tampilDiUndanganwajib saat membuat. Tidak ada bawaan, dan itu disengaja: acara yang lolos tanpa dipilih akan tampil ke setiap tamu lengkap dengan jam dan alamatnya, sekaligus menggeser rentang tanggal di kepala undangan. Rangkaian Acara memang tempat mencatat prosesi yang bukan untuk tamu umum.- Hari Utama punya URL-nya sendiri, bukan field
utama. Menandai satu acara wajib mencabut yang lain, dan ia menggeser tanggal pernikahan yang jadi patokan seluruh Checklist Timeline — jadi ia tak boleh ikut berpindah hanya karena kamu menggemakan dokumen yang baru saja kamu baca. Acara tanpa tanggal tetap boleh jadi Hari Utama; responsnya menyebutkan bahwa patokannya tidak digeser. tanggalmenerimaYYYY-MM-DDatau bentuk yang kami kembalikan (…T00:00:00.000Z), tidak yang lain. Tanggal yang tak ada seperti2026-02-30ditolak, bukan digeser diam-diam ke 2 Maret. Bentuk tanpa zona waktu juga ditolak — artinya berubah tergantung di mana skripmu berjalan.- Catatan internal digerbangi dua arah. Membacanya dan menulisnya sama-sama menuntut
?termasuk=catatan. Tanpa itu, catatanmu tidak ikut di respons dan tidak bisa diubah — tapi juga tidak terhapus.
Menghapus acara
Menghapus satu acara memusnahkan permanen denah kursi acara itu dan tanda “diundang ke acara ini” pada setiap tamu yang ditandai. Pos budget, rundown, tugas panitia, katering, dan pemuput tidakikut terhapus — semuanya jadi “Umum”.
Karena API tak punya dialog konfirmasi, penggantinya adalah pengakuan: permintaan pertama dijawab 409 beserta angka kerusakannya, dan kamu mengulanginya sambil menyebutkan angka itu. Angkanya harus yang terbaru — dihitung ulang tepat saat penghapusan, jadi pengakuan yang kamu tulis mati di skrip akan gagal justru ketika kerusakannya berubah.
// 1) ditolak, tapi kami sebutkan apa yang akan hilang
DELETE /acara/<id> → 409 { error: { kode: "akibat_belum_diakui", … } }
// 2) ulangi dengan angkanya (tambahkan &akuiUtama=1 bila ia Hari Utama)
DELETE /acara/<id>?akuiKursi=6&akuiTamu=42
→ 200 { dihapus: true, akibat: { kursi: 6, tamu: 42 },
dilepas: { budget: 3, rundown: 8, panitia: 2, katering: 1, pemuput: 1 } }Cocokkan acara lewat id, jangan lewat namanya. Skrip sinkron yang menghapus-lalu-membuat-ulang saat sebuah nama berubah akan memusnahkan denah dan penandaan tamunya setiap kali.
Perubahan label atau tanggal tidak menyusul ke berkas kalender yang sudah tersimpan di ponsel tamu, maupun ke kartu WhatsApp yang sudah ter-cache di percakapan mereka.
Amplop digital: membaca, bukan mencairkan
GET /amplop/saldo menjawab tiga angka yang berbeda, dan membedakannya penting:
masuk— total yang benar-benar tiba dari tamu.pencairanTerbuka— sudah kamu minta cairkan, belum kami transfer. Uangnya masih di kami.belumDiminta— sisa yang masih bisa kamu minta. Jangan menampilkannya sebagai “saldomu”. Karena permintaan pencairan selalu mengambil seluruh sisa, angka ini jatuh ke nol pada detik kamu menekan Minta Cairkan — padahal belum ada rupiah yang berpindah. TampilkanpencairanTerbukadi sebelahnya, atau jumlahkan keduanya.
Nomor rekening tidak pernah dikembalikan API — tidak utuh, tidak pula empat digit terakhirnya — dan begitu juga nama bank, nama pemilik rekening, serta bukti transfer. Cocokkan baris pencairan lewat tanggal dan nominalnya. Nomor lengkapmu ada di halaman Amplop Digital di aplikasi.
Meminta pencairan hanya bisa lewat dasbor, dan itu permanen — bukan “belum ada”. Menentukan ke rekening siapa uang keluarga dikirim adalah keputusan kepemilikan; kami sudah menolak memberikannya kepada kolaborator yang kamu percaya sendiri, dan kunci API hidup lebih lama daripada niat yang menerbitkannya. Pencairannya juga dieksekusi manusia, bukan mesin — jadi antrean permintaan programatik terhadapnya tak akan pernah kami buka.
Kalau ada yang salah
Setiap galat menjawab dengan bentuk yang sama, dan ok: false selalu ada di badan — jadi kamu bisa memeriksanya tanpa melihat kode status:
{ "ok": false, "error": { "kode": "kunci_tak_dikenal", "pesan": "…", "dok": "…" } }kunci_absen— headerAuthorizationbelum terpasang.kunci_tak_dikenal/kunci_dicabut— salah tempel, atau kunci itu sudah kamu cabut. Terbitkan yang baru.kunci_salah_kelas— kunci rahasia dipakai di alamat publik, atau sebaliknya.kunci_di_url— kunci dikirim lewat?key=. Pindahkan ke header.sk_di_peramban— kunci rahasia terdeteksi dipakai dari peramban. Pindahkan ke server, lalu cabut & terbitkan ulang.undangan_tak_ditemukan— slug tak dikenal, atau undangannya sedang tidak aktif.rsvp_tutup— batas waktu konfirmasi yang kamu setel sudah lewat. Halaman kami pun menolaknya.konflik_tulis— dipakai dua status yang obatnya berlawanan. 409: ada penulisan lain berpapasan dengan punyamu — kirim ulang badan yang sama. 412:versiyang kamu kirim sudah basi — ambil ulang denganGET, gabungkan, baru kirim lagi. Jangan menyamakan keduanya.akibat_belum_diakui— penghapusan yang akan memusnahkan sesuatu yang tak bisa dipulihkan. Badannya menyebut angkanya; ulangi dengan angka itu.terlalu_sering— kuota per jam habis. HeaderRetry-Aftermenyebut berapa detik lagi.
Batas yang perlu kamu tahu
- Undangan harus aktif. Alamat ini memakai gerbang yang sama dengan halaman undangan — selama linknya belum kamu aktifkan, API menjawab
undangan_tak_ditemukan. Kamu boleh mengaktifkan link tanpa membagikannya. - Mencabut kunci berlaku seketika, dan halaman yang memakainya langsung berhenti mendapat data sampai kamu memasang kunci baru. Cabut hanya kalau kamu memang siap memperbarui halamanmu.
- Kami belum menjanjikan versi selamanya. Alamatnya ber-
/v1, dan perubahan yang mematahkan akan masuk ke alamat versi berikutnya — tapi kami tak bisa menjanjikan lebih dari selama layanan ini ada, dan tak akan berpura-pura bisa.
Pertanyaan
Kirim lewat halaman kontak. Sebutkan slug undanganmu dan empat karakter terakhir kunci yang bermasalah — jangan pernah mengirimkan kuncinya sendiri, kepada kami maupun kepada siapa pun.