Lewati ke konten utama

Dokumentasi Bulk Template Message API — v2

API ini memungkinkan Anda mengirim pesan template ke banyak penerima sekaligus melalui saluran WhatsApp.

Pengiriman pesan diproses secara asinkron; permintaan API langsung mengembalikan bulkOperationId, sementara pesan diantrekan dan diproses di latar belakang.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js
Format respons

Setiap endpoint dalam dokumen ini adalah custom function. Isi respons HTTP memuat kolom milik function itu sendiri (_id, title, pathString…) dan respons sebenarnya dari endpoint di bawah result. Contoh respons dalam dokumen ini menampilkan isi result:

{
"_id": "function_id",
"title": "Show",
"pathString": "/bulk-message-api-app/api/v2/bulk-operation/show.js",
"result": {
"bulkOperation": { "_id": "abc123xyz789", "status": "running" }
}
}

Migrasi dari v1​

v2 berjalan berdampingan dengan v1, sehingga Anda dapat bermigrasi sesuai jadwal Anda sendiri. Endpoint v1 (/api/bulk-message/…, /api/bulk-message-records/…) akan dihentikan; integrasi baru sebaiknya menggunakan v2.

  1. Pindahkan path endpoint ke v2: …/api/bulk-message/… menjadi …/api/v2/bulk-operation/…, dan …/api/bulk-message-records/… menjadi …/api/v2/bulk-operation-items/…. Isi permintaan send tidak berubah; satu permintaan kini menerima hingga 100.000 penerima, bukan 5.000.
  2. Kirim bulkOperationId alih-alih bulkMessageId dalam permintaan.
  3. Ganti stats.js dengan show.js.
  4. Baca respons dengan nama kolom baru pada tabel di bawah.

Endpoint v2 hanya mengenali operasi massal yang dibuat dengan send v2. Untuk melacak pesan massal yang dibuat dengan v1 sebelum Anda beralih, tetap gunakan endpoint v1 untuk pesan tersebut.

Endpoint​

v1v2Apa yang berubah dalam respons
bulk-message/send.jsv2/bulk-operation/send.js{ bulkMessageId } menjadi { bulkOperationId }
bulk-message/stats.jsv2/bulk-operation/show.js{ bulkMessage, stats } menjadi { bulkOperation }
bulk-message/message-stats.jsv2/bulk-operation/message-stats.jsPenghitung berada di root, bukan di bawah messageStats
bulk-message/stop.jsv2/bulk-operation/stop.jsTidak ada
bulk-message-records/list.jsv2/bulk-operation-items/list.jsbulkMessageRecords menjadi bulkOperationItems
bulk-message-records/list-with-messages.jsv2/bulk-operation-items/list-with-messages.jsSama seperti list, dan setiap item juga membawa session

Nama kolom​

v1v2
stats.successbulkOperation.progress.succeeded
stats.pending, stats.failed, stats.cancelled, stats.totalbulkOperation.progress.pending, .failed, .cancelled, .total
—bulkOperation.progress.unknown, bulkOperation.status, bulkOperation.result.outcome
bulkMessage (pesan massal)bulkOperation (operasi massal)
bulkMessageRecord (catatan)bulkOperationItem (item)
bulkMessageId dalam permintaan, dalam respons send, dan pada catatanbulkOperationId
username / userId / sessionId catatan sebagaimana dikirimpayload.username / payload.userId / payload.sessionId
referenceId catatanpayload.referenceId
payload catatan (payload template penerima)payload.payload
userId, sessionId, messageId catatan setelah pengirimanresult.userId, result.sessionId, result.messageId
status catatan successsucceeded
errorMessage catatan pada catatan yang gagalerror.message, berdampingan dengan error.code dan error.retryable
—position (indeks penerima dalam recipients)
filter {"status": "success"}{"status": "succeeded"}
filter {"referenceId": "…"}{"payload.referenceId": "…"}
error send schema-error, invalidRequestzod-schema-error, dengan path kolom yang tidak valid di dalam pesan

