NgirimWA Docs
API

Cek Status Pesan

GET /messages — cek apakah pesan terkirim, diterima, dibaca, atau gagal, tanpa harus membuat webhook.

Setiap pesan yang dikirim lewat API mendapat tracking_id di respons kirim. Pakai tracking_id itu — atau ref_id milik Anda sendiri (mis. nomor tagihan) — untuk menanyakan nasib pesannya kapan saja. Webhook tidak wajib. Cocok untuk aplikasi di shared hosting, cron, atau localhost yang tidak bisa menerima webhook.

Baru 9 Oktober 2026. Data status disimpan 30 hari sejak pesan dikirim.

Base URL

https://dash.ngirimwa.com/api/v1

Headers

x-api-key: API_KEY_ANDA

Lingkupnya adalah perangkat milik API key: key perangkat A tidak bisa melihat pesan perangkat B walau satu akun. Cek status tetap bisa dipakai saat langganan sudah habis, agar Anda masih bisa merekonsiliasi pesan yang terkirim sebelumnya. Request ini ikut dihitung dalam rate limit 1.000/jam per API key — pakai mode banyak sekaligus untuk polling.

Siklus status

statusArti
queuedDiterima NgirimWA, menunggu dikirim (mis. perangkat sedang offline — ditahan sampai expires_at)
sentDiterima server WhatsApp (centang 1)
deliveredSampai di HP penerima (centang 2)
readDibaca penerima (centang biru) — hanya bila penerima mengaktifkan laporan dibaca
failedGagal — alasannya di error.code, lihat kode gagal kirim
queued ──► sent ──► delivered ──► read
   │         │
   └─────────┴──► failed

Status tidak pernah mundur. sent belum berarti sampai di HP — bila Anda perlu kepastian, tunggu delivered. Penerima yang HP-nya mati bisa tetap di sent sampai HP menyala lagi.

Selama queued, NgirimWA terus mencoba mengirim sampai expires_at — termasuk bila koneksi perangkat putus tepat saat pesan sedang dikirim. Begitu perangkat tersambung lagi, pesan yang tertahan dikirim bertahap (berjarak ±2,5 detik, bukan serentak) agar nomor Anda aman dari pembatasan WhatsApp.

Apa artinya "perangkat offline"? Nomor WhatsApp Anda terhubung ke NgirimWA sebagai perangkat tertaut (seperti WhatsApp Web), jadi pesan tetap terkirim walau HP Anda mati atau tanpa internet (selama HP tidak offline lebih dari ±14 hari). Pesan baru tertahan bila sesi perangkat di NgirimWA terputus — mis. pemeliharaan/restart server, gangguan jaringan, atau perangkat di-logout dari HP.


Cek satu pesan

GET /messages/{tracking_id}
curl https://dash.ngirimwa.com/api/v1/messages/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1 \
  -H "x-api-key: API_KEY_ANDA"

Respon

{
  "success": true,
  "message": "OK",
  "data": {
    "tracking_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1",
    "ref_id": "INV-2026-0042",
    "status": "delivered",
    "to": "628123456789",
    "type": "text",
    "wa_message_id": "3EB0XYZ789",
    "job_id": "61503",
    "error": null,
    "created_at": "2026-10-09T10:00:00.000Z",
    "expires_at": "2026-10-09T11:00:00.000Z",
    "sent_at": "2026-10-09T10:00:01.120Z",
    "delivered_at": "2026-10-09T10:00:03.540Z",
    "read_at": null,
    "failed_at": null,
    "updated_at": "2026-10-09T10:00:03.540Z"
  }
}

Contoh pesan yang gagal karena perangkat offline melewati expires_in:

{
  "tracking_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1",
  "ref_id": "INV-2026-0042",
  "status": "failed",
  "to": "628123456789",
  "type": "text",
  "wa_message_id": null,
  "error": {
    "code": "expired",
    "message": "Not sent before expires_at (device was offline or the queue was busy)",
    "wa_code": null
  },
  "failed_at": "2026-10-09T11:00:05.000Z"
}

