Mengirim WhatsApp dari aplikasi saya sendiri (API)
WACO menyediakan API sederhana supaya aplikasi Anda sendiri — sistem absensi, tagihan, antrean, PPDB — bisa mengirim WhatsApp lewat nomor resmi Anda. Dua endpoint, satu header autentikasi. Tidak perlu menyentuh dashboard Meta.
Autentikasi
Buat kunci API di halaman Developer. Kunci berbentuk
waco_… dan hanya tampil sekali — simpan baik-baik. Kirim di setiap permintaan:
Authorization: Bearer waco_KUNCI_ANDA
Base URL: https://waco.id. Kunci yang dicabut, atau tenant yang ditangguhkan
karena tagihan, langsung berhenti bekerja.
1. Lihat template yang siap dipakai
curl https://waco.id/api/v1/template \ -H "Authorization: Bearer waco_KUNCI_ANDA"
Jawaban berisi hanya template yang sudah disetujui Meta:
{
"template": [
{ "nama": "absensi_hadir", "bahasa": "id", "kategori": "UTILITY",
"isi": "Halo {{1}}, {{2}} hadir pukul {{3}}.",
"jumlah_nilai": 3, "tombol": [] }
]
}
jumlah_nilai memberi tahu berapa nilai yang harus Anda kirim untuk mengisi
{{1}}, {{2}}, dan seterusnya.
2. Kirim notifikasi
curl -X POST https://waco.id/api/v1/kirim \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nomor": "628123456789",
"nama": "Ibu Ani",
"template": "absensi_hadir",
"isi": ["Budi", "Budi", "07:15"]
}'
Medan: nomor (E.164 tanpa +, wajib), template (wajib),
isi (larik nilai variabel — jumlahnya harus sama dengan jumlah_nilai),
nama (opsional, untuk pengenalan kontak). Template berheader gambar
wajib membawa gambar_url (https publik, JPEG/PNG ≤5 MB) — Meta tidak menyimpan
gambar contoh, jadi tiap kiriman menyebut gambarnya lagi; template berheader PDF memakai
dokumen_url (+ dokumen_nama opsional). Jawaban sukses:
{ "status": "terkirim", "message_id": "wamid.HBg…", "percakapan_id": 81 }
message_id adalah wamid dari WhatsApp — simpan ini, karena
pesan_id pada webhook message.status memakai id yang
sama. Itulah cara melacak sent → delivered → read per pesan.
percakapan_id hanya muncul kalau nomor Anda punya kotak masuk; akun mode API
murni tidak mendapatkannya.
Contoh Node.js
const res = await fetch('https://waco.id/api/v1/kirim', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.WACO_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
nomor: '628123456789',
template: 'absensi_hadir',
isi: ['Budi', 'Budi', '07:15'],
}),
});
const data = await res.json();
Contoh PHP
$ch = curl_init('https://waco.id/api/v1/kirim');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WACO_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'nomor' => '628123456789',
'template' => 'absensi_hadir',
'isi' => ['Budi', 'Budi', '07:15'],
]),
]);
$data = json_decode(curl_exec($ch), true);
Membalas percakapan (tanpa template)
Kalau pelanggan baru saja mengirim pesan (dalam 24 jam terakhir), Anda bisa membalas teks bebas tanpa template — cocok untuk alur interaktif: terima balasan lewat webhook, lalu jawab lewat sini.
curl -X POST https://waco.id/api/v1/balas \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nomor": "628123456789",
"teks": "Baik Bu, pendaftaran atas nama Ananda sudah kami terima."
}'
Jawaban: { "status": "terkirim", "message_id": "wamid…" }. Batas teks 4096 karakter.
Hanya berlaku dalam jendela 24 jam. Di luar itu Meta menolak (kode 131047) dan
Anda harus memakai /api/v1/kirim dengan template. Kenapa begitu, ada di
panduan template.
Mengirim media (gambar, dokumen, video, audio)
Kirim file lewat URL publik — Meta yang mengunduhnya, jadi Anda tidak perlu mengunggah dulu. Cocok untuk hasil lab, invoice PDF, atau foto. Sama seperti balas, ini hanya dalam jendela 24 jam.
curl -X POST https://waco.id/api/v1/kirim-media \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nomor": "628123456789",
"tipe": "document",
"url": "https://app.anda.com/invoice/INV-001.pdf",
"filename": "Invoice-INV-001.pdf",
"caption": "Invoice pendaftaran"
}'
tipe: image, document, video, atau
audio. url wajib HTTPS dan dapat diakses publik. caption
opsional (tidak untuk audio); filename hanya untuk document. Batas ukuran mengikuti
WhatsApp (mis. dokumen 100 MB, gambar 5 MB).
Membuat template lewat API
Template juga bisa dibuat dari aplikasi Anda, tanpa membuka dashboard:
curl -X POST https://waco.id/api/v1/template \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nama": "konfirmasi_pesanan",
"kategori": "UTILITY",
"isi": "Halo {{1}}, pesanan {{2}} sudah kami terima.",
"contoh": ["Budi", "INV-123"]
}'
Jawaban sukses (201): { "id": "…", "status": "PENDING", … }.
Penting: sukses berarti diajukan, belum bisa dipakai. Setiap template
ditinjau Meta dulu — biasanya beberapa menit sampai beberapa jam, dan bisa ditolak. Pantau
statusnya sampai APPROVED:
curl "https://waco.id/api/v1/template?status=semua" \ -H "Authorization: Bearer waco_KUNCI_ANDA"
Dengan ?status=semua, tiap template membawa kolom status
(PENDING / APPROVED / REJECTED) dan
alasan_tolak bila ditolak. Setelah APPROVED, kirim lewat /kirim
seperti biasa.
Medan lain yang tersedia: bahasa (bawaan id), footer
(≤60 karakter), tombol (balasan cepat, maks 3), tombol_url
({"teks":"…","url":"https://…"}), dan untuk kategori AUTHENTICATION
objek otp — isi badannya disusun Meta, jangan menulis sendiri. Aturan yang paling
sering membuat pengajuan ditolak sudah kami periksa lebih dulu: jumlah contoh
wajib sama dengan banyaknya variabel di isi.
Menghapus: DELETE /api/v1/template/nama_template. Nama yang dihapus dikarantina
Meta 30 hari — tidak bisa langsung dipakai ulang.
Template bergambar (blast dengan media)
Pesan template bisa memuat gambar di atas teks (header gambar) — cocok untuk blast promo berposter atau pengingat dengan foto. Tiga jalan, semuanya sudah tersedia:
- Dashboard: halaman Template → unggah gambar di kolom header; halaman Blast → pilih template bertanda 🖼️ dan unggah gambarnya sekali untuk semua penerima.
- API pembuatan: tambahkan
gambar_urlpadaPOST /api/v1/template— WACO mengunduh gambarnya, mengunggah contoh ke Meta, dan mengajukan template berheader gambar. - API pengiriman: setelah APPROVED, kirim lewat
POST /api/v1/kirimdengangambar_urlgambar yang benar-benar mau ditampilkan (boleh berbeda dari contoh). Untuk blast massal bergambar dari API, pakaiPOST /api/v1/blastdengangambar_url— templatenya dibuat otomatis.
curl -X POST https://waco.id/api/v1/template \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nama": "promo_september",
"kategori": "MARKETING",
"isi": "Halo {{1}}, promo September sudah dibuka. Lihat posternya di atas ya!",
"contoh": ["Budi"],
"gambar_url": "https://cdn.tokoanda.id/poster-september.jpg"
}'
# setelah APPROVED:
curl -X POST https://waco.id/api/v1/kirim \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"nomor": "628123456789",
"template": "promo_september",
"isi": ["Budi"],
"gambar_url": "https://cdn.tokoanda.id/poster-september.jpg"
}'
Gambar harus JPEG/PNG ≤5 MB di URL https yang bisa diunduh publik. Pesan bebas bergambar
di dalam jendela 24 jam tetap lewat /api/v1/kirim-media dengan
caption; di luar jendela itu, satu-satunya jalan adalah template berheader gambar
seperti di atas. Header PDF dan video belum bisa dibuat lewat API — buat dari dashboard.
Memilih nomor pengirim (multi-cabang)
Punya lebih dari satu nomor (mis. tiap cabang klinik)? Tambahkan dari untuk memilih
nomor mana yang mengirim. Tanpa dari, dipakai nomor pertama Anda. Berlaku untuk
/kirim, /balas, dan /kirim-media:
curl -X POST https://waco.id/api/v1/kirim \
-H "Authorization: Bearer waco_KUNCI_ANDA" \
-H "Content-Type: application/json" \
-d '{
"dari": "628158825011",
"nomor": "628123456789",
"template": "absensi_hadir",
"isi": ["Budi", "Budi", "07:15"]
}'
dari dicocokkan dengan nomor tampilan cabang Anda. Kalau tidak cocok dengan nomor
mana pun, jawabannya 400 — jadi salah ketik nomor pengirim ketahuan, bukan diam-diam
terkirim dari cabang lain.
Kode kesalahan
401— Kunci API tidak dikenali (header salah, atau kunci dicabut).403— Layanan ditangguhkan (tagihan belum dibayar).429— Terlalu banyak permintaan (batas 120 kirim/menit per kunci). Coba lagi sebentar.400—nomor/templatekosong, nomor tidak valid, atau jumlahisitidak cocok dengan template.404— Template tidak ditemukan pada nomor Anda.409— WhatsApp belum tersambung, atau template belum disetujui Meta.502— Meta menolak pengiriman; alasannya ada di medandetail.
Untuk menerima balasan dan status pesan di aplikasi Anda, lihat Menerima balasan & status lewat webhook.