Fitur utama​

  • Kirim pesan template massal ke 1–100.000 penerima dalam satu permintaan
  • Variabel yang dipersonalisasi untuk setiap penerima (HEADER, BODY, BUTTONS, CAROUSEL)
  • defaultPayload bersama untuk semua penerima dengan penggabungan payload khusus penerima (isMerge)
  • Pengiriman terjadwal (scheduleAt)
  • Tentukan penerima menggunakan username (nomor telepon), userId, atau sessionId
  • Kirim beberapa pesan ke pengguna yang sama dalam satu permintaan massal
  • referenceId opsional untuk melacak catatan dengan sistem eksternal
  • Tugaskan percakapan secara otomatis ke pengguna atau grup kerja setelah pengiriman (action)
peringatan

API ini hanya dapat mengirim template yang telah disetujui Meta.

Nama template dan kode bahasa harus persis sama dengan template yang terdaftar di Meta Business Manager.

Parameter permintaan​

Parameter tingkat atas​

ParameterTipeWajibDeskripsi
channelUsernamestringYaNomor saluran WhatsApp yang digunakan untuk mengirim pesan (misalnya "908506669933")
connectorBrandstringYaMerek konektor saluran. Nilai yang saat ini didukung: "whatsapp"
titlestringTidakJudul kampanye. Digunakan untuk tampilan di dasbor. Default: "-"
scheduleAtstring (ISO 8601)TidakTanggal dan waktu pengiriman terjadwal (misalnya "2026-06-10T10:00:00.000Z"). Jika dihilangkan, pesan dikirim segera.
defaultPayloadobjectBersyarat*Payload template default yang berlaku untuk semua penerima. Wajib jika penerima tidak menyediakan payload sendiri.
recipientsarrayYaDaftar penerima. Minimum 1, maksimum 100.000 penerima.
actionobjectTidakTindakan yang diterapkan pada percakapan setelah pengiriman. assign-to-user atau assign-to-workgroup.

*Jika setiap penerima menyediakan payload sendiri, defaultPayload bersifat opsional.

Struktur penerima​

Untuk setiap penerima, tepat satu dari username, userId, atau sessionId harus diberikan. Beberapa pengenal tidak dapat digunakan bersamaan, dan jika semuanya dihilangkan akan terjadi error.

Untuk mengirim beberapa pesan ke pengguna yang sama dalam satu permintaan massal, tambahkan pengenal yang sama ke daftar penerima beberapa kali.

KolomTipeDeskripsi
usernamestringNomor telepon penerima (misalnya "905554443322"). Jika pengguna belum ada di sistem, pengguna dibuat otomatis.
userIdstringID pengguna yang sudah ada di sistem.
sessionIdstringID sesi percakapan yang sudah ada di sistem.
referenceIdstringReference ID opsional (maks. 256 karakter) untuk mencocokkan dengan catatan sistem eksternal (CRM, pesanan, tiket, dll.). Harus unik di dalam satu operasi massal jika diberikan.
payloadobjectPayload template khusus penerima (opsional). Jika isMerge: true, payload digabungkan dengan defaultPayload.
isMergebooleanMenggantikan perilaku penggabungan untuk penerima ini (opsional). Jika dihilangkan, defaultPayload.isMerge digunakan.

Struktur action​

KolomTipeDeskripsi
action.keystring"assign-to-user" menugaskan percakapan ke agen tertentu; "assign-to-workgroup" menugaskannya ke grup kerja.
action.valuestringID pengguna atau grup kerja tujuan.

Struktur payload template​

defaultPayload dan payload khusus penerima memiliki struktur yang sama. Untuk pesan template, type: "template" harus ditentukan.

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
KolomTipeWajibDeskripsi
typestringYaTipe payload. Untuk pesan template: "template"
template.templateNamestringYa*Nama template yang terdaftar di Meta. Opsional pada payload penerima saat isMerge: true digunakan (diwarisi dari default).
template.languageCodestringTidakKode bahasa template (misalnya "tr", "en", "tr-TR", "en-US"). Harus persis sama dengan bahasa yang terdaftar di Meta.
template.variablesarrayTidakDaftar variabel yang diterapkan pada komponen template. Dijelaskan di bawah.
isMergebooleanTidaktrue: payload penerima digabungkan secara mendalam dengan defaultPayload. false atau dihilangkan: payload penerima sepenuhnya menggantikan defaultPayload.
Perilaku isMerge
  • Jika defaultPayload.isMerge: true dan penerima menyediakan payload sendiri, penggabungan mendalam (deep merge) diterapkan.
  • Dengan deep merge, penerima cukup menyediakan variables; templateName dan languageCode diwarisi dari payload default.
  • Kolom isMerge penerima menggantikan defaultPayload.isMerge.
  • Jika penerima tidak menyediakan payload, defaultPayload selalu digunakan.

