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" }
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
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 — hanya mengembalikan grup yang sudah disimpan ke Group Book.
Ambil Grup Tersimpan — POST /api/v1/group
$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"
},
{
"id": 2,
"name": "Internal Ops",
"jid": "120363040000000002@g.us",
"token": "grp:A1EF661F",
"size": 5,
"is_admin": false,
"saved_at": "2026-07-14 10:30:00"
}
]
}
Alias:
POST /api/v1/group/saved— request dan response identik.
Contoh — ambil grup lalu langsung kirim pesan via token:
$res = whutzupp('group', ['number_key' => NUMBER_KEY]);
// Buat map nama → token
$groupMap = array_column($res['groups'], 'token', 'name');
whutzupp('send_message', [
'number_key' => NUMBER_KEY,
'phone_no' => $groupMap['Tim Marketing'], // "grp:E0B512E5"
'message' => 'Update dari sistem!',
]);
Detail + Anggota — GET /api/v1/group/{jid}?session=nama-sesi
$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;
}
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.
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
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.
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";
Smart Bot — Memproses Pesan Masuk di File PHP
Smart Bot memanggil file PHP Anda setiap kali pesan masuk cocok dengan keyword trigger.
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 |
Parameter juga tersedia di query string jika Anda pakai placeholder {param1} dst di URL trigger:
| Query param | Isi |
|---|---|
param1 |
Kata kedua dalam pesan (setelah keyword) |
param2 |
Kata ketiga |
params |
Semua kata setelah keyword, digabung spasi |
Contoh: pesan DAFTAR 6281234 ABC → param1=6281234, param2=ABC, params=6281234 ABC
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-Senderbisa berupa nomor biasa atau JID. Gunakanpreg_replace('/@\S+/', '', $sender)untuk mendapatkan nomor saja.
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 - Phonebook & Group Book — kelola kontak dan grup tersimpan di Dashboard untuk referensi cepat saat membuat Pesan Berkala