WhutzUpp Gateway — Panduan Integrasi API
Base URL: https://whutzupp.web.id/api/v1
Dua Jenis Key
API Key
Format: 12 karakter uppercase alphanumeric. Contoh: ABC123DEF456
Pengenal akun Anda. Satu per akun. Tampil di Dashboard → API Key.
Number Key
Format: 10 karakter uppercase alphanumeric. Contoh: AB12CD34EF
Pengenal nomor WA yang dipakai untuk mengirim. Dibuat otomatis saat sesi WA berhasil terhubung. Tampil di Dashboard → API Key → tabel Number Key.
Setiap request kirim pesan wajib menyertakan keduanya.
Cara Mendapatkan Key
- Login Dashboard → API Key → salin API Key (12 karakter)
- Hubungkan nomor WA di Dashboard → Sesi → scan QR
- Setelah terhubung, Number Key (10 karakter) muncul otomatis di tabel Number Key
- Gunakan keduanya di setiap request kirim pesan
Autentikasi
Cara A — Header + Body (direkomendasikan)
X-API-Key: ABC123DEF456
X-Timestamp: 1720600000
{ "number_key": "AB12CD34EF", "phone_no": "628xxx", "message": "..." }
Cara B — Semua di Body
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "628xxx",
"message": "..."
}
X-Timestamp (Unix timestamp) opsional tapi direkomendasikan — request lebih dari ±5 menit dari waktu server akan ditolak.
Kirim Pesan
Teks — POST /api/v1/send_message
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "628123456789",
"message": "Halo!"
}
Field alternatif: to (alias phone_no), text (alias message).
Response sukses:
{ "success": true, "message": "Pesan terkirim", "data": { "message_id": 42, "msg_id": "3EB0..." } }
Gambar / Media — POST /api/v1/send_image_url
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "628123456789",
"url": "https://domain.com/foto.jpg",
"message": "Caption opsional"
}
Atau dengan field type eksplisit — POST /api/v1/message/send-media:
{
"number_key": "AB12CD34EF",
"to": "628123456789",
"type": "image",
"url": "https://domain.com/foto.jpg",
"caption": "Caption opsional"
}
type yang didukung: image, video, document.
Kirim Massal — POST /api/v1/message/send-bulk
Kirim teks yang sama ke banyak nomor (maks 100 per request). Diproses secara async.
{
"number_key": "AB12CD34EF",
"numbers": ["628111000001", "628111000002", "grp:E0B512E5"],
"text": "Promo spesial hari ini!",
"delay_ms": 1500
}
delay_ms — jeda antar kirim dalam milidetik (min 500, maks 5000, default 1000).
numbers menerima nomor biasa, JID grup (@g.us), maupun Group Token (grp:…) secara bersamaan.
Response:
{ "success": true, "data": { "queued": 3, "job_id": "bulk_2_1720600000" } }
Cek Nomor WhatsApp — POST /api/v1/validate_number
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "628123456789"
}
Response:
{ "status": 200, "message": "Valid WhatsApp Number" }
{ "status": 400, "message": "Not a WhatsApp Number" }
Hapus Pesan — POST /api/v1/message/delete
Hapus pesan yang sebelumnya dikirim bot (hanya fromMe: true). Bekerja di grup maupun chat pribadi.
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"to": "120363040000000001@g.us",
"msg_id": "3EB0ABCDEF1234567890"
}
to — JID tujuan yang sama dengan saat pesan dikirim (grup @g.us atau nomor @s.whatsapp.net).
msg_id — ID pesan, didapat dari field data.msg_id di response send_message.
Response sukses:
{ "success": true, "message": "Pesan berhasil dihapus", "data": { "msg_id": "3EB0..." } }
Contoh use case — bot kirim rekap, simpan msg_id, lalu hapus sebelum kirim rekap baru:
// 1. Kirim rekap dan simpan msg_id
$res = whutzupp('send_message', [
'number_key' => NUMBER_KEY,
'phone_no' => '120363040000000001@g.us',
'message' => "Rekap donasi per jam 09:00:\n- Total: Rp 500.000",
]);
$lastMsgId = $res['data']['msg_id'] ?? null;
// (simpan $lastMsgId ke DB / file untuk dipakai nanti)
// 2. Sebelum kirim rekap berikutnya, hapus yang lama
if ($lastMsgId) {
whutzupp('message/delete', [
'number_key' => NUMBER_KEY,
'to' => '120363040000000001@g.us',
'msg_id' => $lastMsgId,
]);
}
Cek Status Pesan — GET /api/v1/message/{id}/status
GET /api/v1/message/42/status
X-API-Key: ABC123DEF456
data.status: queued → sent → delivered → read | failed | deleted
Format Nomor Telepon
Semua format berikut diterima dan dikonversi otomatis:
| Input | Dikonversi ke |
|---|---|
08123456789 |
628123456789@s.whatsapp.net |
628123456789 |
628123456789@s.whatsapp.net |
+628123456789 |
628123456789@s.whatsapp.net |
628123456789@s.whatsapp.net |
tetap (tidak diubah) |
120363xxx@g.us |
tetap — JID grup |
grp:E0B512E5 |
JID grup dari Group Book — lihat bagian Group Token |
Manajemen Sesi
Endpoint sesi cukup api_key saja (tidak perlu number_key).
| Method | Endpoint | Keterangan |
|---|---|---|
GET |
/api/v1/session |
List semua sesi |
POST |
/api/v1/session |
Buat sesi baru |
GET |
/api/v1/session/{name}/qr |
Ambil QR code (base64) |
GET |
/api/v1/session/{name}/status |
Status koneksi sesi |
DELETE |
/api/v1/session/{name} |
Hapus sesi |
Buat sesi baru:
POST /api/v1/session
X-API-Key: ABC123DEF456
{ "session_name": "marketing" }
Setelah sesi dibuat, poll /session/marketing/qr setiap beberapa detik sampai QR tersedia lalu tampilkan ke pengguna untuk di-scan.
Grup WhatsApp
Semua endpoint grup memerlukan api_key + number_key. Sistem menentukan sesi secara otomatis dari number_key.
Ambil Grup Tersimpan — POST /api/v1/group
Mengembalikan grup yang sudah disimpan ke Group Book di dashboard.
$ch = curl_init('https://whutzupp.web.id/api/v1/group');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'api_key' => 'ABC123DEF456',
'number_key' => 'AB12CD34EF',
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($res['groups'] as $g) {
echo $g['name'] . ' — token: ' . $g['token'] . PHP_EOL;
}
Response:
{
"success": true,
"session_name": "marketing",
"phone": "628123456789",
"total": 2,
"groups": [
{
"id": 1,
"name": "Tim Marketing",
"jid": "120363040000000001@g.us",
"token": "grp:E0B512E5",
"size": 12,
"is_admin": true,
"saved_at": "2026-07-14 09:00:00"
}
]
}
Alias:
POST /api/v1/group/saved— request dan response identik.
Semua Grup Live Bot — GET /api/v1/group/list?session={nama}
Mengembalikan semua grup yang saat ini diikuti bot, langsung dari WhatsApp (bukan hanya yang tersimpan di Group Book). Berguna untuk sinkronisasi atau audit keanggotaan.
GET /api/v1/group/list?session=marketing
X-API-Key: ABC123DEF456
Response:
{
"success": true,
"total": 5,
"groups": [
{
"id": "120363040000000001@g.us",
"subject": "Tim Marketing",
"desc": "Grup koordinasi tim",
"owner": "628123456789@s.whatsapp.net",
"size": 12,
"creation": 1720000000,
"is_admin": true
}
]
}
Detail + Anggota — GET /api/v1/group/{jid}?session={nama}
$jid = urlencode('120363040000000001@g.us');
$ch = curl_init("https://whutzupp.web.id/api/v1/group/$jid?session=marketing");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['X-API-Key: ABC123DEF456'],
CURLOPT_RETURNTRANSFER => true,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($res['group']['participants'] as $p) {
echo $p['phone'] . ' — ' . ($p['admin'] ?? 'member') . PHP_EOL;
}
Link Undangan Grup — GET /api/v1/group/invite-link?jid={jid}&session={nama}
Mengambil JID dan link undangan (https://chat.whatsapp.com/…) sekaligus dalam satu request.
Syarat: Bot harus menjadi admin di grup tersebut.
$jid = '120363040000000001@g.us';
$session = 'marketing';
$ch = curl_init('https://whutzupp.web.id/api/v1/group/invite-link?' . http_build_query([
'jid' => $jid,
'session' => $session,
]));
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['X-API-Key: ABC123DEF456'],
CURLOPT_RETURNTRANSFER => true,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $res['jid']; // 120363040000000001@g.us
echo $res['invite_link']; // https://chat.whatsapp.com/AbCdEfGhIjK...
Response sukses:
{
"success": true,
"jid": "120363040000000001@g.us",
"invite_link": "https://chat.whatsapp.com/AbCdEfGhIjKlMnOpQrStUv"
}
Alur umum — ambil semua grup sekaligus lalu loop untuk dapat link tiap grup:
// 1. Ambil daftar grup
$ch = curl_init('https://whutzupp.web.id/api/v1/group/list?session=marketing');
curl_setopt_array($ch, [CURLOPT_HTTPHEADER => ['X-API-Key: ABC123DEF456'], CURLOPT_RETURNTRANSFER => true]);
$groups = json_decode(curl_exec($ch), true)['groups'] ?? [];
curl_close($ch);
// 2. Ambil link per grup
foreach ($groups as $g) {
$ch = curl_init('https://whutzupp.web.id/api/v1/group/invite-link?' . http_build_query([
'jid' => $g['id'],
'session' => 'marketing',
]));
curl_setopt_array($ch, [CURLOPT_HTTPHEADER => ['X-API-Key: ABC123DEF456'], CURLOPT_RETURNTRANSFER => true]);
$link = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $g['subject'] . ' → ' . $link['invite_link'] . PHP_EOL;
}
Kick Member — POST /api/v1/group/kick
Keluarkan anggota dari grup. Bot harus menjadi admin di grup tersebut.
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"session": "marketing",
"group_jid": "120363040000000001@g.us",
"participant": "628111000001"
}
participant bisa berupa nomor biasa atau JID lengkap (@s.whatsapp.net).
Response sukses:
{ "success": true, "message": "Member berhasil di-kick dari grup" }
Kirim Pesan ke Grup
Ada dua cara mengalamati grup sebagai tujuan:
Cara 1 — JID langsung (panjang, perlu disimpan sendiri):
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "120363040000000001@g.us",
"message": "Halo tim! Ada pengumuman penting."
}
Cara 2 — Group Token (pendek, dari Group Book — direkomendasikan):
{
"api_key": "ABC123DEF456",
"number_key": "AB12CD34EF",
"phone_no": "grp:E0B512E5",
"message": "Halo tim! Ada pengumuman penting."
}
Token
grp:XXXXXXXXdidapat dari Dashboard → Grup WA → Group Book — klik ikon salin di samping token.
Kirim ke Banyak Grup
// Bisa campur nomor individu, JID grup, dan Group Token
$targets = [
'grp:E0B512E5', // dari Group Book
'grp:A1EF661F', // dari Group Book
'628111000001', // nomor individu
];
$message = 'Pengumuman untuk semua!';
foreach ($targets as $to) {
$ch = curl_init('https://whutzupp.web.id/api/v1/send_message');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'api_key' => 'ABC123DEF456',
'number_key' => 'AB12CD34EF',
'phone_no' => $to,
'message' => $message,
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
sleep(2);
}
Group Token
Group Token adalah alias pendek untuk JID grup WhatsApp yang panjang. Token di-generate otomatis saat grup disimpan ke Group Book di dashboard.
Format
grp:XXXXXXXX
XXXXXXXX — 8 karakter uppercase alphanumeric, unik per platform.
Cara Mendapatkan Token
- Buka Dashboard → Grup WA
- Pilih sesi → grup muncul
- Klik tombol Simpan Group pada grup yang diinginkan
- Di panel Group Book di bawah, token
grp:XXXXXXXXtampil di samping nama grup - Klik ikon salin — token langsung tersalin ke clipboard
Penggunaan di API
Token bisa dipakai di field to, phone_no, maupun elemen array numbers di mana pun nomor tujuan diterima:
// Kirim teks ke grup via token
whutzupp('send_message', [
'number_key' => 'AB12CD34EF',
'phone_no' => 'grp:E0B512E5',
'message' => 'Notifikasi otomatis dari sistem.',
]);
// Kirim media ke grup via token
whutzupp('message/send-media', [
'number_key' => 'AB12CD34EF',
'to' => 'grp:E0B512E5',
'type' => 'image',
'url' => 'https://domain.com/grafik.jpg',
'caption' => 'Laporan harian',
]);
// Bulk — campur token dan nomor biasa
whutzupp('message/send-bulk', [
'number_key' => 'AB12CD34EF',
'numbers' => ['grp:E0B512E5', 'grp:A1EF661F', '628111000001'],
'text' => 'Update sistem telah selesai.',
]);
Token diselesaikan ke JID di sisi server — tidak perlu menyimpan atau mengelola JID panjang di kode Anda.
Webhook
Daftarkan endpoint di server Anda untuk menerima notifikasi real-time saat ada event di WhatsApp.
Manajemen Webhook
| Method | Endpoint | Keterangan |
|---|---|---|
GET |
/api/v1/webhook |
List semua webhook terdaftar |
POST |
/api/v1/webhook |
Daftarkan webhook baru |
DELETE |
/api/v1/webhook/{id} |
Hapus webhook |
Tidak ada batas jumlah webhook per akun.
Daftarkan webhook:
POST /api/v1/webhook
X-API-Key: ABC123DEF456
{
"url": "https://domain.com/wa-event.php",
"secret": "rahasia-untuk-verifikasi",
"events": ["message.received", "group.join", "group.leave"]
}
Event yang Tersedia
| Event | Kapan dipicu |
|---|---|
message.received |
Pesan masuk ke bot (DM) |
message.sent |
Pesan terkirim dari bot |
message.delivered |
Pesan terkirim ke perangkat penerima |
message.read |
Pesan dibaca penerima |
session.connected |
Sesi WA berhasil terhubung |
session.disconnected |
Sesi WA terputus |
group.join |
Ada anggota baru bergabung ke grup |
group.leave |
Anggota keluar atau dikeluarkan dari grup |
group.mention |
Bot disebut (@mention) di grup |
Format Payload ke Endpoint Anda
{
"event": "message.received",
"timestamp": 1720600000,
"session": "marketing",
"data": {
"from": "628123456789@s.whatsapp.net",
"text": "Halo!",
"msg_id": "3EB0ABCDEF1234567890"
},
"signature": "<HMAC-SHA256 dari secret webhook>"
}
Verifikasi Signature
$secret = 'rahasia-untuk-verifikasi';
$body = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WHUTZUPP_SIGNATURE'] ?? '';
if (!hash_equals(hash_hmac('sha256', $body, $secret), $signature)) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);
// proses $event['event'], $event['data'], dst
Retry otomatis 3× jika endpoint Anda membalas selain 2xx: delay 5 detik, 30 detik, 5 menit.
Data per Event
group.join / group.leave:
{
"group_jid": "120363040000000001@g.us",
"action": "join",
"participants": [
{ "jid": "628111000001@s.whatsapp.net", "phone": "628111000001" }
]
}
group.mention:
{
"group_jid": "120363040000000001@g.us",
"from_jid": "628111000001@s.whatsapp.net",
"text": "Halo @bot ada pertanyaan"
}
Pesan Berkala
Opsi 1 — Dashboard (tanpa coding)
Dashboard → Pesan Berkala — buat jadwal kirim otomatis, diproses server setiap menit.
| Tipe | Format Nilai | Contoh |
|---|---|---|
| Sekali kirim | YYYY-MM-DD HH:MM |
2026-08-01 09:00 |
| Setiap hari | HH:MM |
08:30 |
| Setiap minggu | D,HH:MM (D: 1=Sen … 7=Min) |
1,08:00 |
| Interval | Menit integer | 60 |
Kolom Tujuan menerima nomor individu (628xxx), JID grup (120363xxx@g.us), maupun Group Token (grp:XXXXXXXX).
Pilih langsung dari Phonebook atau Group Book via tombol di samping input.
Opsi 2 — Cron di Server Anda
<?php
$apiKey = 'ABC123DEF456'; // ganti dengan API Key Anda
$numberKey = 'AB12CD34EF'; // ganti dengan Number Key Anda
$groupToken = 'grp:E0B512E5'; // dari Dashboard → Group Book
$message = sprintf(
"📊 *Laporan %s*\n\nOrder: %d\nOmzet: %s",
date('d F Y'), 42, 'Rp 12.500.000'
);
$ch = curl_init('https://whutzupp.web.id/api/v1/send_message');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'api_key' => $apiKey,
'number_key' => $numberKey,
'phone_no' => $groupToken,
'message' => $message,
]),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . $apiKey,
'X-Timestamp: ' . time(),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $result['success'] ? "OK\n" : "Gagal: " . $result['message'] . "\n";
Daftarkan ke crontab (jam 08:00 WITA = 00:00 UTC):
0 0 * * * /usr/bin/php /path/to/kirim_laporan.php >> /var/log/wa_laporan.log 2>&1
Smart Bot — Memproses Pesan Masuk di File PHP
Smart Bot memanggil file PHP Anda setiap kali pesan masuk cocok dengan keyword trigger.
Metode HTTP yang Digunakan
Penting: Smart Bot mengirim request ke webhook Anda menggunakan HTTP GET, bukan POST. Seluruh data — sender, message, group_jid, dll — tersedia di query string (
$_GET). HeaderX-WhutzUpp-*juga dikirim bersamaan.Pastikan endpoint Anda bisa menerima GET. Jika Anda memfilter method di router (misalnya
$routes->post(...)), trigger tidak akan diproses meski server membalas HTTP 200.
Contoh URL yang dipanggil Smart Bot:
GET /webhook.php?sender=6281234567890&session=marketing&message=TF+Nama+500000&group_jid=120363xxx%40g.us
Yang Dikirim Server ke File PHP Anda
| Header | Isi |
|---|---|
X-WhutzUpp-Key |
Webhook key — gunakan untuk verifikasi pengirim |
X-WhutzUpp-Trigger |
Keyword yang cocok, huruf besar (misal: INFO) |
X-WhutzUpp-Sender |
Nomor pengirim (misal: 6281234567890) |
X-WhutzUpp-Session |
Nama sesi bot yang menerima pesan |
X-WhutzUpp-Message |
Isi pesan lengkap dari pengirim |
X-WhutzUpp-Group |
JID grup asal pesan (misal: 120363xxx@g.us) — hanya ada jika pesan dari grup |
Data yang sama juga tersedia di query string ($_GET):
| Query param | Isi |
|---|---|
sender |
Nomor pengirim |
session |
Nama sesi |
message |
Isi pesan lengkap |
param1 |
Kata kedua dalam pesan (setelah keyword) |
param2 |
Kata ketiga |
params |
Semua kata setelah keyword, digabung spasi |
group_jid |
JID grup asal pesan — otomatis ditambahkan jika pesan dari grup |
Contoh: pesan DAFTAR 6281234 ABC → param1=6281234, param2=ABC, params=6281234 ABC
Jika pesan berasal dari grup, header
X-WhutzUpp-Groupdan query paramgroup_jidterisi otomatis dengan JID grup (misal:120363040000000001@g.us). Gunakan ini sebagaitosaat membalas ke grup via API.
Tambah Trigger via Dashboard
Buka Dashboard → Smart Bot → Trigger Keyword → klik Tambah Trigger.
Setelah trigger dibuat, klik Cek Koneksi Webhook — jika berhasil (HTTP 200), tombol Aktifkan muncul. Trigger baru aktif setelah dikonfirmasi.
Tambah Trigger via API
Untuk integrasi programatik — misalnya aplikasi Anda ingin mendaftarkan trigger sendiri.
Request trigger:
POST /api/v1/trigger/request
X-API-Key: ABC123DEF456
{
"keyword": "DAFTAR",
"webhook_url": "https://domain.com/daftar.php?from={sender}&kode={param1}",
"description": "Daftarkan nomor baru",
"callback_url": "https://domain.com/trigger-approved.php"
}
| Field | Wajib | Keterangan |
|---|---|---|
keyword |
Ya | Satu kata, huruf besar otomatis |
webhook_url |
Ya | URL yang dipanggil saat trigger aktif |
description |
Tidak | Catatan singkat |
callback_url |
Tidak | URL yang dipanggil saat trigger disetujui |
Setelah request masuk, sistem langsung ping webhook_url dengan dummy request:
- Jika server Anda balas HTTP 2xx → trigger langsung aktif,
callback_urldipanggil - Jika ping gagal → request ditolak dengan pesan error, trigger tidak disimpan
Keyword yang sama boleh didaftarkan di sesi lain — konflik hanya terjadi jika keyword + sesi sama persis.
Response sukses (webhook aktif):
{
"success": true,
"message": "Trigger 'DAFTAR' aktif — webhook berhasil diverifikasi.",
"data": {
"trigger_id": 7,
"whutzupp_trigger_id": 7,
"keyword": "DAFTAR",
"webhook_key": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"is_active": true,
"ping_http_code": 200
}
}
Response gagal (webhook tidak merespons):
{
"success": false,
"message": "Gagal mendaftarkan trigger 'DAFTAR'. Webhook tidak merespons (timeout/tidak terjangkau). Pastikan URL dapat diakses dari internet.",
"errors": { "ping_http_code": 0, "ping_error": "Connection timed out" }
}
Response gagal (server error):
{
"success": false,
"message": "Gagal mendaftarkan trigger 'DAFTAR'. Webhook membalas HTTP 403 (bukan 2xx). Pastikan endpoint mengembalikan HTTP 200.",
"errors": { "ping_http_code": 403, "ping_error": null }
}
Simpan webhook_key dari response sukses — dibutuhkan untuk verifikasi di file PHP Anda. callback_url langsung dipanggil:
{
"status": "approved",
"keyword": "DAFTAR",
"trigger_id": 7,
"webhook_key": "a1b2c3d4e5f6..."
}
Cabut trigger:
DELETE /api/v1/trigger/7
X-API-Key: ABC123DEF456
Contoh File PHP per Versi
PHP 5.6 / 7.0
<?php
define('WEBHOOK_KEY', 'isi_key_dari_dashboard');
function respond($code, $msg, $extra = array()) {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(array_merge(array('status' => $code === 200 ? 'ok' : 'error', 'message' => $msg), $extra));
exit;
}
$key = isset($_SERVER['HTTP_X_WHUTZUPP_KEY']) ? $_SERVER['HTTP_X_WHUTZUPP_KEY'] : '';
if (!hash_equals(WEBHOOK_KEY, $key)) { respond(403, 'Unauthorized'); }
$trigger = isset($_SERVER['HTTP_X_WHUTZUPP_TRIGGER']) ? $_SERVER['HTTP_X_WHUTZUPP_TRIGGER'] : '';
$sender = isset($_SERVER['HTTP_X_WHUTZUPP_SENDER']) ? $_SERVER['HTTP_X_WHUTZUPP_SENDER'] : '';
$session = isset($_SERVER['HTTP_X_WHUTZUPP_SESSION']) ? $_SERVER['HTTP_X_WHUTZUPP_SESSION'] : '';
$message = isset($_SERVER['HTTP_X_WHUTZUPP_MESSAGE']) ? $_SERVER['HTTP_X_WHUTZUPP_MESSAGE'] : '';
$param1 = isset($_GET['param1']) ? $_GET['param1'] : '';
$phone = preg_replace('/@\S+/', '', $sender);
switch (strtoupper($trigger)) {
case 'INFO':
respond(200, 'OK', array('pengirim' => $phone, 'pesan' => $message));
break;
default:
respond(200, 'OK');
}
PHP 7.1 – 7.4
<?php
declare(strict_types=1);
define('WEBHOOK_KEY', 'isi_key_dari_dashboard');
function respond(int $code, string $msg, array $extra = []): void {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(array_merge(['status' => $code === 200 ? 'ok' : 'error', 'message' => $msg], $extra));
exit;
}
$key = $_SERVER['HTTP_X_WHUTZUPP_KEY'] ?? '';
if (!hash_equals(WEBHOOK_KEY, $key)) { respond(403, 'Unauthorized'); }
$trigger = $_SERVER['HTTP_X_WHUTZUPP_TRIGGER'] ?? '';
$sender = $_SERVER['HTTP_X_WHUTZUPP_SENDER'] ?? '';
$session = $_SERVER['HTTP_X_WHUTZUPP_SESSION'] ?? '';
$message = $_SERVER['HTTP_X_WHUTZUPP_MESSAGE'] ?? '';
$param1 = $_GET['param1'] ?? '';
$phone = preg_replace('/@\S+/', '', $sender);
switch (strtoupper($trigger)) {
case 'INFO':
respond(200, 'OK', ['pengirim' => $phone, 'pesan' => $message]);
break;
default:
respond(200, 'OK');
}
PHP 8.0+
<?php
declare(strict_types=1);
define('WEBHOOK_KEY', 'isi_key_dari_dashboard');
function respond(int $code, string $msg, array $extra = []): void {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => $code === 200 ? 'ok' : 'error', 'message' => $msg, ...$extra]);
exit;
}
$key = $_SERVER['HTTP_X_WHUTZUPP_KEY'] ?? '';
if (!hash_equals(WEBHOOK_KEY, $key)) { respond(403, 'Unauthorized'); }
$trigger = $_SERVER['HTTP_X_WHUTZUPP_TRIGGER'] ?? '';
$sender = $_SERVER['HTTP_X_WHUTZUPP_SENDER'] ?? '';
$session = $_SERVER['HTTP_X_WHUTZUPP_SESSION'] ?? '';
$message = $_SERVER['HTTP_X_WHUTZUPP_MESSAGE'] ?? '';
$param1 = $_GET['param1'] ?? '';
$phone = preg_replace('/@\S+/', '', $sender);
match (strtoupper($trigger)) {
'INFO' => respond(200, 'OK', ['pengirim' => $phone, 'pesan' => $message]),
default => respond(200, 'OK'),
};
Cara Baca Header di PHP
| Header dikirim | Cara baca di PHP |
|---|---|
X-WhutzUpp-Key |
$_SERVER['HTTP_X_WHUTZUPP_KEY'] |
X-WhutzUpp-Trigger |
$_SERVER['HTTP_X_WHUTZUPP_TRIGGER'] |
X-WhutzUpp-Sender |
$_SERVER['HTTP_X_WHUTZUPP_SENDER'] |
X-WhutzUpp-Session |
$_SERVER['HTTP_X_WHUTZUPP_SESSION'] |
X-WhutzUpp-Message |
$_SERVER['HTTP_X_WHUTZUPP_MESSAGE'] |
X-WhutzUpp-Group |
$_SERVER['HTTP_X_WHUTZUPP_GROUP'] — hanya ada jika dari grup |
X-WhutzUpp-Senderbisa berupa nomor biasa atau JID. Gunakanpreg_replace('/@\S+/', '', $sender)untuk mendapatkan nomor saja.Pola umum balasan:
$to = $_SERVER['HTTP_X_WHUTZUPP_GROUP'] ?: $_SERVER['HTTP_X_WHUTZUPP_SENDER'];— pakai grup jika ada, fallback ke pengirim.
Notif Grup — Group Join Trigger
Kirim pesan otomatis saat ada anggota baru bergabung ke grup yang dipantau.
Via Dashboard
Buka Dashboard → Smart Bot → Notif Grup → klik Tambah Notif Grup.
Via API
| Method | Endpoint | Keterangan |
|---|---|---|
GET |
/api/v1/bot/group-trigger |
List semua group trigger |
POST |
/api/v1/bot/group-trigger |
Buat group trigger baru |
POST |
/api/v1/bot/group-trigger/{id}/toggle |
Aktifkan / nonaktifkan |
DELETE |
/api/v1/bot/group-trigger/{id} |
Hapus |
Buat group trigger:
POST /api/v1/bot/group-trigger
X-API-Key: ABC123DEF456
{
"number_key": "AB12CD34EF",
"session_name": "marketing",
"source_group_jid": "120363040000000001@g.us",
"source_group_name":"Grup Pelanggan",
"target_jid": "120363040000000002@g.us",
"message_template": "Selamat datang, {nomor}! Silakan perkenalkan diri."
}
session_name bisa digantikan dengan number_key — sistem otomatis menentukan sesi.
Placeholder di message_template:
| Placeholder | Isi |
|---|---|
{nomor} |
Nomor HP anggota baru |
{jid} |
JID lengkap anggota baru |
{group_jid} |
JID grup yang dipantau |
Bot di Grup — Keyword Trigger dari Pesan Grup
Smart Bot sekarang juga merespons pesan yang dikirim ke grup WhatsApp yang diikuti bot, tidak hanya pesan pribadi.
Cara Kerja
- Anggota grup mengirim pesan yang dimulai dengan keyword (misal:
TF hb Fathur Rp 1jt) - Bot mencocokkan keyword
TFdengan trigger yang sudah dikonfigurasi - Bot memanggil URL webhook Anda dan — jika diatur — membalas langsung di grup
- Jika keyword tidak cocok: bot tidak membalas di grup (tidak ada pesan fallback di grup)
Keyword trigger dikonfigurasi di Dashboard → Smart Bot → Trigger Keyword — sama persis dengan trigger untuk pesan pribadi. Tidak perlu konfigurasi terpisah.
Filter Pengirim — Hanya Nomor Tertentu yang Bisa Trigger Bot di Grup
Secara default semua anggota grup bisa men-trigger bot. Anda bisa membatasinya agar hanya nomor tertentu yang direspons.
Cara mengatur:
- Buka Dashboard → Sesi
- Klik ikon ⚙ di kartu sesi yang diinginkan
- Di bagian "Filter Pengirim di Grup", isi nomor HP yang diizinkan — satu nomor per baris:
6281234567890 6289876543210 - Klik Simpan
Catatan:
- Kosongkan = semua anggota grup bisa trigger bot (default)
- Nomor boleh diawali
0atau62— sistem otomatis normalisasi - Filter ini hanya berlaku untuk pesan dari grup — pesan pribadi tidak terpengaruh
- Whitelist berlaku per sesi, bukan per grup
Contoh Use Case
Grup keuangan → anggota kirim: "TF hb Fathur Rp 1.000.000"
Bot mendeteksi keyword TF → memanggil webhook Anda:
X-WhutzUpp-Trigger : TF
X-WhutzUpp-Sender : 6281234567890
X-WhutzUpp-Session : keuangan
X-WhutzUpp-Message : TF hb Fathur Rp 1.000.000
X-WhutzUpp-Group : 120363040000000001@g.us ← JID grup
param1 : hb
param2 : Fathur
params : hb Fathur Rp 1.000.000
group_jid : 120363040000000001@g.us ← sama, di query string
File PHP Anda membaca header X-WhutzUpp-Group (atau query param group_jid) untuk tahu ke mana harus membalas:
<?php
define('API_KEY', 'ABC123DEF456');
define('NUMBER_KEY', 'AB12CD34EF');
define('WEBHOOK_KEY', 'isi_key_dari_dashboard');
$key = $_SERVER['HTTP_X_WHUTZUPP_KEY'] ?? '';
if (!hash_equals(WEBHOOK_KEY, $key)) { http_response_code(403); exit; }
$trigger = $_SERVER['HTTP_X_WHUTZUPP_TRIGGER'] ?? '';
$sender = $_SERVER['HTTP_X_WHUTZUPP_SENDER'] ?? '';
$message = $_SERVER['HTTP_X_WHUTZUPP_MESSAGE'] ?? '';
$groupJid = $_SERVER['HTTP_X_WHUTZUPP_GROUP'] ?? ''; // kosong = pesan pribadi
$params = $_GET['params'] ?? '';
// Tentukan tujuan balasan: grup jika ada, fallback ke sender
$replyTo = $groupJid ?: $sender;
http_response_code(200);
header('Content-Type: application/json');
echo json_encode(['status' => 'ok']);
// Proses di background agar webhook tidak timeout
fastcgi_finish_request(); // untuk PHP-FPM; hapus jika tidak pakai
// Balas ke grup / pengirim
$balasan = "Transfer *{$params}* dicatat. Terima kasih!";
$ch = curl_init('https://whutzupp.web.id/api/v1/send_message');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'api_key' => API_KEY,
'number_key' => NUMBER_KEY,
'phone_no' => $replyTo, // ← grup JID atau nomor pengirim
'message' => $balasan,
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
curl_exec($ch);
curl_close($ch);
Mode Whitelist (Keamanan Pengiriman)
Semua sesi aktif menerapkan mode whitelist secara default. Dalam mode ini, bot hanya mau mengirim pesan ke nomor yang sebelumnya pernah menghubungi bot terlebih dahulu.
Cara Kerja
- Seseorang mengirim pesan ke bot → nomornya otomatis masuk whitelist sesi tersebut
- Ketika Anda request kirim pesan ke nomor tersebut dari API → dikirim
- Nomor yang belum pernah chat dengan bot → request ditolak (tidak dikirim)
Tujuan
Melindungi klien dari mengirim pesan ke nomor yang tidak dikenal, mengurangi risiko akun WA diblokir karena spam.
Melihat Jumlah Whitelist
Di Dashboard → Sesi, setiap sesi yang aktif mode whitelist menampilkan badge berisi jumlah nomor yang sudah terdaftar.
Solusi Jika Nomor Belum di Whitelist
Minta penerima mengirim pesan apapun ke nomor bot terlebih dahulu. Setelah itu nomor mereka otomatis tersimpan dan pesan dari API bisa dikirim.
Rate Limit
| Tier | Limit pengiriman | Pesan/hari | Sesi maks |
|---|---|---|---|
| Free | 1 per 3 menit | 5 | 1 |
| Starter | Tak terbatas | Tak terbatas | 1 |
| Pro | Tak terbatas | Tak terbatas | 2 |
| Enterprise | Tak terbatas | Tak terbatas | 4 |
Kirim ke grup dihitung sama dengan kirim ke individu.
Rate limit terlampaui → HTTP 429, header Retry-After berisi detik tunggu.
Akun & Penggunaan
Usage Bulan Ini — GET /api/v1/account/usage
GET /api/v1/account/usage
X-API-Key: ABC123DEF456
Response:
{
"success": true,
"data": {
"year": 2026,
"month": 9,
"messages_sent": 142,
"messages_received": 88,
"sessions_active": 2
}
}
Profil Akun — GET /api/v1/account/profile
GET /api/v1/account/profile
X-API-Key: ABC123DEF456
Response:
{
"success": true,
"data": {
"name": "Nama Klien",
"email": "email@domain.com",
"tier": "pro",
"status": "active"
}
}
Contoh PHP Lengkap
<?php
// Ganti dengan key Anda dari Dashboard → API Key
define('API_KEY', 'ABC123DEF456'); // 12 karakter
define('NUMBER_KEY', 'AB12CD34EF'); // 10 karakter
define('BASE_URL', 'https://whutzupp.web.id/api/v1');
function whutzupp(string $endpoint, array $body): array {
$ch = curl_init(BASE_URL . '/' . ltrim($endpoint, '/'));
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . API_KEY,
'X-Timestamp: ' . time(),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
]);
$raw = curl_exec($ch);
curl_close($ch);
return json_decode($raw ?: '{}', true) ?: ['success' => false, 'message' => 'Curl error'];
}
// Kirim teks ke nomor
$res = whutzupp('send_message', [
'number_key' => NUMBER_KEY,
'phone_no' => '628123456789',
'message' => 'Halo dari sistem!',
]);
echo $res['success'] ? "Terkirim: msg_id=" . $res['data']['message_id'] . "\n" : "Gagal: " . $res['message'] . "\n";
// Kirim gambar
$res = whutzupp('send_image_url', [
'number_key' => NUMBER_KEY,
'phone_no' => '628123456789',
'url' => 'https://domain.com/gambar.jpg',
'message' => 'Lihat gambar ini!',
]);
// Kirim ke grup via Group Token (direkomendasikan)
$res = whutzupp('send_message', [
'number_key' => NUMBER_KEY,
'phone_no' => 'grp:E0B512E5', // dari Dashboard → Group Book
'message' => 'Pengumuman untuk seluruh tim.',
]);
// Kirim ke grup via JID langsung
$res = whutzupp('send_message', [
'number_key' => NUMBER_KEY,
'phone_no' => '120363040000000001@g.us',
'message' => 'Pengumuman untuk seluruh tim.',
]);
// Bulk ke banyak nomor dan grup (async, max 100)
$res = whutzupp('message/send-bulk', [
'number_key' => NUMBER_KEY,
'numbers' => ['628111000001', '628111000002', 'grp:E0B512E5'],
'text' => 'Promo spesial hari ini!',
'delay_ms' => 1500,
]);
echo "Antrian: " . ($res['data']['queued'] ?? 0) . " nomor\n";
Tips
- Group Token — simpan grup ke Group Book sekali, pakai
grp:XXXXXXXXselamanya — jauh lebih mudah dari JID panjang@g.us - JID grup selalu berakhiran
@g.us— alternatif Group Token jika butuh JID langsung - Kirim ke grup = kirim ke individu — cukup ganti
phone_nodengan JID atau Group Token, tidak ada endpoint khusus - Rate limit sama — kirim ke grup dihitung sama dengan kirim ke individu
- Jeda antar kirim — pakai
sleep(1-2)ataudelay_mssaat blast ke banyak nomor/grup - Whitelist — minta pelanggan kirim pesan ke bot lebih dulu agar nomornya otomatis terdaftar sebelum Anda kirim notifikasi
- Webhook signature — selalu verifikasi
X-WhutzUpp-Signaturedi endpoint webhook Anda sebelum memproses event - Phonebook & Group Book — kelola kontak dan grup tersimpan di Dashboard untuk referensi cepat saat membuat Pesan Berkala