Struktur variabel​

Setiap item dalam array variables sesuai dengan satu komponen template. Satu jenis komponen (type) hanya boleh muncul sekali dalam array.

typeDeskripsiparameterscards
"HEADER"Komponen header template. Variabel teks atau URL media (gambar, video, dokumen)Ya—
"BODY"Variabel teks body templateYa—
"BUTTONS"Variabel akhiran URL dinamis untuk tombolYa—
"CAROUSEL"Komponen kartu untuk template carousel—Ya

Format parameter​

Kolom parameters dapat diberikan dalam tiga format berbeda:

// Format 1: Array (berbasis indeks) — untuk placeholder seperti {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]

// Format 2: Objek (kunci numerik) — representasi alternatif untuk {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }

// Format 3: Objek (kunci bernama) — untuk placeholder seperti {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
Format mana yang sebaiknya saya pakai?
  • Jika template Meta Anda menggunakan placeholder seperti {{1}}, {{2}}, gunakan format array atau format objek dengan kunci numerik.
  • Jika template Anda menggunakan placeholder bernama seperti {{firstName}} atau {{orderTotal}}, gunakan format objek dengan kunci bernama.
  • Saat menggunakan array, urutan berpengaruh: elemen pertama untuk {{1}}, elemen kedua untuk {{2}}, dan seterusnya.

Komponen HEADER​

Gunakan komponen HEADER saat header template berisi media (gambar, video, dokumen) atau teks dinamis.

// Header media (URL gambar)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}

// Variabel header teks
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}

Komponen BODY​

Digunakan untuk variabel teks dinamis di dalam body template.

// Format array — jika template menggunakan {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}

// Format bernama — jika template menggunakan {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}

Komponen BUTTONS​

Digunakan untuk tombol dengan akhiran URL dinamis. Jika template berisi beberapa tombol URL, hanya tombol yang memiliki variabel yang diindeks secara berurutan (tombol tanpa variabel atau tombol FLOW diabaikan).

// Variabel akhiran untuk satu tombol URL
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}

// Variabel akhiran untuk beberapa tombol URL (tombol URL pertama, tombol URL kedua)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}

Untuk template carousel, variabel komponen ditentukan secara terpisah untuk setiap kartu.

{
"type": "CAROUSEL",
"cards": [
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card1.jpg"]
},
{
"type": "BODY",
"parameters": ["Product A", "99.00 USD"]
}
]
},
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card2.jpg"]
},
{
"type": "BODY",
"parameters": ["Product B", "149.00 USD"]
}
]
}
]
}
peringatan

Panjang array cards harus persis sama dengan jumlah kartu yang ditentukan di template.

Contoh​

1. Template sederhana — tanpa variabel, isi sama untuk semua penerima​

Ini cara paling sederhana untuk mengirim template statis tanpa variabel ke banyak penerima.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }, { "username": "905554443303" }]
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [
{ "username": "905554443301" },
{ "username": "905554443302" },
{ "username": "905554443303" }
]
}'
tips
  • Penerima yang ditentukan lewat username dibuat otomatis jika belum ada di sistem
  • Semua penerima menggunakan defaultPayload yang sama; tidak diperlukan data khusus penerima
  • Jika isMerge tidak ditentukan, setiap penerima langsung menggunakan defaultPayload

2. Template dengan variabel body bersama​

Template yang sama dikirim ke semua penerima dengan nilai variabel yang identik. Template berisi placeholder seperti {{1}} dan {{2}}.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Summer Campaign",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "promo_notification",
"languageCode": "tr-TR",
"variables": [
{
"type": "BODY",
"parameters": ["30%", "July 31, 2026"]
}
]
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }]
}
tips
  • Pada contoh ini, body template dapat berisi teks seperti: "Nikmati diskon {{1}} di kampanye kami! Penawaran berlaku hingga {{2}}."
  • parameters[0] menggantikan {{1}}, sedangkan parameters[1] menggantikan {{2}}

3. Template yang dipersonalisasi — variabel per penerima dengan isMerge​

Nilai variabel yang berbeda digunakan untuk setiap penerima. Dengan menetapkan isMerge: true pada defaultPayload, penerima hanya perlu menyediakan variables; templateName dan languageCode diwarisi dari payload default.

