Treceți la conținutul principal

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
Formatul răspunsului

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.

  1. 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 cererii send nu se schimbă; o singură cerere acceptă acum până la 100.000 de destinatari în loc de 5.000.
  2. Trimiteți bulkOperationId în loc de bulkMessageId în cereri.
  3. Înlocuiți stats.js cu show.js.
  4. 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​

v1v2Ce se schimbă în răspuns
bulk-message/send.jsv2/bulk-operation/send.js{ bulkMessageId } devine { bulkOperationId }
bulk-message/stats.jsv2/bulk-operation/show.js{ bulkMessage, stats } devine { bulkOperation }
bulk-message/message-stats.jsv2/bulk-operation/message-stats.jsContoarele sunt la rădăcină în loc de messageStats
bulk-message/stop.jsv2/bulk-operation/stop.jsNimic
bulk-message-records/list.jsv2/bulk-operation-items/list.jsbulkMessageRecords devine bulkOperationItems
bulk-message-records/list-with-messages.jsv2/bulk-operation-items/list-with-messages.jsLa fel ca list, iar fiecare element conține și session

Nume de câmpuri​

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 (mesaj în masă)bulkOperation (operațiune în masă)
bulkMessageRecord (înregistrare)bulkOperationItem (element)
bulkMessageId în cereri, în răspunsul send și în înregistrăribulkOperationId
username / userId / sessionId ale înregistrării, așa cum au fost trimisepayload.username / payload.userId / payload.sessionId
referenceId al înregistrăriipayload.referenceId
payload al înregistrării (payload-ul șablonului destinatarului)payload.payload
userId, sessionId, messageId ale înregistrării după trimitereresult.userId, result.sessionId, result.messageId
starea înregistrării successsucceeded
errorMessage al înregistrărilor eșuateerror.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, invalidRequestzod-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)
  • defaultPayload comun pentru toți destinatarii, cu îmbinarea payload-ului specific fiecărui destinatar (isMerge)
  • Livrare programată (scheduleAt)
  • Indicați destinatarii prin username (număr de telefon), userId sau sessionId
  • Trimiteți mai multe mesaje aceluiași utilizator în cadrul unei singure cereri în masă
  • referenceId opțional pentru urmărirea înregistrărilor în sisteme externe
  • Atribuiți automat conversațiile unui utilizator sau unui grup de lucru după trimitere (action)
avertisment

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​

ParametruTipObligatoriuDescriere
channelUsernamestringDaNumărul canalului WhatsApp folosit pentru trimiterea mesajului (de exemplu "908506669933")
connectorBrandstringDaBrandul conectorului de canal. Valoare acceptată în prezent: "whatsapp"
titlestringNuTitlul campaniei. Folosit pentru afișare în dashboard. Implicit: "-"
scheduleAtstring (ISO 8601)NuData și ora livrării programate (de exemplu "2026-06-10T10:00:00.000Z"). Dacă este omis, mesajele se trimit imediat.
defaultPayloadobjectCondiționat*Payload-ul implicit al șablonului, aplicat tuturor destinatarilor. Obligatoriu dacă un destinatar nu furnizează propriul payload.
recipientsarrayDaLista destinatarilor. Minimum 1, maximum 100.000 de destinatari.
actionobjectNuAcț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âmpTipDescriere
usernamestringNumărul de telefon al destinatarului (de exemplu "905554443322"). Dacă utilizatorul nu există în sistem, este creat automat.
userIdstringID-ul unui utilizator existent în sistem.
sessionIdstringID-ul unei sesiuni de conversație existente în sistem.
referenceIdstringID 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ă.
payloadobjectPayload-ul șablonului specific destinatarului (opțional). Dacă isMerge: true, este îmbinat cu defaultPayload.
isMergebooleanSuprascrie comportamentul de îmbinare pentru acest destinatar (opțional). Dacă este omis, se folosește defaultPayload.isMerge.

