● WhutzUppGateway

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

  1. Login Dashboard → API Key → salin API Key (12 karakter)
  2. Hubungkan nomor WA di Dashboard → Sesi → scan QR
  3. Setelah terhubung, Number Key (10 karakter) muncul otomatis di tabel Number Key
  4. 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:XXXXXXXX didapat 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

  1. Buka Dashboard → Grup WA
  2. Pilih sesi → grup muncul
  3. Klik tombol Simpan Group pada grup yang diinginkan
  4. Di panel Group Book di bawah, token grp:XXXXXXXX tampil di samping nama grup
  5. 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). Header X-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-Group dan query param group_jid terisi otomatis dengan JID grup (misal: 120363040000000001@g.us). Gunakan ini sebagai to saat 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:

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-Sender bisa berupa nomor biasa atau JID. Gunakan preg_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

  1. Anggota grup mengirim pesan yang dimulai dengan keyword (misal: TF hb Fathur Rp 1jt)
  2. Bot mencocokkan keyword TF dengan trigger yang sudah dikonfigurasi
  3. Bot memanggil URL webhook Anda dan — jika diatur — membalas langsung di grup
  4. 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:

  1. Buka Dashboard → Sesi
  2. Klik ikon ⚙ di kartu sesi yang diinginkan
  3. Di bagian "Filter Pengirim di Grup", isi nomor HP yang diizinkan — satu nomor per baris:
    6281234567890
    6289876543210
  4. Klik Simpan

Catatan:

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

  1. Seseorang mengirim pesan ke bot → nomornya otomatis masuk whitelist sesi tersebut
  2. Ketika Anda request kirim pesan ke nomor tersebut dari API → dikirim
  3. 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

  1. Group Token — simpan grup ke Group Book sekali, pakai grp:XXXXXXXX selamanya — jauh lebih mudah dari JID panjang @g.us
  2. JID grup selalu berakhiran @g.us — alternatif Group Token jika butuh JID langsung
  3. Kirim ke grup = kirim ke individu — cukup ganti phone_no dengan JID atau Group Token, tidak ada endpoint khusus
  4. Rate limit sama — kirim ke grup dihitung sama dengan kirim ke individu
  5. Jeda antar kirim — pakai sleep(1-2) atau delay_ms saat blast ke banyak nomor/grup
  6. Whitelist — minta pelanggan kirim pesan ke bot lebih dulu agar nomornya otomatis terdaftar sebelum Anda kirim notifikasi
  7. Webhook signature — selalu verifikasi X-WhutzUpp-Signature di endpoint webhook Anda sebelum memproses event
  8. Phonebook & Group Book — kelola kontak dan grup tersimpan di Dashboard untuk referensi cepat saat membuat Pesan Berkala
Coba Langsung — Hubungkan Nomor WhatsApp via API Gunakan API Key dari dashboard Anda

Belum punya API Key? Daftar gratis atau login ke dashboard.

Buka WhatsApp di HP → ⋮ Menu → Perangkat Tertaut → Tautkan Perangkat

Menunggu QR code dari server...
✅

WhatsApp Terhubung!

🔑 Number Key — gunakan ini bersama API Key di setiap request pengiriman pesan

Simpan Number Key ini — dibutuhkan di setiap request kirim pesan. Lihat semua key di Dashboard → API Key.

File Contoh PHP Ganti API_KEY_ANDA dan NUMBER_KEY_ANDA, langsung pakai.
↓ Download whutzupp-example.php
⇧