Pada contoh ini, template memiliki header media sekaligus variabel body yang dipersonalisasi.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Personal Order Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-a.jpg"]
},
{
"type": "BODY",
"parameters": ["Ahmet", "ORD-001", "150.00 TRY"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-b.jpg"]
},
{
"type": "BODY",
"parameters": ["Fatma", "ORD-002", "289.00 TRY"]
}
]
}
}
}
]
}
tips
  • Berkat isMerge: true, templateName tidak perlu diulang di setiap payload penerima
  • Array variables setiap penerima sepenuhnya independen
  • URL media header harus dapat diakses publik
  • Jika type dihilangkan pada payload penerima, defaultPayload.type diwarisi

4. Variabel tombol URL​

Gunakan komponen BUTTONS saat template berisi tombol dengan akhiran URL dinamis. Misalnya, nomor pelacakan yang ditambahkan ke URL dasar https://example.com/track/.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Shipment Tracking Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "shipment_tracking",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Ahmet", "TK-98765"]
},
{
"type": "BUTTONS",
"parameters": ["TK-98765"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Recep", "TK-12345"]
},
{
"type": "BUTTONS",
"parameters": ["TK-12345"]
}
]
}
}
}
]
}
tips
  • Parameter BUTTONS dicocokkan menurut urutan tombol yang memiliki variabel
  • Tombol FLOW dan tombol tanpa variabel diabaikan; pengindeksan hanya berlaku untuk tombol URL dinamis
  • Jika URL tombol template adalah https://example.com/track/{{1}}, maka parameters[0] menggantikan {{1}}

5. Pengiriman terjadwal​

Jadwalkan pesan untuk dikirim pada tanggal dan waktu mendatang. scheduleAt harus diberikan sebagai stempel waktu UTC ISO 8601.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Morning Campaign Message",
"scheduleAt": "2026-06-10T07:00:00.000Z",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "morning_campaign",
"languageCode": "en-US"
},
"isMerge": true
},
"action": {
"key": "assign-to-workgroup",
"value": "WORKGROUP_ID"
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Ahmet", "discountRate": "25" }
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Zeynep", "discountRate": "40" }
}
]
}
}
}
]
}
tips
  • scheduleAt harus diberikan dalam zona waktu UTC (misalnya, untuk pukul 10.00 waktu Turki, gunakan 07:00:00.000Z)
  • Contoh ini menggunakan format parameter bernama; template harus berisi placeholder seperti {{name}} dan {{discountRate}}
  • Dengan action, percakapan yang dibuat oleh pengiriman pesan otomatis ditugaskan ke grup kerja yang ditentukan

Respons​

Permintaan yang berhasil mengembalikan bulkOperationId, yang dapat digunakan untuk melacak proses pengiriman:

{
"bulkOperationId": "abc123xyz789"
}

Respons error​

StatusDeskripsi
recipients field is requiredKolom recipients tidak dikirim
Channel not foundTidak ditemukan saluran terverifikasi yang cocok dengan channelUsername dan connectorBrand
Channel is not verifiedSaluran yang cocok ada tetapi belum terverifikasi
zod-schema-errorSebuah kolom di isi permintaan gagal validasi skema (kolom wajib tidak ada, tipe salah, nilai tidak didukung, lebih dari satu pengenal pada satu penerima, atau payload tidak ada). Pesan menyebutkan nama kolomnya, misalnya recipients.0.referenceId: referenceId must be unique

bulkOperationId yang dikembalikan dapat digunakan dengan endpoint di bawah ini untuk melihat statistik pengiriman dan menghentikan proses pengiriman.


Show — Status dan statistik operasi massal​

Mengambil operasi massal beserta status terkininya dan penghitung pengiriman item-itemnya, di bawah kunci bulkOperation.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js

Parameter permintaan​

ParameterTipeWajibDeskripsi
bulkOperationIdstringYaID operasi massal yang dilacak (dikembalikan dari send)
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'

Respons​