Structura acțiunii​

CâmpTipDescriere
action.keystring"assign-to-user" atribuie conversația unui anumit agent; "assign-to-workgroup" o atribuie unui grup de lucru.
action.valuestringID-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âmpTipObligatoriuDescriere
typestringDaTipul payload-ului. Pentru mesaje șablon: "template"
template.templateNamestringDa*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.languageCodestringNuCodul de limbă al șablonului (de exemplu "tr", "en", "tr-TR", "en-US"). Trebuie să corespundă exact limbii înregistrate în Meta.
template.variablesarrayNuLista variabilelor aplicate componentelor șablonului. Detalii mai jos.
isMergebooleanNutrue: payload-ul destinatarului este îmbinat în profunzime cu defaultPayload. false sau omis: payload-ul destinatarului înlocuiește complet defaultPayload.
Comportamentul isMerge
  • Dacă defaultPayload.isMerge: true și destinatarul furnizează propriul payload, se aplică o îmbinare în profunzime.
  • Cu îmbinarea în profunzime, destinatarul poate furniza doar variables; templateName și languageCode sunt moștenite din payload-ul implicit.
  • Câmpul isMerge al destinatarului îl suprascrie pe defaultPayload.isMerge.
  • Dacă un destinatar nu furnizează un payload, se folosește întotdeauna defaultPayload.

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.

typeDescriereparameterscards
"HEADER"Componenta de antet a șablonului. Variabilă de text sau URL media (imagine, videoclip, document)Da—
"BODY"Variabilele de text din corpul șablonuluiDa—
"BUTTONS"Variabile pentru sufixul URL dinamic al butoanelorDa—
"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" }
Ce format ar trebui să folosesc?
  • 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"]
}

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"]
}
]
}
]
}
avertisment

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" }
]
}'
sfat
  • Destinatarii indicați prin username sunt creați automat dacă nu există încă în sistem
  • Toți destinatarii folosesc același defaultPayload; nu sunt necesare date specifice destinatarului
  • Când isMerge nu este specificat, fiecare destinatar folosește direct defaultPayload

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" }]
}
sfat
  • Î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}}, iar parameters[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"]
}
]
}
}
}
]
}
sfat
  • Datorită isMerge: true, templateName nu trebuie repetat în payload-ul fiecărui destinatar
  • Array-ul variables al fiecărui destinatar este complet independent
  • URL-ul media din antet trebuie să fie accesibil public
  • Dacă type este omis în payload-ul destinatarului, se moștenește defaultPayload.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"]
}
]
}
}
}
]
}
sfat
  • Parametrii BUTTONS sunt 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}}, atunci parameters[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" }
}
]
}
}
}
]
}
sfat
  • scheduleAt trebuie furnizat în fusul orar UTC (de exemplu, pentru ora 10:00 AM a Turciei, folosiți 07: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​

StareDescriere
recipients field is requiredCâmpul recipients nu a fost trimis
Channel not foundNu a fost găsit niciun canal verificat care să corespundă channelUsername și connectorBrand
Channel is not verifiedCanalul găsit există, dar nu a fost încă verificat
zod-schema-errorUn 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​

ParametruTipObligatoriuDescriere
bulkOperationIdstringDaID-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âmpTipDescriere
statusstringStarea operațiunii în masă: preparing, scheduled, pending, running, stopping, stopped, completed, failed
progress.totalnumberNumărul total de elemente
progress.pendingnumberElemente aflate încă în coadă
progress.succeedednumberElemente procesate cu succes pentru livrare
progress.failednumberElemente care au întâmpinat o eroare de livrare
progress.cancellednumberElemente anulate prin stop
progress.unknownnumberElemente al căror rezultat nu a putut fi determinat
result.outcomestringRezultatul final după încheierea operațiunii în masă: success, partial, all-failed, cancelled, unknown
result.hasErrorsbooleantrue dacă cel puțin un element a eșuat
scheduleAtstringOra livrării programate (doar pentru operațiunile în masă programate)
startedAt, completedAtstringCând a început și când s-a încheiat livrarea
notă

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.

Show față de Message Stats
  • 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, error etc.)
  • 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).

