● 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" }

Cek Status Pesan — GET /api/v1/message/{id}/status

GET /api/v1/message/42/status
X-API-Key: ABC123DEF456

data.status: queuedsentdeliveredread | 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: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.


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 ABCparam1=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-Sender bisa berupa nomor biasa atau JID. Gunakan preg_replace('/@\S+/', '', $sender) untuk mendapatkan nomor saja.


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. Phonebook & Group Book — kelola kontak dan grup tersimpan di Dashboard untuk referensi cepat saat membuat Pesan Berkala
File Contoh PHP Ganti API_KEY_ANDA dan NUMBER_KEY_ANDA, langsung pakai.
↓ Download whutzupp-example.php