{
"bulkOperation": {
"_id": "abc123xyz789",
"type": "send-bulk-message",
"slug": "my-workspace",
"userId": "agent_user_id",
"payload": {
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "om2WabVegaCloud",
"defaultLanguageCode": "tr-TR",
"sentUser": { "firstname": "John", "lastname": "Doe" },
"defaultPayload": {
"type": "template",
"template": { "templateName": "order_confirmation", "languageCode": "tr-TR" },
"isMerge": true
},
"source": { "type": "recipients", "bulkOperationInputGroupId": "group_id" }
},
"status": "running",
"result": { "outcome": "unknown", "hasErrors": false },
"progress": {
"total": 100,
"pending": 45,
"succeeded": 42,
"failed": 3,
"cancelled": 10,
"unknown": 0
},
"scheduleAt": "2026-06-10T07:00:00.000Z",
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-10T07:00:30.000Z",
"startedAt": "2026-06-10T07:00:05.000Z"
}
}

Kolom show​

Kolom-kolom ini berada di bawah bulkOperation.

KolomTipeDeskripsi
statusstringStatus operasi massal: preparing, scheduled, pending, running, stopping, stopped, completed, failed
progress.totalnumberJumlah total item
progress.pendingnumberItem yang masih menunggu dalam antrean
progress.succeedednumberItem yang berhasil diproses untuk pengiriman
progress.failednumberItem yang mengalami error pengiriman
progress.cancellednumberItem yang dibatalkan oleh stop
progress.unknownnumberItem yang hasilnya tidak dapat ditentukan
result.outcomestringHasil akhir setelah operasi massal selesai: success, partial, all-failed, cancelled, unknown
result.hasErrorsbooleantrue jika setidaknya satu item gagal
scheduleAtstringWaktu pengiriman terjadwal (hanya untuk operasi massal terjadwal)
startedAt, completedAtstringKapan pengiriman dimulai dan selesai
catatan

progress.succeeded menunjukkan bahwa pesan berhasil diserahkan oleh sistem. Ini tidak menjamin bahwa Meta menyampaikan pesan ke penerima. Pembaruan status berikutnya dari Meta (seperti delivered, read, atau failed) tidak memengaruhi penghitung ini dan tidak tercermin di sini.

Show vs Message Stats
  • Endpoint show: Menampilkan status pengiriman item (pending, succeeded, failed, cancelled, unknown)
  • Endpoint message-stats: Menampilkan status pesan sebenarnya (pending, sending, sent, delivered, read, error, dll.)
  • Sebuah item bisa succeeded, tetapi pesannya mungkin belum terkirim/terbaca

Reference ID​

referenceId adalah kolom opsional yang dapat Anda gunakan untuk mencocokkan item pengiriman dengan ID dari sistem Anda sendiri untuk keperluan pelacakan (misalnya nomor pesanan, ID tiket). Nilai ini dikembalikan pada setiap item sebagai payload.referenceId.

Jika diberikan, nilainya harus unik di dalam satu operasi massal (maksimal 256 karakter).

Penting
  • Tidak wajib digunakan
  • Tidak boleh duplikat dalam operasi massal yang sama
  • Dapat dipakai ulang di operasi massal yang berbeda

Message Stats — Status pesan WhatsApp​

Mengambil statistik status pesan dari sebuah operasi massal. Berbeda dengan endpoint show, endpoint ini menampilkan message.status sebenarnya dari pesan yang dikirim, bukan status item.

Status pesan yang mungkin: pending, sending, sent, delivered, read, deleted, warning, error, unknown, not-sended

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/message-stats.js

Parameter permintaan​

ParameterTipeWajibDeskripsi
bulkOperationIdstringYaID operasi massal yang di-query
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'

Respons​

{
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 20,
"total": 120
}

Kolom message stats​

KolomTipeDeskripsi
pendingnumberPesan yang belum dikirim
sendingnumberPesan yang sedang dikirim
sentnumberPesan yang sudah diserahkan ke WhatsApp, belum terkirim
deliverednumberPesan yang terkirim ke ponsel penerima
readnumberPesan yang dibaca penerima
deletednumberPesan yang dihapus
warningnumberPesan dengan peringatan
errornumberPesan dengan error
unknownnumberPesan dengan status tidak diketahui
not-sendednumberPesan yang tidak dapat dikirim
no-messagenumberItem tanpa pesan (masih dalam antrean, gagal, atau dibatalkan)
totalnumberJumlah total item
Tips penggunaan
  • Jumlah no-message yang tinggi saat operasi massal berstatus running menunjukkan pengiriman masih berlangsung
  • Jumlah delivered menunjukkan pesan berhasil terkirim
  • Jumlah read dapat digunakan untuk mengukur keterlibatan kampanye
  • Anda dapat memanggil endpoint ini secara berkala untuk pelacakan real-time

