Penanganan Error
Daftar error yang mungkin muncul dari endpoint API NgirimWA, beserta penyebab dan solusinya.
Daftar error yang mungkin Anda temui dan cara mengatasinya.
Pembaruan 18 September 2026: semua error kini memakai satu amplop
{ success: false, message, details: { code } }. Perubahan yang perlu Anda perhatikan: status perangkat (device_not_connected,device_logged_out) menjadi 409 (sebelumnya 400) dengan pesan Inggris; API key salah selalu 403 (sebelumnya bisa 429 setelah dicache); ada 503auth_unavailablesaat backend autentikasi tidak bisa dihubungi; rate limit dihitung per API key;/contacts/verifymenjawab 503/504 alih-alih 200 dengan semuaexists: false; respons 501 diganti 503session_service_unavailable; path yang tidak dikenal menjawab 404 JSON. Field lamaerror(string JSON) pada respons validasi dan rate limit masih dikirim sebagai alias sampai 31 Oktober 2026, lalu dihapus.
Amplop Error
{
"success": false,
"message": "Deskripsi error (bahasa Inggris)",
"details": { "code": "device_not_connected" }
}Gunakan details.code untuk logika program; message hanya untuk manusia dan bisa berubah. Respons 429/503/504 selalu membawa header Retry-After (detik).
Ringkasan Kode HTTP
| Kode | Arti | Endpoint yang umum trigger |
|---|---|---|
| 400 | Request tidak valid (validasi body, format nomor, media gagal diunduh, API key tanpa perangkat) | semua POST |
| 401 | API Key tidak disertakan | semua |
| 403 | API Key salah / nonaktif / langganan tidak aktif | semua |
| 404 | Resource tidak ditemukan (template) atau path endpoint tidak dikenal | /messages/send-template, path salah |
| 408 | Timeout pembuatan QR | /devices/connect |
| 409 | Status perangkat: tidak terhubung, atau sesi berakhir (perlu scan QR) | kirim (hanya device_logged_out), /groups, /contacts/verify, /messages/reaction, /messages/mark-read, /messages/presence |
| 429 | Kuota bulanan habis, rate limit per API key, atau terlalu banyak auth gagal | semua |
| 500 | Error internal | semua |
| 503 | Layanan autentikasi / sesi perangkat / WhatsApp sementara tidak tersedia — coba lagi | semua (auth_unavailable), /devices/connect, /devices/disconnect, /groups, /contacts/verify |
| 504 | Layanan sesi perangkat / WhatsApp tidak menjawab tepat waktu — coba lagi | /contacts/verify, /devices/*, /groups |
Tabel Kode details.code
details.code | HTTP | Arti | Retry? |
|---|---|---|---|
api_key_missing | 401 | Header x-api-key tidak ada | ❌ perbaiki request |
invalid_api_key | 403 | API key tidak dikenal | ❌ |
api_key_inactive | 403 | API key dinonaktifkan di dashboard | ❌ |
subscription_inactive | 403 | Langganan pemilik key tidak aktif (details.status: expired, dll) | ❌ perpanjang langganan |
auth_blocked | 429 | Terlalu banyak auth gagal (5/key atau 20/IP dalam 10 menit) — blokir 30 menit | ⏳ setelah Retry-After |
auth_unavailable | 503 | Backend autentikasi sementara tidak bisa dihubungi — bukan salah key Anda | ✅ setelah Retry-After (5 dtk) |
rate_limited | 429 | Lebih dari 1.000 request/jam untuk API key ini | ⏳ setelah Retry-After |
quota_exceeded | 429 | Kuota pesan bulanan habis; Retry-After = detik sampai tanggal 1 bulan depan | ❌ upgrade / tunggu reset |
validation_error | 400 | Body tidak valid; rincian di details.errors[] | ❌ perbaiki request |
media_download_failed | 400 | URL media tidak bisa diunduh; details.upstream_status bila host menjawab HTTP error | ❌ perbaiki URL |
template_not_found | 404 | template_id tidak ada / sudah dihapus | ❌ |
not_found | 404 | Path endpoint tidak dikenal | ❌ periksa URL |
device_not_connected | 409 | Perangkat tidak punya sesi WhatsApp aktif saat ini | ⏳ cek /devices/status |
device_logged_out | 409 | Sesi WhatsApp berakhir (logout dari HP / diblokir / pairing gagal) — perlu scan QR | ❌ hubungkan ulang |
session_service_unavailable | 503 | Layanan sesi perangkat sedang restart / tidak bisa dijangkau | ✅ beberapa detik |
verify_unavailable | 503 | WhatsApp tidak mengembalikan hasil verifikasi nomor | ✅ beberapa detik |
verify_timeout | 504 | WhatsApp tidak menjawab verifikasi dalam 15 detik | ✅ beberapa detik |
internal_error | 500 | Kesalahan tak terduga di sisi kami | ✅ sekali, lalu hubungi support |
Detail per error di bawah.
API Key Tidak Disertakan
{
"success": false,
"message": "API Key is required",
"details": { "code": "api_key_missing" }
}Status Code: 401
Solusi: pastikan header x-api-key ada di request. Kegagalan ini dihitung terhadap proteksi auth (lihat di bawah) — jangan biarkan job berulang tanpa header.
API Key Tidak Valid / Langganan Tidak Aktif
Respon (salah satu)
{ "success": false, "message": "Invalid API Key", "details": { "code": "invalid_api_key" } }
{ "success": false, "message": "API Key is inactive", "details": { "code": "api_key_inactive" } }
{ "success": false, "message": "Your subscription has expired. Please renew your subscription to continue using the API.", "details": { "code": "subscription_inactive", "status": "expired" } }
{ "success": false, "message": "Your subscription is not active. Please renew your subscription to continue using the API.", "details": { "code": "subscription_inactive", "status": "inactive" } }Status Code: 403
Penyebab:
- API Key salah atau sudah dinonaktifkan di dashboard
- Langganan akun pemilik API Key kedaluwarsa / belum aktif
Solusi:
- Periksa API Key di dashboard
- Perpanjang langganan
API key yang salah selalu dijawab 403, berapa kali pun diulang. Setelah 5 kegagalan (key salah/nonaktif atau header hilang) dalam 10 menit untuk key yang sama — atau 20 kegagalan dari IP klien yang sama — request berikutnya dijawab 429
auth_blockedselama 30 menit. Langganan yang tidak aktif tidak dihitung sebagai kegagalan auth. Jangan retry otomatis pada 401/403.
Terlalu Banyak Auth Gagal
{
"success": false,
"message": "Too many failed requests. Please try again later.",
"details": { "code": "auth_blocked", "retry_after": 1734 }
}Status Code: 429 (+ header Retry-After)
Solusi: hentikan job yang memakai key/header salah, tunggu Retry-After detik, lalu lanjutkan dengan key yang benar.
Layanan Autentikasi Sementara Tidak Tersedia
{
"success": false,
"message": "Authentication service is temporarily unavailable. Please retry in a few seconds.",
"details": { "code": "auth_unavailable", "retry_after": 5 }
}Status Code: 503 (+ Retry-After: 5)
Penyebab: backend kami tidak bisa memverifikasi API key karena database autentikasi sementara tidak bisa dihubungi. Bukan berarti key Anda salah, dan tidak dihitung sebagai kegagalan auth.
Solusi: ulangi request setelah beberapa detik (back-off). Aman untuk di-retry dengan Idempotency-Key yang sama.
API Key Tidak Terhubung ke Perangkat
{
"success": false,
"message": "API Key does not have an associated device"
}Status Code: 400
Solusi: buat API Key baru dan pilih perangkat, atau pasangkan perangkat pada API Key di dashboard.
Kuota Pesan Habis
Respon:
{
"success": false,
"message": "Monthly message quota has been exceeded. Please upgrade your plan or purchase additional quota to continue sending messages.",
"details": { "code": "quota_exceeded" }
}Status Code: 429 (+ Retry-After = detik sampai tanggal 1 bulan depan)
Penyebab:
- Kuota bulanan habis
Solusi:
- Upgrade paket langganan atau beli kuota tambahan
- Tunggu reset kuota bulan depan (tanggal 1)
Berlaku untuk semua endpoint kirim termasuk
/messages/reaction./messages/mark-read,/messages/presence, dan/contacts/verifytidak memakai kuota.Bila sistem kami sementara tidak bisa membaca kuota Anda (gangguan database), request tetap diproses — Anda tidak akan ditolak karena gangguan di sisi kami.
Perangkat Tidak Terhubung
Respon:
{
"success": false,
"message": "WhatsApp device is not connected",
"details": { "code": "device_not_connected" }
}Status Code: 409
Endpoint yang menjawab ini: GET /groups, POST /contacts/verify, POST /messages/reaction, POST /messages/mark-read, POST /messages/presence — operasi yang memerlukan socket WhatsApp hidup saat itu juga.
Endpoint kirim (/messages/send, /send-template, /quick-reply, /interactive, /buttons, /list, /carousel) tidak menjawab error ini. Pesan diproses lewat antrean: bila perangkat hanya terputus sesaat (gangguan singkat / restart), request tetap diterima (200, data.status: "queued") dan dikirim saat koneksi pulih — hasil akhirnya dilaporkan lewat webhook message.sent / message.failed.
Penyebab:
- Koneksi perangkat sedang terputus (gangguan singkat / restart)
Solusi:
- Cek
/devices/status; bilaconnecting, tunggu beberapa detik dan coba lagi - Bila
disconnected, hubungkan perangkat via dashboard atau/devices/connect
Sesi Perangkat Berakhir
{
"success": false,
"message": "WhatsApp session for this device has ended. Re-link the device by scanning the QR code.",
"details": { "code": "device_logged_out" }
}Status Code: 409
Endpoint yang menjawab ini: semua endpoint kirim (ditolak di depan karena tidak mungkin terkirim) dan endpoint lain yang memerlukan sesi.
Penyebab: perangkat logout dari HP, diblokir WhatsApp, atau pairing tidak selesai. Tidak akan pulih sendiri.
Solusi: scan QR ulang via dashboard atau /devices/connect.
Format Nomor Tidak Valid
Respon
{ "success": false, "message": "Invalid phone number format: too short", "details": { "code": "validation_error" } }
{ "success": false, "message": "Invalid phone number format: too long", "details": { "code": "validation_error" } }Status Code: 400
Penyebab:
- Nomor kurang dari 8 atau lebih dari 15 digit setelah karakter non-digit dibuang
Solusi:
- Gunakan format:
628123456789,08123456789,8123456789, atau nomor internasional lengkap dengan kode negara (14155551234). Aturan ini sama di semua endpoint, termasuk/contacts/verify.
Validasi Body Gagal
{
"success": false,
"message": "Validation Error",
"details": {
"code": "validation_error",
"errors": [{ "field": "body.to", "message": "Required" }]
},
"error": "[{\"field\":\"body.to\",\"message\":\"Required\"}]"
}Status Code: 400
Gunakan details.errors (array { field, message }). Field error berisi string JSON yang sama — deprecated, masih dikirim sampai 31 Oktober 2026 untuk klien lama yang memakai JSON.parse(body.error).
Media Tidak Bisa Diunduh
{
"success": false,
"message": "Failed to download media from URL: the media host answered HTTP 404",
"details": { "code": "media_download_failed", "upstream_status": 404 }
}Status Code: 400
Penyebab: URL media tidak bisa diakses dari server kami — host menjawab error (details.upstream_status), tidak dapat dijangkau, atau timeout (30 detik).
Solusi: pastikan URL publik (HTTPS), tidak butuh login, dan merespons cepat; atau kirim media sebagai data-URI base64.
Template Tidak Ditemukan
Respon
{
"success": false,
"message": "Template not found",
"details": { "code": "template_not_found" }
}Status Code: 404
Penyebab:
- Template ID salah
- Template sudah dihapus
Solusi:
- Periksa template ID di dashboard
- Buat template baru jika diperlukan
Endpoint Tidak Dikenal
{
"success": false,
"message": "Endpoint not found: POST /api/v1/messages/sned",
"details": { "code": "not_found" }
}Status Code: 404
Solusi: periksa method dan path. Semua path yang tidak dikenal di bawah /api dijawab JSON seperti di atas (bukan halaman HTML).
Rate Limit Terlampaui
Respon
{
"success": false,
"message": "Too many requests, please try again later.",
"details": { "code": "rate_limited" },
"error": "Too many requests, please try again later."
}Status Code: 429 (+ Retry-After)
Penyebab:
- Lebih dari 1.000 request per jam untuk API key yang sama (request tanpa
x-api-keydihitung per IP klien)
Solusi:
- Tunggu reset window (lihat header
RateLimit-Reset/Retry-After) - Kurangi frekuensi request
- Implementasikan queue / debounce untuk pengiriman massal
- Bila sistem yang berbeda memang butuh kuota terpisah, buat API key terpisah per sistem
Field
errordi respons ini deprecated (dihapus setelah 31 Oktober 2026) — pakaimessage+details.code.
Layanan Sesi Perangkat Tidak Tersedia
{
"success": false,
"message": "Device session service is temporarily unavailable. Please retry shortly.",
"details": { "code": "session_service_unavailable" }
}Status Code: 503 (+ Retry-After)
Muncul di /devices/connect, /devices/disconnect, /groups, /contacts/verify saat layanan sesi perangkat sedang restart atau tidak bisa dijangkau. Varian 504 Device session service timed out. Please retry. berarti layanan ada tetapi tidak menjawab tepat waktu. Keduanya aman di-retry setelah beberapa detik.
Verifikasi Nomor Gagal
{ "success": false, "message": "WhatsApp did not return verification results. Please retry.", "details": { "code": "verify_unavailable" } }
{ "success": false, "message": "Timed out verifying numbers with WhatsApp. Please retry.", "details": { "code": "verify_timeout" } }Status Code: 503 / 504 (+ Retry-After)
Khusus POST /contacts/verify. Sebelumnya kondisi ini dijawab 200 dengan semua nomor exists: false (false negative) — sekarang dijawab error supaya Anda tidak menghapus kontak yang sebenarnya valid. Ulangi request beberapa detik kemudian.
Tips Penanganan Error
try {
const res = await axios.post(url, body, { headers });
console.log(res.data.data.status); // "queued" — hasil akhir lewat webhook
} catch (error) {
const status = error.response?.status;
const code = error.response?.data?.details?.code;
const retryAfter = Number(error.response?.headers?.['retry-after'] || 5);
if (code === 'auth_unavailable' || code === 'session_service_unavailable' ||
code === 'verify_unavailable' || code === 'verify_timeout') {
await sleep(retryAfter * 1000); // aman di-retry dengan Idempotency-Key yang sama
} else if (code === 'rate_limited' || code === 'auth_blocked') {
await sleep(retryAfter * 1000);
} else if (code === 'quota_exceeded') {
console.log('Kuota bulan ini habis — upgrade atau tunggu tanggal 1');
} else if (code === 'device_logged_out') {
console.log('Perangkat perlu scan QR ulang');
} else if (code === 'device_not_connected') {
console.log('Perangkat sedang offline — cek /devices/status');
} else if (status === 400) {
console.log('Periksa format data Anda', error.response.data.details?.errors);
} else if (status === 401 || status === 403) {
console.log('API Key / langganan bermasalah — jangan retry otomatis');
}
}