Field

FieldArti
tracking_idID pelacakan dari respons kirim
ref_idref_id yang Anda kirim, atau null
statusqueued · sent · delivered · read · failed
toNomor tujuan (format 628…)
typetext · media · template · interactive · quick_reply · list · carousel · buttons
wa_message_idID pesan WhatsApp (sama dengan message.id di webhook). null bila belum/tidak pernah sampai ke WhatsApp
errornull, atau { code, message, wa_code } bila failed
*_atWaktu (ISO 8601, UTC) setiap tahap; null bila belum terjadi

Tidak ada / lebih dari 30 hari / milik perangkat lain → 404 message_not_found.


Cek banyak pesan sekaligus

GET /messages?tracking_ids={id1},{id2},…

Sampai 100 tracking_id per request (dipisah koma). Urutan hasil mengikuti urutan permintaan; ID yang tidak ditemukan dikembalikan di meta.not_found.

curl "https://dash.ngirimwa.com/api/v1/messages?tracking_ids=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1,xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx2" \
  -H "x-api-key: API_KEY_ANDA"
{
  "success": true,
  "message": "OK",
  "data": [ { "tracking_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx1", "status": "read", "…": "…" } ],
  "meta": { "not_found": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx2"] }
}

Cari berdasarkan ref_id / filter

GET /messages?ref_id={ref_id}&status={status}&since={iso}&until={iso}&limit={n}&cursor={cursor}
QueryKeterangan
ref_idSemua pesan dengan ref_id ini (mis. semua pengingat untuk satu tagihan)
statusqueued · sent · delivered · read · failed
since, untilRentang waktu kirim, ISO 8601 (mis. 2026-10-09T00:00:00+07:00)
limit1–100, default 20
cursorDari meta.next_cursor halaman sebelumnya

Hasil diurutkan terbaru dulu. Bila masih ada halaman berikutnya, meta.next_cursor berisi nilai untuk request berikutnya; null berarti sudah habis.

# Semua pesan untuk tagihan INV-2026-0042
curl "https://dash.ngirimwa.com/api/v1/messages?ref_id=INV-2026-0042" -H "x-api-key: API_KEY_ANDA"

# Pesan yang gagal sejak kemarin
curl "https://dash.ngirimwa.com/api/v1/messages?status=failed&since=2026-10-08T00:00:00%2B07:00&limit=100" \
  -H "x-api-key: API_KEY_ANDA"
{
  "success": true,
  "message": "OK",
  "data": [ { "tracking_id": "…", "ref_id": "INV-2026-0042", "status": "read", "…": "…" } ],
  "meta": { "limit": 20, "next_cursor": "xxxxxxxxxxxxxxxx" }
}

tracking_ids tidak bisa digabung dengan filter lain (400 validation_error).


Saran polling

  • Jangan polling satu per satu tiap detik. Cukup cron tiap 5–15 menit yang mengambil pesan yang masih queued/sent di database Anda, lalu cek sekaligus dengan ?tracking_ids= (100 per request).
  • Berhenti mengecek pesan yang sudah final: delivered, read, atau failed. (sent bisa berubah menjadi delivered berjam-jam kemudian bila HP penerima mati.)
  • Untuk rekap harian cukup satu request: ?status=failed&since=<kemarin>.
  • Butuh status seketika? Pakai webhook — payload-nya membawa tracking_id dan ref_id yang sama.

Contoh alur lengkap (kirim → simpan → cek → tangani gagal): Notifikasi Transaksional.

Melihat di dashboard

Pemilik akun bisa melihat status yang sama tanpa kode di Dashboard → Perangkat → Riwayat Pesan: pesan API tampil bersama kolom ref_id dan Keterangan (tahap terakhir atau alasan gagal). Ketik ref_id (mis. nomor tagihan) di kotak cari, atau klik ref_id pada tabel, untuk melihat semua pesan satu transaksi.

On this page