Struktur options — penomoran halaman, pemfilteran, dan pengurutan​

Parameter options yang digunakan pada endpoint list dan list-with-messages menyediakan struktur standar untuk penomoran halaman, pemfilteran, dan pengurutan.

Kolom options​

KolomTipeWajibDeskripsi
paginationobjectTidakPengaturan penomoran halaman
filteringobjectTidakKriteria pemfilteran
sortingobjectTidakPengaturan pengurutan (misalnya {"position": 1})

Struktur pagination​

Jika pagination tidak dikirim, halaman pertama dikembalikan dengan maksimal 50 item. Jika dikirim, currentPage wajib diisi.

KolomTipeDefaultDeskripsi
currentPagenumber—Nomor halaman yang diambil (wajib saat pagination dikirim)
pageItemsnumber50Jumlah item per halaman (maksimum: 50)

Struktur filtering​

Pemfilteran menggunakan format query MongoDB pada kolom item, dengan nama kolom persis seperti yang muncul dalam respons (misalnya status, payload.referenceId, result.messageId). Pada endpoint list-with-messages, Anda juga dapat memfilter berdasarkan kolom pesan (misalnya message.status).

// Filter berdasarkan status item
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}

// Filter berdasarkan referenceId
{
"options": {
"filtering": {
"payload.referenceId": "ORDER-12345"
}
}
}

// Filter berdasarkan status pesan (hanya list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}

// Filter berdasarkan beberapa status dengan $in (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}

// Kecualikan status tertentu dengan $nin (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}

// Tampilkan item yang tidak memiliki pesan (hanya list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}

Struktur sorting​

Pengurutan menggunakan format sort MongoDB. 1 berarti menaik, -1 berarti menurun. position adalah urutan penerima dalam array recipients pada permintaan (dimulai dari 0).

// Urutkan sesuai urutan penerima dikirim dalam permintaan
{
"options": {
"sorting": {
"position": 1
}
}
}

// Urutkan berdasarkan beberapa kolom
{
"options": {
"sorting": {
"status": 1,
"position": 1
}
}
}

Contoh penggunaan gabungan​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"position": 1
}
}
}

Contoh ini menampilkan halaman kedua dari pesan yang terkirim, sesuai urutan penerima.

Tips praktis
  • Gabungkan filtering dan pagination untuk query yang terarah
  • Respons menyertakan options.pagination.totalCount dan options.pagination.totalPages untuk navigasi
  • Filter message.status hanya berfungsi pada endpoint list-with-messages

Items — Detail dan daftar item​

Menampilkan semua item pengiriman dari sebuah operasi massal. Setiap item mewakili satu entri dalam array recipients.

List — Daftar item​

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list.js

Parameter permintaan​

ParameterTipeWajibDeskripsi
bulkOperationIdstringYaID operasi massal yang ditampilkan
optionsobjectTidakOpsi penomoran halaman, pemfilteran, dan pengurutan. Lihat Struktur options untuk detailnya.

Permintaan — penggunaan dasar​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}

Permintaan — filter berdasarkan status tertentu​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "failed"
}
}
}

Hanya menampilkan item pengiriman yang gagal, dengan alasannya di error.

Respons​

{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 0,
"payload": {
"username": "905554443301",
"referenceId": "ORDER-12345",
"payload": {
"template": {
"variables": [{ "type": "BODY", "parameters": ["Ahmet", "ORD-001"] }]
}
}
},
"status": "succeeded",
"attempt": 1,
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
},
{
"_id": "item_2",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 1,
"payload": { "username": "905554443302", "referenceId": "ORDER-12346" },
"status": "failed",
"attempt": 1,
"error": { "code": "error", "message": "Variable missing", "retryable": false },
"result": { "userId": "user_124", "sessionId": "session_457" },
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}

List With Messages — Daftar dengan detail pesan​

Memiliki fitur yang sama dengan endpoint list (penomoran halaman, pemfilteran, pengurutan). Perbedaannya: setiap item juga membawa objek message dan session terkait jika ada. Dengan begitu Anda dapat melihat status pesan (delivered, read, error, dll.) dan payload dalam satu query.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list-with-messages.js

Permintaan — penggunaan dasar​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}

Permintaan — filter berdasarkan status pesan​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}

Contoh ini hanya mengambil pesan dengan status "delivered".

