Panduan lengkap integrasi WhatsApp API dengan contoh kode PHP, JavaScript, Python. Kirim pesan, media, dan kelola kontak dengan mudah.
WAPRO adalah platform WhatsApp Gateway yang memungkinkan Anda mengirim dan menerima pesan WhatsApp secara terprogram melalui REST API. Sistem ini dirancang untuk:
Kirim pesan teks ke nomor WhatsApp apapun dengan format internasional
Dukungan image, video, document, dan audio dengan caption
Kirim pesan ke ribuan kontak sekaligus dengan delay antar pesan
Kelola kontak dengan grup, label, dan pencarian
Terima notifikasi real-time untuk pesan masuk dan status
Balas pesan otomatis berdasarkan keyword
Daftar gratis di halaman registrasi. Verifikasi email Anda untuk mengaktifkan akun.
Masuk ke dashboard, klik "Tambah Device", beri nama, lalu scan QR Code dengan WhatsApp Anda.
Buka menu API Keys, klik "Generate Key". Simpan key tersebut dengan aman.
Gunakan contoh kode di bawah untuk mengirim pesan tes:
curl -X POST https://wapro.dev/api/v1/messages/send \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to":"6281234567890","message":"Hello World!"}'Device adalah koneksi WhatsApp yang menghubungkan nomor WhatsApp Anda dengan sistem. Setiap akun dapat memiliki multiple device sesuai paket yang dipilih.
⚠️ Penting: WhatsApp di HP harus tetap aktif dan terhubung internet. Jika HP mati atau offline, device akan terputus.
Device aktif dan siap kirim pesan
Perlu scan QR untuk menghubungkan
Terputus, perlu reconnect
Sedang proses koneksi
https://wapro.dev/api/v1| Method | Endpoint | Deskripsi |
|---|---|---|
| POST | /api/v1/messages/send | Kirim pesan teks |
| POST | /api/v1/messages/send-media | Kirim media (image/video/doc/audio) |
| POST | /api/v1/messages/send-bulk | Kirim pesan massal via API Key (max 1000) |
| GET | /api/v1/messages | Riwayat pesan (paginated) |
| GET | /api/v1/messages/{id} | Detail pesan |
| GET | /api/v1/devices | Daftar device |
| GET | /api/v1/devices/{id}/status | Status detail device |
| GET | /api/v1/contacts | Daftar kontak |
| POST | /api/v1/contacts | Tambah kontak baru |
| GET | /api/v1/contacts/{id} | Detail kontak |
| PUT | /api/v1/contacts/{id} | Update kontak |
| DELETE | /api/v1/contacts/{id} | Hapus kontak |
| GET | /api/v1/quota | Cek kuota harian |
| GET | /api/v1/profile | Info akun lengkap |
Semua request API memerlukan autentikasi menggunakan API Key. API Key harus disertakan dalam header setiap request.
X-API-KEY: wag_live_xxxxxxxxxxxxxxxxxxxxx # atau Authorization: Bearer wag_live_xxxxxxxxxxxxxxxxxxxxx
⚠️ Penting: API Key hanya ditampilkan satu kali saat dibuat. Jika hilang, Anda harus membuat key baru. Jangan pernah membagikan API Key ke publik atau commit ke repository.
/messages/sendMengirim pesan teks ke nomor WhatsApp tujuan.
{
"to": "6281234567890",
"message": "Halo, ini pesan tes!",
"device_id": "uuid-device-opsional"
}| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | Yes | Nomor tujuan (format internasional tanpa +) |
| message | string | Yes | Isi pesan (max 4096 karakter) |
| device_id | uuid | No | Device ID, jika tidak diisi akan pakai device pertama yang connected |
{
"success": true,
"message": "Pesan berhasil dikirim.",
"data": {
"message_id": "uuid-xxx",
"to": "6281234567890",
"status": "sent",
"sent_at": "2026-03-25T16:00:00+07:00"
}
}/messagesMendapatkan riwayat pesan dengan pagination.
| Parameter | Type | Default | Description |
|---|---|---|---|
| device_id | uuid | - | Filter by device |
| direction | string | - | inbound/outbound |
| status | string | - | sent/delivered/failed |
| from | date | - | Filter tanggal mulai (YYYY-MM-DD) |
| to_date | date | - | Filter tanggal akhir (YYYY-MM-DD) |
| per_page | integer | 20 | Items per page (max 100) |
/messages/send-mediaMengirim media (gambar, video, dokumen, audio) dengan caption opsional. Gunakan multipart/form-data untuk upload file.
to=6281234567890 type=image file=[file upload] caption=Lihat gambar ini! device_id=uuid-device-opsional
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | Yes | Nomor tujuan |
| type | string | Yes | image/video/document/audio |
| file | file | * | Upload file (max 100MB). Wajib jika tidak menggunakan media_url. |
| media_url | url | * | URL media publik. Wajib jika tidak menggunakan file upload. |
| caption | string | No | Keterangan media (max 4096 chars) |
| device_id | uuid | No | Device ID |
image
JPG, PNG, GIF
video
MP4, MOV
document
PDF, DOC, XLS
audio
MP3, OGG, OPUS
⚠️ Perhatian: Broadcast hanya tersedia melalui Dashboard Web (login dengan akun). Fitur broadcast tidak tersedia di API publik v1. Gunakan endpoint /messages/send-bulk untuk mengirim pesan massal via API Key.
Fitur Broadcast memungkinkan Anda mengirim pesan ke banyak kontak sekaligus melalui dashboard. Proses pengiriman berjalan di background (queue) dengan delay antar pesan yang dapat dikonfigurasi.
{nama}, {nomor}, {email} untuk personalisasi)scheduledMenunggu diproses queue
runningSedang mengirim pesan
completedSelesai mengirim
failedGagal (device offline/dll)
draftDraft belum dikirim
cancelledDibatalkan
💡 Tips: Gunakan delay yang cukup (5–10 detik) untuk menghindari pembatasan rate limit dari WhatsApp. Untuk pengiriman via API, gunakan endpoint POST /api/v1/messages/send-bulk.
/contactsMendapatkan daftar kontak dengan pagination dan filter.
| Parameter | Description |
|---|---|
| search | Cari berdasarkan nama atau nomor telepon |
| group_id | Filter berdasarkan grup kontak |
| per_page | Jumlah per halaman (max 100) |
/contacts{
"name": "Budi Santoso",
"phone_number": "6281234567890",
"email": "budi@example.com",
"notes": "Pelanggan VIP",
"tags": ["vip", "jakarta"],
"group_id": "uuid-group-opsional"
}| Parameter | Type | Required |
|---|---|---|
| name | string | Yes |
| phone_number | string | Yes |
| string | No | |
| notes | string | No |
| tags | array | No |
| group_id | uuid | No |
/contacts/{id}Update data kontak. Semua field opsional, hanya field yang dikirim yang akan diupdate.
/contacts/{id}Hapus kontak dari sistem. Aksi ini tidak dapat dibatalkan.
Webhook memungkinkan sistem Anda menerima notifikasi real-time saat terjadi event tertentu seperti pesan masuk, pesan terkirim, atau perubahan status device.
message.receivedPesan masuk diterima
message.sentPesan berhasil terkirim
device.connectedDevice berhasil terhubung
device.disconnectedDevice terputus
{
"event": "message.received",
"device_id": "uuid-device",
"device_name": "HP Marketing",
"timestamp": "2026-03-25T16:00:00+07:00",
"data": {
"message_id": "uuid-msg",
"from": "6281234567890",
"to": "6289876543210",
"content": "Halo, ada yang bisa dibantu?",
"type": "text",
"timestamp": "2026-03-25T16:00:00+07:00"
}
}X-Webhook-Signature: sha256=xxxxxxxxxx X-Webhook-Event: message.received Content-Type: application/json
Untuk memastikan webhook berasal dari sistem kami, verifikasi signature menggunakan HMAC-SHA256:
// PHP
$payload = file_get_contents('php://input');
$signature = hash_hmac('sha256', $payload, $webhook_secret);
$expected = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
if (!hash_equals('sha256=' . $signature, $expected)) {
http_response_code(401);
exit('Invalid signature');
}⚠️ Penting: Endpoint webhook harus merespon dengan HTTP 200 dalam waktu 10 detik. Jika gagal, sistem akan mencoba retry maksimal 3 kali.
Fitur Auto Reply memungkinkan Anda membuat balasan otomatis berdasarkan keyword yang diterima. Cocok untuk customer service otomatis atau FAQ.
Cocok jika pesan mengandung keyword
Contoh: "harga" cocok dengan "info harga dong"
Cocok jika pesan persis sama dengan keyword
Contoh: "harga" hanya cocok dengan "harga"
Cocok jika pesan diawali keyword
Contoh: "order" cocok dengan "order 123"
💡 Tips: Gunakan keyword yang spesifik untuk menghindari balasan yang tidak relevan. Prioritas diberikan ke rule yang dibuat terakhir jika ada multiple matches.
| HTTP Code | Error | Penyebab | Solusi |
|---|---|---|---|
| 401 | Unauthorized | API Key tidak valid, dinonaktifkan, atau hilang | Periksa header X-API-KEY |
| 401 | API Key sudah kadaluarsa | Tanggal kadaluarsa API Key sudah terlewat | Buat API Key baru di menu API Keys |
| 403 | Forbidden | Fitur tidak tersedia di paket | Upgrade paket Anda |
| 403 | IP tidak diizinkan | API Key dibatasi ke daftar IP tertentu | Tambahkan IP server Anda ke IP Whitelist |
| 404 | Not Found | Device atau resource tidak ditemukan | Periksa ID device |
| 422 | Validation Error | Data tidak valid atau device offline | Periksa format data dan status device |
| 429 | Too Many Requests | Kuota pesan harian habis | Tunggu reset kuota atau upgrade paket |
| 502 | Bad Gateway | WA Engine tidak merespon | Coba lagi dalam beberapa saat |
{
"success": false,
"error": "Kuota pesan harian habis.",
"quota": {
"limit": 50,
"used": 50,
"remaining": 0
}
}⚠️ Rate Limiting: Selain kuota harian, API memiliki rate limit 60 request per menit. Jika terlampaui, Anda akan menerima response 429.
⚠️ Perhitungan kuota pada pengiriman massal:/messages/send-bulk dan broadcast memotong kuota harian per penerima, bukan per request. Permintaan dengan jumlah penerima melebihi sisa kuota akan ditolak dengan 429 sebelum satu pesan pun terkirim. Bila kuota habis di tengah proses, broadcast berhenti dan berstatus failed — penerima yang belum terkirim tetap berstatus pending. Cek sisa kuota lewat GET /api/v1/quota sebelum mengirim batch besar.
<?php
$apiKey = 'wag_live_xxxxx';
$baseUrl = 'https://wapro.dev/api/v1';
// Kirim pesan teks
$ch = curl_init($baseUrl . '/messages/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-KEY: ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'to' => '6281234567890',
'message' => 'Halo dari PHP!'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
if ($data['success']) {
echo "Pesan terkirim! ID: " . $data['data']['message_id'];
} else {
echo "Error: " . $data['error'];
}
curl_close($ch);use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
'X-API-KEY' => 'wag_live_xxxxx',
])->post('https://wapro.dev/api/v1/messages/send', [
'to' => '6281234567890',
'message' => 'Halo dari Laravel!',
]);
if ($response->json('success')) {
$messageId = $response->json('data.message_id');
// Pesan terkirim
}