Documentația Bulk Template Message API — v2
Acest API vă permite să trimiteți mesaje șablon către mai mulți destinatari simultan, prin canalul WhatsApp.
Livrarea mesajelor este procesată asincron; cererea API returnează imediat un bulkOperationId, iar mesajele sunt puse în coadă și procesate în fundal.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js
Fiecare endpoint din acest document este o funcție personalizată (custom function). Corpul răspunsului HTTP conține câmpurile proprii ale funcției (_id, title, pathString…), iar răspunsul efectiv al endpoint-ului se află în result. Exemplele de răspuns din acest document arată conținutul lui result:
{
"_id": "function_id",
"title": "Show",
"pathString": "/bulk-message-api-app/api/v2/bulk-operation/show.js",
"result": {
"bulkOperation": { "_id": "abc123xyz789", "status": "running" }
}
}
Migrarea de la v1
v2 funcționează în paralel cu v1, astfel încât puteți migra în ritmul dvs. Endpoint-urile v1 (/api/bulk-message/…, /api/bulk-message-records/…) vor fi retrase; integrările noi trebuie să folosească v2.
- Mutați căile endpoint-urilor pe v2:
…/api/bulk-message/…devine…/api/v2/bulk-operation/…, iar…/api/bulk-message-records/…devine…/api/v2/bulk-operation-items/…. Corpul cereriisendnu se schimbă; o singură cerere acceptă acum până la 100.000 de destinatari în loc de 5.000. - Trimiteți
bulkOperationIdîn loc debulkMessageIdîn cereri. - Înlocuiți
stats.jscushow.js. - Citiți răspunsurile folosind noile nume de câmpuri din tabelul de mai jos.
Endpoint-urile v2 recunosc doar operațiunile în masă create cu send din v2. Pentru a urmări un mesaj în masă creat cu v1 înainte de migrare, continuați să folosiți endpoint-urile v1 pentru acesta.
Endpoint-uri
| v1 | v2 | Ce se schimbă în răspuns |
|---|---|---|
bulk-message/send.js | v2/bulk-operation/send.js | { bulkMessageId } devine { bulkOperationId } |
bulk-message/stats.js | v2/bulk-operation/show.js | { bulkMessage, stats } devine { bulkOperation } |
bulk-message/message-stats.js | v2/bulk-operation/message-stats.js | Contoarele sunt la rădăcină în loc de messageStats |
bulk-message/stop.js | v2/bulk-operation/stop.js | Nimic |
bulk-message-records/list.js | v2/bulk-operation-items/list.js | bulkMessageRecords devine bulkOperationItems |
bulk-message-records/list-with-messages.js | v2/bulk-operation-items/list-with-messages.js | La fel ca list, iar fiecare element conține și session |
Nume de câmpuri
| v1 | v2 |
|---|---|
stats.success | bulkOperation.progress.succeeded |
stats.pending, stats.failed, stats.cancelled, stats.total | bulkOperation.progress.pending, .failed, .cancelled, .total |
| — | bulkOperation.progress.unknown, bulkOperation.status, bulkOperation.result.outcome |
bulkMessage (mesaj în masă) | bulkOperation (operațiune în masă) |
bulkMessageRecord (înregistrare) | bulkOperationItem (element) |
bulkMessageId în cereri, în răspunsul send și în înregistrări | bulkOperationId |
username / userId / sessionId ale înregistrării, așa cum au fost trimise | payload.username / payload.userId / payload.sessionId |
referenceId al înregistrării | payload.referenceId |
payload al înregistrării (payload-ul șablonului destinatarului) | payload.payload |
userId, sessionId, messageId ale înregistrării după trimitere | result.userId, result.sessionId, result.messageId |
starea înregistrării success | succeeded |
errorMessage al înregistrărilor eșuate | error.message, alături de error.code și error.retryable |
| — | position (indexul destinatarului în recipients) |
filtrul {"status": "success"} | {"status": "succeeded"} |
filtrul {"referenceId": "…"} | {"payload.referenceId": "…"} |
erorile send schema-error, invalidRequest | zod-schema-error, cu calea câmpului invalid în mesaj |
Funcționalități principale
- Trimiteți mesaje șablon în masă către 1–100.000 de destinatari într-o singură cerere
- Variabile personalizate pentru fiecare destinatar (HEADER, BODY, BUTTONS, CAROUSEL)
defaultPayloadcomun pentru toți destinatarii, cu îmbinareapayload-ului specific fiecărui destinatar (isMerge)- Livrare programată (
scheduleAt) - Indicați destinatarii prin
username(număr de telefon),userIdsausessionId - Trimiteți mai multe mesaje aceluiași utilizator în cadrul unei singure cereri în masă
referenceIdopțional pentru urmărirea înregistrărilor în sisteme externe- Atribuiți automat conversațiile unui utilizator sau unui grup de lucru după trimitere (
action)
Acest API poate trimite doar șabloane aprobate de Meta.
Numele șablonului și codul de limbă trebuie să corespundă exact șablonului înregistrat în Meta Business Manager.
Parametrii cererii
Parametri de nivel superior
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
channelUsername | string | Da | Numărul canalului WhatsApp folosit pentru trimiterea mesajului (de exemplu "908506669933") |
connectorBrand | string | Da | Brandul conectorului de canal. Valoare acceptată în prezent: "whatsapp" |
title | string | Nu | Titlul campaniei. Folosit pentru afișare în dashboard. Implicit: "-" |
scheduleAt | string (ISO 8601) | Nu | Data și ora livrării programate (de exemplu "2026-06-10T10:00:00.000Z"). Dacă este omis, mesajele se trimit imediat. |
defaultPayload | object | Condiționat* | Payload-ul implicit al șablonului, aplicat tuturor destinatarilor. Obligatoriu dacă un destinatar nu furnizează propriul payload. |
recipients | array | Da | Lista destinatarilor. Minimum 1, maximum 100.000 de destinatari. |
action | object | Nu | Acțiune aplicată conversației după trimitere. assign-to-user sau assign-to-workgroup. |
*Dacă fiecare destinatar furnizează propriul payload, defaultPayload este opțional.
Structura destinatarului
Pentru fiecare destinatar trebuie furnizat exact unul dintre username, userId sau sessionId. Mai mulți identificatori nu pot fi folosiți împreună, iar omiterea tuturor duce la o eroare.
Pentru a trimite mai multe mesaje aceluiași utilizator într-o singură cerere în masă, adăugați același identificator în lista de destinatari de mai multe ori.
| Câmp | Tip | Descriere |
|---|---|---|
username | string | Numărul de telefon al destinatarului (de exemplu "905554443322"). Dacă utilizatorul nu există în sistem, este creat automat. |
userId | string | ID-ul unui utilizator existent în sistem. |
sessionId | string | ID-ul unei sesiuni de conversație existente în sistem. |
referenceId | string | ID de referință opțional (maximum 256 de caractere) pentru asocierea cu înregistrările din sisteme externe (CRM, comandă, tichet etc.). Dacă este furnizat, trebuie să fie unic în cadrul trimiterii în masă. |
payload | object | Payload-ul șablonului specific destinatarului (opțional). Dacă isMerge: true, este îmbinat cu defaultPayload. |
isMerge | boolean | Suprascrie comportamentul de îmbinare pentru acest destinatar (opțional). Dacă este omis, se folosește defaultPayload.isMerge. |
Structura acțiunii
| Câmp | Tip | Descriere |
|---|---|---|
action.key | string | "assign-to-user" atribuie conversația unui anumit agent; "assign-to-workgroup" o atribuie unui grup de lucru. |
action.value | string | ID-ul utilizatorului sau al grupului de lucru țintă. |
Structura payload-ului șablonului
defaultPayload și payload-ul specific destinatarului au aceeași structură. Pentru mesajele șablon trebuie indicat type: "template".
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
type | string | Da | Tipul payload-ului. Pentru mesaje șablon: "template" |
template.templateName | string | Da* | Numele șablonului înregistrat în Meta. Opțional în payload-urile destinatarilor când se folosește isMerge: true (se moștenește din cel implicit). |
template.languageCode | string | Nu | Codul de limbă al șablonului (de exemplu "tr", "en", "tr-TR", "en-US"). Trebuie să corespundă exact limbii înregistrate în Meta. |
template.variables | array | Nu | Lista variabilelor aplicate componentelor șablonului. Detalii mai jos. |
isMerge | boolean | Nu | true: payload-ul destinatarului este îmbinat în profunzime cu defaultPayload. false sau omis: payload-ul destinatarului înlocuiește complet defaultPayload. |
- Dacă
defaultPayload.isMerge: trueși destinatarul furnizează propriulpayload, se aplică o îmbinare în profunzime. - Cu îmbinarea în profunzime, destinatarul poate furniza doar
variables;templateNameșilanguageCodesunt moștenite din payload-ul implicit. - Câmpul
isMergeal destinatarului îl suprascrie pedefaultPayload.isMerge. - Dacă un destinatar nu furnizează un
payload, se folosește întotdeaunadefaultPayload.
Structura variabilelor
Fiecare element din array-ul variables corespunde unei componente a șablonului. Un tip de componentă (type) poate apărea o singură dată în array.
| type | Descriere | parameters | cards |
|---|---|---|---|
"HEADER" | Componenta de antet a șablonului. Variabilă de text sau URL media (imagine, videoclip, document) | Da | — |
"BODY" | Variabilele de text din corpul șablonului | Da | — |
"BUTTONS" | Variabile pentru sufixul URL dinamic al butoanelor | Da | — |
"CAROUSEL" | Componentele cardurilor pentru șabloanele de tip carusel | — | Da |
Formate pentru parametri
Câmpul parameters poate fi furnizat în trei formate diferite:
// Formatul 1: array (pe bază de index) — pentru substituenți precum {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]
// Formatul 2: obiect (chei numerice) — reprezentare alternativă pentru {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }
// Formatul 3: obiect (chei denumite) — pentru substituenți precum {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
- Dacă șablonul dvs. Meta folosește substituenți precum
{{1}},{{2}}, folosiți fie formatul array, fie formatul obiect cu chei numerice. - Dacă șablonul dvs. folosește substituenți cu nume, precum
{{firstName}}sau{{orderTotal}}, folosiți formatul obiect cu chei denumite. - Când folosiți array-uri, ordinea contează: primul element corespunde lui
{{1}}, al doilea lui{{2}}și așa mai departe.
Componenta HEADER
Folosiți componenta HEADER când antetul șablonului conține media (imagine, videoclip, document) sau text dinamic.
// Antet media (URL de imagine)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}
// Variabilă de text în antet
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}
Componenta BODY
Se folosește pentru variabilele de text dinamic din corpul șablonului.
// Format array — când șablonul folosește {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}
// Format cu nume — când șablonul folosește {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}
Componenta BUTTONS
Se folosește pentru butoanele cu sufixe URL dinamice. Dacă șablonul conține mai multe butoane URL, doar butoanele cu variabile sunt indexate secvențial (butoanele fără variabile sau butoanele FLOW sunt ignorate).
// Variabilă pentru sufixul unui singur buton URL
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}
// Variabile pentru sufixele mai multor butoane URL (primul buton URL, al doilea buton URL)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}
Componenta CAROUSEL
Pentru șabloanele de tip carusel, variabilele componentelor se definesc separat pentru fiecare card.
{
"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"]
}
]
}
]
}
Lungimea array-ului cards trebuie să corespundă exact numărului de carduri definite în șablon.
Exemple
1. Șablon simplu — fără variabile, același conținut pentru toți destinatarii
Aceasta este cea mai simplă modalitate de a trimite un șablon static, fără variabile, către mai mulți destinatari.
{
"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" }
]
}'
- Destinatarii indicați prin
usernamesunt creați automat dacă nu există încă în sistem - Toți destinatarii folosesc același
defaultPayload; nu sunt necesare date specifice destinatarului - Când
isMergenu este specificat, fiecare destinatar folosește directdefaultPayload
2. Șablon cu variabile de corp comune
Același șablon este trimis tuturor destinatarilor, cu aceleași valori ale variabilelor. Șablonul conține substituenți precum {{1}} și {{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" }]
}
- În acest exemplu, corpul șablonului ar putea conține un text de genul: „Beneficiați de o reducere de
{{1}}în campania noastră! Ofertă valabilă până la{{2}}.” parameters[0]înlocuiește{{1}}, iarparameters[1]înlocuiește{{2}}
3. Șablon personalizat — variabile pentru fiecare destinatar, cu isMerge
Pentru fiecare destinatar se folosesc valori diferite ale variabilelor. Dacă setați isMerge: true în defaultPayload, destinatarii trebuie să furnizeze doar variables; templateName și languageCode sunt moștenite din payload-ul implicit.
În acest exemplu, șablonul include atât un antet media, cât și variabile de corp personalizate.
{
"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"]
}
]
}
}
}
]
}
- Datorită
isMerge: true,templateNamenu trebuie repetat în payload-ul fiecărui destinatar - Array-ul
variablesal fiecărui destinatar este complet independent - URL-ul media din antet trebuie să fie accesibil public
- Dacă
typeeste omis în payload-ul destinatarului, se moșteneștedefaultPayload.type
4. Variabilă pentru butonul URL
Folosiți componenta BUTTONS când șablonul conține un buton cu sufix URL dinamic. De exemplu, un număr de urmărire adăugat la URL-ul de bază 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"]
}
]
}
}
}
]
}
- Parametrii
BUTTONSsunt asociați în ordinea butoanelor care conțin variabile - Butoanele FLOW și butoanele fără variabile sunt ignorate; indexarea se aplică doar butoanelor URL dinamice
- Dacă URL-ul butonului din șablon este
https://example.com/track/{{1}}, atunciparameters[0]înlocuiește{{1}}
5. Livrare programată
Programați trimiterea unui mesaj la o dată și o oră viitoare. scheduleAt trebuie furnizat ca timestamp UTC în format 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" }
}
]
}
}
}
]
}
scheduleAttrebuie furnizat în fusul orar UTC (de exemplu, pentru ora 10:00 AM a Turciei, folosiți07:00:00.000Z)- Acest exemplu folosește formatul cu parametri denumiți; șablonul trebuie să conțină substituenți precum
{{name}}și{{discountRate}} - Cu
action, conversațiile create prin livrarea mesajului sunt atribuite automat grupului de lucru indicat
Răspuns
O cerere reușită returnează un bulkOperationId, care poate fi folosit pentru a urmări procesul de livrare:
{
"bulkOperationId": "abc123xyz789"
}
Răspunsuri de eroare
| Stare | Descriere |
|---|---|
recipients field is required | Câmpul recipients nu a fost trimis |
Channel not found | Nu a fost găsit niciun canal verificat care să corespundă channelUsername și connectorBrand |
Channel is not verified | Canalul găsit există, dar nu a fost încă verificat |
zod-schema-error | Un câmp din corpul cererii nu a trecut validarea schemei (câmp obligatoriu lipsă, tip incorect, valoare neacceptată, mai mulți identificatori pentru un destinatar sau payload lipsă). Mesajul indică numele câmpului, de exemplu recipients.0.referenceId: referenceId must be unique |
bulkOperationId-ul returnat poate fi folosit cu endpoint-urile de mai jos pentru a interoga statisticile de livrare și pentru a opri procesul de livrare.
Show — starea și statisticile operațiunii în masă
Returnează operațiunea în masă, cu starea curentă și contoarele de livrare ale elementelor sale, sub cheia bulkOperation.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js
Parametrii cererii
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
bulkOperationId | string | Da | ID-ul operațiunii în masă de urmărit (returnat de 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"
}'
Răspuns
{
"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"
}
}
Câmpurile Show
Câmpurile se află sub bulkOperation.
| Câmp | Tip | Descriere |
|---|---|---|
status | string | Starea operațiunii în masă: preparing, scheduled, pending, running, stopping, stopped, completed, failed |
progress.total | number | Numărul total de elemente |
progress.pending | number | Elemente aflate încă în coadă |
progress.succeeded | number | Elemente procesate cu succes pentru livrare |
progress.failed | number | Elemente care au întâmpinat o eroare de livrare |
progress.cancelled | number | Elemente anulate prin stop |
progress.unknown | number | Elemente al căror rezultat nu a putut fi determinat |
result.outcome | string | Rezultatul final după încheierea operațiunii în masă: success, partial, all-failed, cancelled, unknown |
result.hasErrors | boolean | true dacă cel puțin un element a eșuat |
scheduleAt | string | Ora livrării programate (doar pentru operațiunile în masă programate) |
startedAt, completedAt | string | Când a început și când s-a încheiat livrarea |
progress.succeeded indică faptul că mesajul a fost predat cu succes de sistem. Nu garantează că Meta a livrat mesajul destinatarului. Actualizările de stare ulterioare generate de Meta (precum delivered, read sau failed) nu afectează acest contor și nu sunt reflectate aici.
- endpoint-ul show: arată starea de livrare a elementelor (
pending,succeeded,failed,cancelled,unknown) - endpoint-ul message-stats: arată starea reală a mesajului (
pending,sending,sent,delivered,read,erroretc.) - Un element poate fi
succeeded, dar mesajul poate să nu fie încă livrat sau citit
ID de referință
referenceId este un câmp opțional pe care îl puteți folosi pentru a asocia elementele de livrare cu un ID din propriul sistem, în scopuri de urmărire (de exemplu, numărul comenzii sau ID-ul tichetului). Este returnat în fiecare element ca payload.referenceId.
Dacă este furnizat, trebuie să fie unic în cadrul trimiterii în masă (maximum 256 de caractere).
- Nu este obligatoriu
- Nu poate fi duplicat în cadrul aceleiași operațiuni în masă
- Poate fi refolosit în operațiuni în masă diferite
Message Stats — starea mesajelor WhatsApp
Returnează statisticile de stare a mesajelor pentru o operațiune în masă. Spre deosebire de endpoint-ul show, acesta arată message.status real al mesajelor trimise, în loc de starea elementului.
Stări posibile ale mesajului: 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
Parametrii cererii
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
bulkOperationId | string | Da | ID-ul operațiunii în masă de interogat |
{
"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"
}'
Răspuns
{
"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
}
Câmpurile Message Stats
| Câmp | Tip | Descriere |
|---|---|---|
pending | number | Mesaje netrimise încă |
sending | number | Mesaje în curs de trimitere |
sent | number | Mesaje predate către WhatsApp, încă nelivrate |
delivered | number | Mesaje livrate pe telefonul destinatarului |
read | number | Mesaje citite de destinatar |
deleted | number | Mesaje șterse |
warning | number | Mesaje cu avertismente |
error | number | Mesaje cu erori |
unknown | number | Mesaje cu stare necunoscută |
not-sended | number | Mesaje care nu au putut fi trimise |
no-message | number | Elemente fără mesaj (încă în coadă, eșuate sau anulate) |
total | number | Numărul total de elemente |
- Un număr mare de
no-messagecât timp operațiunea în masă esterunningindică faptul că livrarea este încă în curs - Numărul
deliveredarată câte mesaje au fost livrate cu succes - Numărul
readpoate fi folosit pentru a măsura implicarea în campanie - Puteți interoga periodic acest endpoint pentru urmărire în timp real
Structura options — paginare, filtrare și sortare
Parametrul options folosit în endpoint-urile list și list-with-messages oferă o structură standard pentru paginare, filtrare și sortare.
Câmpurile options
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
pagination | object | Nu | Setări de paginare |
filtering | object | Nu | Criterii de filtrare |
sorting | object | Nu | Setări de sortare (de exemplu {"position": 1}) |
Structura paginării
Dacă pagination nu este trimis, se returnează prima pagină, cu cel mult 50 de elemente. Dacă este trimis, currentPage este obligatoriu.
| Câmp | Tip | Implicit | Descriere |
|---|---|---|---|
currentPage | number | — | Numărul paginii de preluat (obligatoriu când se trimite pagination) |
pageItems | number | 50 | Numărul de elemente pe pagină (maximum: 50) |
Structura filtrării
Filtrarea se face în formatul de interogare MongoDB, pe câmpurile elementului, folosind numele câmpurilor exact așa cum apar în răspuns (de exemplu status, payload.referenceId, result.messageId). În endpoint-ul list-with-messages puteți filtra și după câmpurile mesajului (de exemplu, message.status).
// Filtrare după starea elementului
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}
// Filtrare după referenceId
{
"options": {
"filtering": {
"payload.referenceId": "ORDER-12345"
}
}
}
// Filtrare după starea mesajului (doar list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}
// Filtrare după mai multe stări cu $in (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}
// Excluderea unor stări cu $nin (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}
// Listarea elementelor fără mesaj (doar list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}
Structura sortării
Sortarea se face în formatul de sortare MongoDB. 1 înseamnă crescător, -1 înseamnă descrescător. position este poziția destinatarului în array-ul recipients din cerere (începând de la 0).
// Sortare în ordinea în care destinatarii au fost trimiși în cerere
{
"options": {
"sorting": {
"position": 1
}
}
}
// Sortare după mai multe câmpuri
{
"options": {
"sorting": {
"status": 1,
"position": 1
}
}
}
Exemplu de utilizare combinată
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"position": 1
}
}
}
Acest exemplu listează a doua pagină de mesaje livrate, în ordinea destinatarilor.
- Combinați
filteringșipaginationpentru interogări țintite - Răspunsul include
options.pagination.totalCountșioptions.pagination.totalPagespentru navigare - Filtrul
message.statusfuncționează doar în endpoint-ullist-with-messages
Items — detalii și listarea elementelor
Listează toate elementele de livrare ale unei operațiuni în masă. Fiecare element reprezintă o intrare din array-ul recipients.
List — lista elementelor
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list.js
Parametrii cererii
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
bulkOperationId | string | Da | ID-ul operațiunii în masă de listat |
options | object | Nu | Opțiuni de paginare, filtrare și sortare. Consultați Structura options pentru detalii. |
Cerere — utilizare de bază
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Cerere — filtrare după o anumită stare
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "failed"
}
}
}
Listează doar elementele de livrare eșuate, cu motivul în error.
Răspuns
{
"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 — listare cu detaliile mesajelor
Are aceleași funcționalități ca endpoint-ul list (paginare, filtrare, sortare). Diferența: fiecare element conține și obiectele message și session asociate, atunci când există. Astfel puteți vedea starea mesajului (delivered, read, error etc.) și payload-ul într-o singură interogare.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list-with-messages.js
Cerere — utilizare de bază
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Cerere — filtrare după starea mesajului
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
Acest exemplu preia doar mesajele cu starea „delivered”.
Cerere — listarea mesajelor eșuate
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
Se folosește pentru a verifica mesajele care au întâmpinat erori de livrare.
Răspuns
{
"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": {}
}
}
Câmpurile elementului
| Câmp | Tip | Descriere |
|---|---|---|
_id | string | ID-ul elementului |
bulkOperationId | string | ID-ul operațiunii în masă căreia îi aparține acest element |
position | number | Poziția destinatarului în array-ul recipients din cerere, începând de la 0 |
payload | object | Destinatarul exact așa cum a fost trimis în cerere (username / userId / sessionId, referenceId, payload, isMerge) |
status | string | Starea elementului: pending, succeeded, failed, cancelled, unknown |
error | object | Doar la elementele failed: code, message și retryable |
result.userId | string | ID-ul utilizatorului destinatar |
result.sessionId | string | ID-ul sesiunii de conversație |
result.messageId | string | ID-ul mesajului trimis (lipsește dacă nu a fost trimis niciun mesaj) |
completedAt | string | Când a fost procesat elementul |
message | object | Detaliile mesajului (doar în list-with-messages) |
session | object | Detaliile conversației (doar în list-with-messages) |
Comparație între List și List-With-Messages
| Funcționalitate | list | list-with-messages |
|---|---|---|
| Paginare | Da | Da |
| Filtrare | Da (doar câmpurile elementului) | Da (câmpuri de element și de mesaj) |
| Message / Session | Nu | Da (dacă există) |
| Performanță | Rapid | Mediu (execută JOIN) |
| Filtru message.status | Indisponibil | Disponibil |
- list: listați rapid toate elementele, filtrați după referenceId, verificați stările elementelor
- list-with-messages: vedeți stările mesajelor WhatsApp (delivered, read), inspectați payload-urile mesajelor
- Exemple de filtrare:
{"status": "failed"}— elemente cu livrare eșuată{"payload.referenceId": "ORDER-123"}— un anumit ID de referință{"message.status": "delivered"}— mesaje livrate (doar list-with-messages){"message.status": "read"}— mesaje citite (doar list-with-messages){"message.status": "error"}— mesaje cu erori (doar list-with-messages){"message.status": {"$in": ["delivered", "read"]}}— mesaje livrate sau citite (doar list-with-messages){"message.status": {"$nin": ["error", "not-sended"]}}— mesaje, fără cele cu erori și cele netrimise (doar list-with-messages){"message": {"$exists": false}}— elemente fără mesaj (doar list-with-messages){"status": {"$in": ["succeeded", "pending"]}}— elemente reușite sau în așteptare
- Endpoint-ul
listeste mai rapid; preferați-l pentru verificările generale de stare - Folosiți
list-with-messagescând aveți nevoie de detaliile mesajelor - Numărul maxim de elemente pe pagină (pageItems) este 50; implicit este 50 dacă nu este specificat
- Filtrul
message.statusfuncționează doar înlist-with-messages - Elementele fără
result.messageIdnu au obiectmessage
Stop — anularea livrării
Oprește livrarea unei operațiuni în masă aflate în desfășurare. Toate elementele pending trec în starea cancelled, iar operațiunea în masă devine stopped. Elementele deja procesate ca succeeded sau failed nu sunt afectate. O operațiune în masă programată poate fi oprită și înainte de ora din scheduleAt.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js
Această acțiune nu poate fi anulată. O livrare oprită nu poate fi reluată.
Parametrii cererii
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
bulkOperationId | string | Da | ID-ul operațiunii în masă de oprit |
{
"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"
}'
Răspuns
Pentru o cerere reușită, corpul răspunsului este gol. Un status HTTP 200 indică faptul că operațiunea s-a încheiat cu succes.
{}
- Pot fi oprite doar operațiunile în masă create prin acest API
- După oprirea unei livrări, puteți folosi endpoint-ul
showpentru a verifica numărul de elemente anulate (bulkOperation.progress.cancelled) - Dacă operațiunea în masă nu este găsită, API-ul returnează eroarea:
Bulk operation not found.