Permintaan — daftar pesan yang gagal​

{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}

Digunakan untuk meninjau pesan yang mengalami error pengiriman.

Respons​

{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"position": 0,
"payload": { "username": "905554443301", "referenceId": "ORDER-12345" },
"status": "succeeded",
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"message": {
"_id": "msg_789",
"type": "template",
"status": "delivered",
"payload": {
"template": {
"name": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z"
},
"session": {
"_id": "session_456",
"status": "opened"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}

Kolom item​

KolomTipeDeskripsi
_idstringID item
bulkOperationIdstringID operasi massal pemilik item ini
positionnumberUrutan penerima dalam array recipients pada permintaan, dimulai dari 0
payloadobjectPenerima persis seperti yang dikirim dalam permintaan (username / userId / sessionId, referenceId, payload, isMerge)
statusstringStatus item: pending, succeeded, failed, cancelled, unknown
errorobjectHanya pada item failed: code, message, dan retryable
result.userIdstringID pengguna penerima
result.sessionIdstringID sesi percakapan
result.messageIdstringID pesan terkirim (tidak ada jika tidak ada pesan yang dikirim)
completedAtstringKapan item diproses
messageobjectDetail pesan (hanya di list-with-messages)
sessionobjectDetail percakapan (hanya di list-with-messages)

Perbandingan List dan List-With-Messages​

Fiturlistlist-with-messages
Penomoran halamanYaYa
PemfilteranYa (hanya kolom item)Ya (kolom item + pesan)
Message / SessionTidakYa (jika ada)
KinerjaCepatSedang (melakukan JOIN)
Filter message.statusTidak tersediaTersedia
Skenario penggunaan
  • list: Menampilkan semua item dengan cepat, memfilter berdasarkan referenceId, memeriksa status item
  • list-with-messages: Melihat status pesan WhatsApp (delivered, read), memeriksa payload pesan
  • Contoh pemfilteran:
    • {"status": "failed"} — Item pengiriman yang gagal
    • {"payload.referenceId": "ORDER-123"} — Reference ID tertentu
    • {"message.status": "delivered"} — Pesan terkirim (hanya list-with-messages)
    • {"message.status": "read"} — Pesan terbaca (hanya list-with-messages)
    • {"message.status": "error"} — Pesan dengan error (hanya list-with-messages)
    • {"message.status": {"$in": ["delivered", "read"]}} — Pesan yang terkirim atau terbaca (hanya list-with-messages)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — Pesan tanpa yang error dan tidak terkirim (hanya list-with-messages)
    • {"message": {"$exists": false}} — Item tanpa pesan (hanya list-with-messages)
    • {"status": {"$in": ["succeeded", "pending"]}} — Item yang berhasil atau tertunda
Catatan kinerja dan penggunaan
  • Endpoint list lebih cepat; pilih endpoint ini untuk pemeriksaan status umum
  • Gunakan list-with-messages saat detail pesan dibutuhkan
  • Jumlah item maksimum per halaman (pageItems) adalah 50; default 50 jika tidak ditentukan
  • Filter message.status hanya berfungsi pada list-with-messages
  • Item tanpa result.messageId tidak memiliki objek message

Stop — Batalkan pengiriman​

Menghentikan pengiriman operasi massal yang sedang berjalan. Semua item pending dipindahkan ke status cancelled dan operasi massal menjadi stopped. Item yang sudah diproses sebagai succeeded atau failed tidak terpengaruh. Operasi massal terjadwal juga dapat dihentikan sebelum waktu scheduleAt-nya.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js
peringatan

Tindakan ini tidak dapat dibatalkan. Pengiriman yang dihentikan tidak dapat dilanjutkan.

Parameter permintaan​

ParameterTipeWajibDeskripsi
bulkOperationIdstringYaID operasi massal yang dihentikan
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'

Respons​

Untuk permintaan yang berhasil, isi respons kosong. Status HTTP 200 menunjukkan bahwa operasi selesai dengan berhasil.

{}
tips
  • Hanya operasi massal yang dibuat melalui API ini yang dapat dihentikan
  • Setelah menghentikan pengiriman, Anda dapat menggunakan endpoint show untuk memeriksa jumlah item yang dibatalkan (bulkOperation.progress.cancelled)
  • Jika operasi massal tidak ditemukan, API mengembalikan error: Bulk operation not found.