Important
  • 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​

ParametruTipObligatoriuDescriere
bulkOperationIdstringDaID-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âmpTipDescriere
pendingnumberMesaje netrimise încă
sendingnumberMesaje în curs de trimitere
sentnumberMesaje predate către WhatsApp, încă nelivrate
deliverednumberMesaje livrate pe telefonul destinatarului
readnumberMesaje citite de destinatar
deletednumberMesaje șterse
warningnumberMesaje cu avertismente
errornumberMesaje cu erori
unknownnumberMesaje cu stare necunoscută
not-sendednumberMesaje care nu au putut fi trimise
no-messagenumberElemente fără mesaj (încă în coadă, eșuate sau anulate)
totalnumberNumărul total de elemente
Sfaturi de utilizare
  • Un număr mare de no-message cât timp operațiunea în masă este running indică faptul că livrarea este încă în curs
  • Numărul delivered arată câte mesaje au fost livrate cu succes
  • Numărul read poate 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âmpTipObligatoriuDescriere
paginationobjectNuSetări de paginare
filteringobjectNuCriterii de filtrare
sortingobjectNuSetă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âmpTipImplicitDescriere
currentPagenumber—Numărul paginii de preluat (obligatoriu când se trimite pagination)
pageItemsnumber50Numă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.

Sfaturi practice
  • Combinați filtering și pagination pentru interogări țintite
  • Răspunsul include options.pagination.totalCount și options.pagination.totalPages pentru navigare
  • Filtrul message.status funcționează doar în endpoint-ul list-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​

ParametruTipObligatoriuDescriere
bulkOperationIdstringDaID-ul operațiunii în masă de listat
optionsobjectNuOpț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âmpTipDescriere
_idstringID-ul elementului
bulkOperationIdstringID-ul operațiunii în masă căreia îi aparține acest element
positionnumberPoziția destinatarului în array-ul recipients din cerere, începând de la 0
payloadobjectDestinatarul exact așa cum a fost trimis în cerere (username / userId / sessionId, referenceId, payload, isMerge)
statusstringStarea elementului: pending, succeeded, failed, cancelled, unknown
errorobjectDoar la elementele failed: code, message și retryable
result.userIdstringID-ul utilizatorului destinatar
result.sessionIdstringID-ul sesiunii de conversație
result.messageIdstringID-ul mesajului trimis (lipsește dacă nu a fost trimis niciun mesaj)
completedAtstringCând a fost procesat elementul
messageobjectDetaliile mesajului (doar în list-with-messages)
sessionobjectDetaliile conversației (doar în list-with-messages)

Comparație între List și List-With-Messages​

Funcționalitatelistlist-with-messages
PaginareDaDa
FiltrareDa (doar câmpurile elementului)Da (câmpuri de element și de mesaj)
Message / SessionNuDa (dacă există)
PerformanțăRapidMediu (execută JOIN)
Filtru message.statusIndisponibilDisponibil
Scenarii de utilizare
  • 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
Note privind performanța și utilizarea
  • Endpoint-ul list este mai rapid; preferați-l pentru verificările generale de stare
  • Folosiți list-with-messages câ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.status funcționează doar în list-with-messages
  • Elementele fără result.messageId nu au obiect message

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
avertisment

Această acțiune nu poate fi anulată. O livrare oprită nu poate fi reluată.

Parametrii cererii​

ParametruTipObligatoriuDescriere
bulkOperationIdstringDaID-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.

{}
sfat
  • Pot fi oprite doar operațiunile în masă create prin acest API
  • După oprirea unei livrări, puteți folosi endpoint-ul show pentru 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.