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.
Batasi IP (opsional). Di halaman Developer, tiap kunci punya tautan
Batasi IP: isi alamat server Anda atau rentang CIDR (103.10.20.30, 10.0.0.0/24,
IPv6 juga bisa). Setelah diisi, kunci hanya diterima dari alamat itu; dari tempat lain jawabannya
401 seperti kunci tak dikenali, dan halaman Developer mencatat IP yang ditolak terakhir
beserta tombol Izinkan IP ini. Kosongkan untuk kunci yang dipakai claude.ai atau ChatGPT
lewat MCP, karena alamat mereka berubah-ubah.
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. Punya beberapa nomor? Tambahkandari(digit nomor pengirim, sama seperti di/kirim), template dicari dan dibuat di nomor itu; tanpadaridipakai nomor pertama.
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, kunci dicabut, atau IP pemanggil di luar daftar Batasi IP).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.