Dokumentasi API SmartWA
Panduan bagi sistem/aplikasi lain yang ingin mengirim dan menerima pesan WhatsApp lewat gateway SmartWA — satu API, banyak nomor, dilindungi kebijakan anti-blokir otomatis.
Ringkasan
SmartWA adalah gateway WhatsApp berbasis Baileys yang bisa dipakai bersama oleh banyak aplikasi (multi-tenant) dan banyak nomor WhatsApp sekaligus. Aplikasi Anda cukup memanggil satu REST API untuk mengirim pesan — SmartWA yang menangani pemilihan nomor, jam kirim, kuota harian, dan seluruh kebijakan anti-blokir di baliknya.
202) berarti pesan masuk antrian, bukan
langsung terkirim. Sistem kami (disebut Guard) memutuskan
kapan pesan benar-benar dikirim berdasarkan jam operasional, kuota,
dan riwayat hubungan dengan nomor tujuan — supaya nomor WhatsApp tidak
diblokir. Pantau status pengiriman lewat endpoint status atau webhook.
Base URL
https://smartwa.indosmartmedia.com/api/v1
Cara mendapatkan akses
Hubungi administrator SmartWA untuk didaftarkan sebagai aplikasi baru. Admin akan membuatkan API key dan meng-assign nomor WhatsApp yang boleh dipakai aplikasi Anda lewat dashboard. API key hanya ditampilkan sekali saat dibuat — simpan dengan aman, tidak bisa dilihat ulang setelahnya (hanya bisa diputar/diganti).
Autentikasi
Sertakan API key sebagai Bearer token di header Authorization pada setiap permintaan:
Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Alternatif (setara): header X-API-Key: sk_xxx....
Permintaan tanpa key atau dengan key yang tidak valid/nonaktif akan mendapat 401.
Endpoint
Semua endpoint mengembalikan JSON dengan field ok (boolean) yang menandakan berhasil/tidaknya permintaan.
Mengirim pesan teks atau media ke satu nomor. Pesan masuk antrian dan dievaluasi oleh Guard sebelum benar-benar dikirim.
Body (JSON)
| Field | Tipe | Keterangan |
|---|---|---|
phonewajib | string | Nomor tujuan. Format bebas (08123..., +62812..., 62812...) — dinormalisasi otomatis. |
textopsional* | string | Isi pesan, maks 4096 karakter. Mendukung spintax {a|b|c} — lihat Kategori & Kebijakan. *Wajib diisi kalau media.url kosong. |
mediaopsional | object | { url, type, caption } — type salah satu dari image, video, audio, document. url harus alamat publik (bukan IP privat/internal). |
categoryopsional | string | transactional, cs, atau marketing. Default cs. Menentukan nomor mana yang dipakai dan aturan mana yang berlaku. |
sessionopsional | string | Kode nomor spesifik (lihat Daftar Nomor). Kosongkan untuk membiarkan SmartWA memilih nomor tersehat secara otomatis sesuai category. |
idempotency_keyopsional | string | Kunci unik dari sisi Anda. Permintaan berulang dengan kunci sama tidak menghasilkan pesan ganda — aman dipakai untuk retry. |
Contoh permintaan
curl -X POST https://smartwa.indosmartmedia.com/api/v1/messages \ -H "Authorization: Bearer sk_xxx..." \ -H "Content-Type: application/json" \ -d '{ "phone": "081234567890", "text": "{Halo|Hai} Pak Budi, invoice INV-882 sudah terbit.", "category": "transactional", "idempotency_key": "inv-882-notif" }'
Respons
{
"ok": true,
"session": "cs-utama",
"id": 1042,
"status": "queued", // atau "scheduled"
"reason": null, // alasan jika "scheduled", mis. di luar jam kirim
"lane": "warm", // "reply-window" | "warm" | "cold" | null
"scheduled_at": "2026-09-13 08:30:12"
}
{ "ok": true, "duplicate": true, "id": 1042, "status": "sent", "reject_reason": null }
error{ "ok": false, "status": "rejected", "error": "Dilarang memakai URL shortener — pakai domain sendiri" }
session) tidak di-assign ke aplikasi Andasession yang disebut tidak ditemukanMengambil status terbaru satu pesan yang pernah dikirim lewat aplikasi Anda.
curl https://smartwa.indosmartmedia.com/api/v1/messages/1042 \
-H "Authorization: Bearer sk_xxx..."
{
"ok": true,
"message": {
"id": 1042, "phone": "6281234567890", "category": "transactional",
"status": "delivered", // queued|scheduled|sending|sent|delivered|read|failed|rejected|cancelled
"reject_reason": null, "wa_message_id": "3EB0...",
"scheduled_at": "2026-09-13 08:30:12", "sent_at": "2026-09-13 08:30:19",
"created_at": "2026-09-13 08:29:55"
}
}
Daftar nomor WhatsApp yang di-assign ke aplikasi Anda, beserta status dan sisa kuota — berguna untuk mengatur ritme pengiriman dari sisi aplikasi Anda sendiri.
{
"ok": true,
"sessions": [
{
"session": "cs-utama", "label": "CS Utama", "phone": "6281111111111",
"role": "cs", "status": "connected", "health_score": 96,
"paused_until": null,
"quota": {
"day": { "used": 42, "cap": 600 },
"hour": { "used": 3, "cap": 75 },
"cold": { "used": 1, "cap": 100 },
"warmupDay": 366
}
}
]
}
Aplikasi Anda hanya melihat nomor yang memang di-assign kepadanya — nomor milik aplikasi lain tidak akan muncul.
Memeriksa apakah sebuah nomor terdaftar di WhatsApp, sebelum mengirim pesan ke sana.
| Field | Tipe | Keterangan |
|---|---|---|
phonewajib | string | Nomor yang dicek. |
sessionopsional | string | Nomor pemeriksa spesifik. Kosongkan untuk otomatis. |
{ "ok": true, "phone": "6281234567890", "on_whatsapp": true }
Menambahkan nomor ke daftar cekal — nomor yang dicekal tidak akan pernah menerima pesan dari nomor WhatsApp mana pun di SmartWA, lintas aplikasi.
| Field | Tipe | Keterangan |
|---|---|---|
phonewajib | string | Nomor yang dicekal. |
reasonopsional | string | Alasan, untuk catatan admin. |
{ "ok": true, "phone": "6281234567890" }
Memeriksa apakah API key masih valid dan aktif — berguna untuk uji koneksi awal.
{ "ok": true, "app": "Nama Aplikasi Anda" }
Kategori & Kebijakan Pengiriman
Setiap pesan wajib punya category. Ini bukan sekadar
label — menentukan nomor mana yang boleh dipakai dan seberapa ketat
aturannya:
| Kategori | Dipakai untuk | Catatan |
|---|---|---|
transactional | OTP, notifikasi transaksi, invoice | Hanya lewat nomor berperan sama; paling longgar kuotanya. |
cs | Balasan layanan pelanggan | Default kalau tidak diisi. |
marketing | Promosi, broadcast | Paling ketat — tautan ke kontak baru ditolak, kuota kontak dingin dibatasi. |
transactional menolak pesan berkategori
marketing, dan sebaliknya. Ini sengaja — satu laporan
spam di nomor marketing tidak boleh sampai menjatuhkan nomor yang
mengirim OTP.
Spintax pada text
Gunakan {opsi1|opsi2|opsi3} supaya setiap penerima
mendapat variasi kalimat yang sedikit berbeda — mengurangi risiko
pesan terdeteksi sebagai blast otomatis identik.
{Halo|Hai|Selamat pagi} Pak {nama}, {ada promo|tersedia penawaran} khusus hari ini.
Kenapa pesan bisa tertunda
- Di luar jam kirim nomor (default 08:00–20:00) — pesan dijadwalkan ke jendela berikutnya, bukan ditolak.
- Kuota harian/per jam tercapai — nomor baru punya kuota lebih kecil (naik bertahap selama masa warmup).
- Kontak baru (belum pernah membalas) punya kuota tersendiri yang lebih kecil.
Balasan ke kontak yang baru mengirim pesan dalam 24 jam terakhir
(lane: "reply-window") tidak terikat jam kirim —
langsung diproses kapan saja.
Kode Status HTTP
| Kode | Arti |
|---|---|
| 200 | Berhasil (permintaan GET, atau POST yang idempotent/tidak menghasilkan entitas baru) |
| 202 | Pesan diterima — masuk antrian atau dijadwalkan |
| 401 | API key tidak disertakan, tidak valid, atau nonaktif |
| 403 | Tidak berhak — nomor bukan milik aplikasi Anda, atau nomor blacklist tidak terkait aplikasi Anda |
| 404 | Sumber daya tidak ditemukan (pesan, atau session yang disebut) |
| 409 | Tidak ada nomor yang cocok/tersedia/tersambung saat ini |
| 422 | Validasi gagal, atau ditolak kebijakan Guard — lihat error |
| 429 | Terlalu banyak permintaan — lihat Batas Laju |
| 500 | Kesalahan internal. Respons menyertakan ref — sertakan saat melapor ke admin |
Batas Laju (Rate Limit)
| Cakupan | Batas |
|---|---|
Seluruh endpoint /api/v1/* | 120 permintaan / menit / aplikasi |
POST /contacts/check | 30 permintaan / menit / aplikasi (tambahan, lebih ketat) |
Respons 429 menyertakan header Retry-After (detik) — tunggu selama itu sebelum mencoba lagi.
Webhook
Kalau aplikasi Anda diberi webhook_url oleh admin,
SmartWA akan mengirim POST ke URL itu setiap kali
ada kejadian berikut:
| Event | Kapan | Payload data |
|---|---|---|
message.inbound | Pesan WhatsApp masuk ke nomor Anda | { session, phone, body, type, is_group, wa_message_id } |
message.sent | Pesan berhasil dikirim | { id, phone, wa_message_id, session } |
message.status | Status pesan berubah (delivered/read) | { session, wa_message_id, status } |
message.failed | Pesan gagal terkirim setelah percobaan berulang | { id, phone, error, session } |
session.logged_out | Nomor ter-logout, perlu scan ulang QR | { session } |
Bentuk permintaan
Body JSON, dan dua header tambahan:
POST <webhook_url_anda> X-SmartWA-Event: message.inbound X-SmartWA-Signature: sha256=<hex> Content-Type: application/json { "event": "message.inbound", "data": { ... }, "ts": 1789200000000 }
Verifikasi tanda tangan
Wajib diverifikasi sebelum memproses — mencegah orang lain
mengirim payload palsu ke endpoint Anda. Gunakan
webhook_secret yang diberikan admin bersamaan dengan
API key.
// Node.js const crypto = require('crypto'); function isValidSignature(rawBody, signatureHeader, webhookSecret) { const expected = 'sha256=' + crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signatureHeader || '') ); }
JSON.stringify() ulang,
yang bisa berbeda urutan/spasi dan membuat tanda tangan tidak cocok.
Percobaan ulang
Kalau endpoint Anda tidak merespons 2xx, SmartWA
mencoba ulang hingga 5 kali dengan jeda 1, 5, 15, 60, lalu 180
menit. Pastikan endpoint merespons cepat (di bawah 10 detik) dan
idempoten terhadap pengiriman ganda.
Pertanyaan Umum
Kenapa pesan saya berstatus "scheduled", bukan langsung terkirim?
Lihat Kategori & Kebijakan — biasanya karena di luar jam kirim nomor atau kuota harian/kontak-baru sudah tercapai. Ini bagian dari perlindungan nomor terhadap pemblokiran, bukan kesalahan.
Bisakah saya memilih nomor pengirim secara spesifik?
Ya, isi field session dengan kode nomor (lihat Daftar Nomor). Kosongkan untuk memilih otomatis.
Bagaimana kalau saya perlu kirim ke banyak nomor sekaligus (broadcast)?
Panggil endpoint kirim pesan satu per satu dari sisi aplikasi Anda. SmartWA akan mengatur jeda dan kecepatan pengiriman sungguhan secara internal — jangan mencoba mem-parallelkan pengiriman dari sisi aplikasi Anda, itu tidak akan mempercepat pengiriman dan berisiko terhadap kesehatan nomor.
Apakah nomor saya bisa dipakai aplikasi lain, atau sebaliknya?
Tidak. Setiap nomor secara eksplisit di-assign per aplikasi oleh admin. Aplikasi Anda tidak bisa melihat atau memakai nomor yang bukan haknya, walau menyebut kode nomor yang benar.
API key saya hilang, bagaimana?
API key tidak bisa ditampilkan ulang setelah dibuat. Minta admin memutar ulang (rotate) API key aplikasi Anda dari dashboard — key lama otomatis tidak berlaku begitu key baru dibuat.
SmartWA · WhatsApp Gateway · indosmartmedia