Passa al contenuto principale

Documentazione dell’API Bulk Template Message

Questa API permette di inviare messaggi template a più destinatari contemporaneamente tramite il canale WhatsApp.

L’invio dei messaggi viene elaborato in modo asincrono; la richiesta API restituisce subito un bulkMessageId, mentre i messaggi vengono messi in coda ed elaborati in background.

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

Funzionalità principali​

  • Invio di messaggi template in blocco a 1–5.000 destinatari in una singola richiesta
  • Variabili personalizzate per ogni destinatario (HEADER, BODY, BUTTONS, CAROUSEL)
  • defaultPayload condiviso da tutti i destinatari, con unione del payload specifico di ciascun destinatario (isMerge)
  • Invio programmato (scheduleAt)
  • Indicazione dei destinatari tramite username (numero di telefono), userId o sessionId
  • Invio di più messaggi allo stesso utente all’interno di una singola richiesta in blocco
  • referenceId facoltativo per collegare i record a sistemi esterni
  • Assegnazione automatica delle conversazioni a un utente o a un gruppo di lavoro dopo l’invio (action)
avvertenza

Questa API può inviare solo template approvati da Meta.

Il nome del template e il codice lingua devono corrispondere esattamente al template registrato in Meta Business Manager.

Parametri della richiesta​

Parametri di primo livello​

ParametroTipoObbligatorioDescrizione
channelUsernamestringSìNumero del canale WhatsApp usato per inviare il messaggio (ad es. "908506669933")
connectorBrandstringSìMarca del connettore del canale. Valore attualmente supportato: "whatsapp"
titlestringNoTitolo della campagna. Usato per la visualizzazione nella dashboard. Predefinito: "-"
scheduleAtstring (ISO 8601)NoData e ora di invio programmato (ad es. "2026-06-10T10:00:00.000Z"). Se omesso, i messaggi vengono inviati subito.
defaultPayloadobjectCondizionale*Payload predefinito del template applicato a tutti i destinatari. Obbligatorio se un destinatario non fornisce un proprio payload.
recipientsarraySìElenco dei destinatari. Minimo 1, massimo 5.000 destinatari.
actionobjectNoAzione applicata alla conversazione dopo l’invio. assign-to-user o assign-to-workgroup.

*Se ogni destinatario fornisce un proprio payload, defaultPayload è facoltativo.

Struttura del destinatario​

Per ogni destinatario deve essere indicato esattamente uno tra username, userId e sessionId. Non si possono usare più identificativi insieme e ometterli tutti provoca un errore.

Per inviare più messaggi allo stesso utente all’interno di una singola richiesta in blocco, aggiungere lo stesso identificativo più volte all’elenco dei destinatari.

CampoTipoDescrizione
usernamestringNumero di telefono del destinatario (ad es. "905554443322"). Se l’utente non esiste nel sistema, viene creato automaticamente.
userIdstringID di un utente esistente nel sistema.
sessionIdstringID di una sessione di conversazione esistente nel sistema.
referenceIdstringID di riferimento facoltativo (massimo 256 caratteri) per il collegamento con i record di sistemi esterni (CRM, ordine, ticket e così via). Se indicato, deve essere univoco all’interno dell’invio in blocco.
payloadobjectPayload del template specifico del destinatario (facoltativo). Se isMerge: true, viene unito a defaultPayload.
isMergebooleanSostituisce il comportamento di unione per questo destinatario (facoltativo). Se omesso, viene usato defaultPayload.isMerge.

Struttura dell’azione​

CampoTipoDescrizione
action.keystring"assign-to-user" assegna la conversazione a un operatore specifico; "assign-to-workgroup" la assegna a un gruppo di lavoro.
action.valuestringID dell’utente o del gruppo di lavoro di destinazione.

Struttura del payload del template​

defaultPayload e il payload specifico del destinatario hanno la stessa struttura. Per i messaggi template deve essere indicato type: "template".

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
CampoTipoObbligatorioDescrizione
typestringSìTipo di payload. Per i messaggi template: "template"
template.templateNamestringSì*Nome del template registrato in Meta. Facoltativo nei payload dei destinatari quando si usa isMerge: true (viene ereditato dal payload predefinito).
template.languageCodestringNoCodice lingua del template (ad es. "tr", "en", "tr-TR", "en-US"). Deve corrispondere esattamente alla lingua registrata in Meta.
template.variablesarrayNoElenco delle variabili applicate ai componenti del template. Dettagli più avanti.
isMergebooleanNotrue: il payload del destinatario viene unito in profondità a defaultPayload. false oppure omesso: il payload del destinatario sostituisce completamente defaultPayload.
Comportamento di isMerge
  • Se defaultPayload.isMerge: true e il destinatario fornisce un proprio payload, viene applicata un’unione in profondità.
  • Con l’unione in profondità, il destinatario può fornire solo variables; templateName e languageCode vengono ereditati dal payload predefinito.
  • Il campo isMerge del destinatario sostituisce defaultPayload.isMerge.
  • Se un destinatario non fornisce un payload, viene sempre usato defaultPayload.

Struttura delle variabili​

Ogni elemento dell’array variables corrisponde a un componente del template. Un tipo di componente (type) può comparire una sola volta nell’array.

typeDescrizioneparameterscards
"HEADER"Componente di intestazione del template. Variabile di testo o URL multimediale (immagine, video, documento)Sì—
"BODY"Variabili di testo del corpo del templateSì—
"BUTTONS"Variabili del suffisso URL dinamico per i pulsantiSì—
"CAROUSEL"Componenti delle schede per i template a carosello—Sì

Formati dei parametri​

Il campo parameters può essere indicato in tre formati diversi:

// Format 1: Array (index-based) — for placeholders like {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]

// Format 2: Object (numeric keys) — alternative representation for {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }

// Format 3: Object (named keys) — for placeholders like {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
Quale formato devo usare?
  • Se il tuo template Meta usa segnaposto come {{1}}, {{2}}, usa il formato array oppure il formato oggetto con chiavi numeriche.
  • Se il tuo template usa segnaposto con nome come {{firstName}} o {{orderTotal}}, usa il formato oggetto con chiavi nominali.
  • Con gli array l’ordine conta: il primo elemento corrisponde a {{1}}, il secondo a {{2}} e così via.

Componente HEADER​

Usa il componente HEADER quando l’intestazione del template contiene un contenuto multimediale (immagine, video, documento) o testo dinamico.

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

// Text header variable
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}

Componente BODY​

Serve per le variabili di testo dinamiche nel corpo del template.

// Array format — when the template uses {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}

// Named format — when the template uses {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}

Componente BUTTONS​

Serve per i pulsanti con suffissi URL dinamici. Se il template contiene più pulsanti URL, vengono indicizzati in sequenza solo i pulsanti con variabili (i pulsanti senza variabili o i pulsanti FLOW vengono ignorati).

// Single URL button suffix variable
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}

// Multiple URL button suffix variables (first URL button, second URL button)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}

Per i template a carosello, le variabili dei componenti sono definite separatamente per ogni scheda.

{
"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"]
}
]
}
]
}
avvertenza

La lunghezza dell’array cards deve corrispondere esattamente al numero di schede definite nel template.

Esempi​

1. Template semplice — nessuna variabile, stesso contenuto per tutti i destinatari​

È il modo più semplice per inviare a più destinatari un template statico senza variabili.

{
"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/bulk-message/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" }
]
}'
suggerimento
  • I destinatari indicati tramite username vengono creati automaticamente se non esistono già nel sistema
  • Tutti i destinatari usano lo stesso defaultPayload; non servono dati specifici per destinatario
  • Quando isMerge non è indicato, ogni destinatario usa direttamente defaultPayload

2. Template con variabili del corpo condivise​

Lo stesso template viene inviato a tutti i destinatari con valori di variabile identici. Il template contiene segnaposto come {{1}} e {{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" }]
}
suggerimento
  • In questo esempio, il corpo del template potrebbe contenere un testo come: "Approfitta di uno sconto del {{1}} nella nostra campagna! Offerta valida fino al {{2}}."
  • parameters[0] sostituisce {{1}}, mentre parameters[1] sostituisce {{2}}

3. Template personalizzato — variabili per destinatario con isMerge​

Per ogni destinatario si usano valori di variabile diversi. Impostando isMerge: true in defaultPayload, i destinatari devono fornire solo variables; templateName e languageCode vengono ereditati dal payload predefinito.

In questo esempio, il template include sia un’intestazione multimediale sia variabili personalizzate nel corpo.

{
"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"]
}
]
}
}
}
]
}
suggerimento
  • Grazie a isMerge: true, templateName non deve essere ripetuto nel payload di ogni destinatario
  • L’array variables di ogni destinatario è del tutto indipendente
  • L’URL del contenuto multimediale dell’intestazione deve essere accessibile pubblicamente
  • Se type è omesso nel payload del destinatario, viene ereditato defaultPayload.type

4. Variabile di un pulsante URL​

Usa il componente BUTTONS quando il template contiene un pulsante con un suffisso URL dinamico. Ad esempio, un numero di tracciamento aggiunto all’URL di base 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"]
}
]
}
}
}
]
}
suggerimento
  • I parametri di BUTTONS vengono associati in base all’ordine dei pulsanti che contengono variabili
  • I pulsanti FLOW e i pulsanti senza variabili vengono ignorati; l’indicizzazione riguarda solo i pulsanti URL dinamici
  • Se l’URL del pulsante del template è https://example.com/track/{{1}}, parameters[0] sostituisce {{1}}

5. Invio programmato​

Programma l’invio di un messaggio a una data e un’ora future. scheduleAt deve essere indicato come timestamp 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" }
}
]
}
}
}
]
}
suggerimento
  • scheduleAt deve essere indicato nel fuso orario UTC (ad es., per le 10:00 ora della Turchia, usa 07:00:00.000Z)
  • Questo esempio usa il formato con parametri nominali; il template deve contenere segnaposto come {{name}} e {{discountRate}}
  • Con action, le conversazioni create dall’invio del messaggio vengono assegnate automaticamente al gruppo di lavoro indicato

Risposta​

Una richiesta riuscita restituisce un bulkMessageId, utilizzabile per seguire il processo di invio:

{
"bulkMessageId": "abc123xyz789"
}

Risposte di errore​

StatoDescrizione
Channel not foundNon è stato trovato alcun canale verificato corrispondente a channelUsername e connectorBrand
Channel is not verifiedIl canale corrispondente esiste ma non è ancora stato verificato
invalidRequestPer un destinatario sono stati indicati più identificativi oppure manca un payload obbligatorio
channelNotFoundNon è stato trovato alcun canale attivo corrispondente al channelId indicato
schema-errorUn campo del corpo della richiesta non ha superato la validazione dello schema (campo obbligatorio mancante, tipo errato o valore non supportato)

Il bulkMessageId restituito può essere usato con gli endpoint seguenti per consultare le statistiche di invio e interrompere il processo di invio.


Stats — statistiche di invio​

Recupera lo stato di invio attuale di un messaggio in blocco. Restituisce il numero di record in sospeso, riusciti, non riusciti e annullati.

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

Parametri della richiesta​

ParametroTipoObbligatorioDescrizione
bulkMessageIdstringSìID del messaggio in blocco da seguire (restituito da createBulkPerRecipient)
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

Risposta​

{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "whatsapp-cloud",
"payload": {
"recipientCount": 100,
"defaultPayloadType": "template",
"jobId": "job_abc123"
},
"schedule": {
"date": "2026-06-10T07:00:00.000Z",
"type": "later"
},
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-08T10:30:00.000Z"
},
"stats": {
"pending": 45,
"success": 42,
"failed": 3,
"cancelled": 10,
"total": 100
}
}

Campi di stats​

CampoTipoDescrizione
stats.pendingnumberNumero di record ancora in attesa nella coda
stats.successnumberNumero di record elaborati con successo per l’invio
stats.failednumberNumero di record che hanno incontrato un errore di invio
stats.cancellednumberNumero di record annullati
stats.totalnumberNumero totale di record (pending + success + failed + cancelled)
nota

stats.success indica che il messaggio è stato consegnato con successo dal sistema. Non garantisce che Meta abbia recapitato il messaggio al destinatario. Gli aggiornamenti di stato successivi generati da Meta (come delivered, read o failed) non incidono su questo contatore e non vengono riportati qui.

Stats e Message Stats a confronto
  • Endpoint stats: mostra lo stato del job di invio (pending, success, failed, cancelled)
  • Endpoint message-stats: mostra lo stato effettivo del messaggio (pending, sending, sent, delivered, read, error e così via)
  • Un job può riuscire anche se il messaggio non è ancora stato recapitato o letto

ID di riferimento​

Il referenceId è un campo facoltativo che puoi usare per associare i record di invio a un ID del tuo sistema a fini di tracciamento (ad es. numero d’ordine, ID del ticket).

Se indicato, deve essere univoco all’interno dell’invio in blocco (massimo 256 caratteri).

Importante
  • Non è obbligatorio
  • Non può essere duplicato all’interno dello stesso messaggio in blocco
  • Può essere riutilizzato in messaggi in blocco diversi

Message Stats — stato dei messaggi WhatsApp​

Recupera le statistiche sullo stato dei messaggi di un messaggio in blocco. A differenza dell’endpoint stats, mostra il message.status effettivo di ogni record invece dello stato del job.

Stati possibili del messaggio: 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/bulk-message/message-stats.js

Parametri della richiesta​

ParametroTipoObbligatorioDescrizione
bulkMessageIdstringSìID del messaggio in blocco da consultare
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

Risposta​

{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"type": "perRecipient",
"title": "Campaign Title"
},
"messageStats": {
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 10,
"total": 120
}
}

Campi di Message Stats​

CampoTipoDescrizione
pendingnumberMessaggi non ancora inviati
sendingnumberMessaggi in corso di invio
sentnumberMessaggi consegnati a WhatsApp, non ancora recapitati
deliverednumberMessaggi recapitati al telefono del destinatario
readnumberMessaggi letti dal destinatario
deletednumberMessaggi eliminati
warningnumberMessaggi con avvisi
errornumberMessaggi con errori
unknownnumberMessaggi con stato sconosciuto
not-sendednumberMessaggi che non è stato possibile inviare
no-messagenumberRecord senza ancora un messaggio (ancora in coda)
totalnumberNumero totale di record
Suggerimenti d’uso
  • Un valore alto di no-message indica che l’invio è ancora in corso
  • Il valore di delivered indica i messaggi recapitati con successo
  • Il valore di read può servire a misurare il coinvolgimento della campagna
  • Puoi interrogare periodicamente questo endpoint per un monitoraggio in tempo reale

Struttura di options — paginazione, filtri e ordinamento​

Il parametro options usato negli endpoint list e list-with-messages offre una struttura standard per paginazione, filtri e ordinamento.

Campi di options​

CampoTipoObbligatorioDescrizione
paginationobjectNoImpostazioni di paginazione
filteringobjectNoCriteri di filtro
sortingobjectNoImpostazioni di ordinamento (ad es. {"createdAt": -1})

Struttura della paginazione​

CampoTipoPredefinitoDescrizione
currentPagenumber1Numero della pagina da recuperare
pageItemsnumber50Numero di record per pagina (massimo: 50)

Struttura dei filtri​

Il filtro si basa sul formato di query di MongoDB. È possibile filtrare per campi del record. Nell’endpoint list-with-messages si può filtrare anche per campi del messaggio (ad es. message.status).

// Filter by record status
{
"options": {
"filtering": {
"status": "success"
}
}
}

// Filter by referenceId
{
"options": {
"filtering": {
"referenceId": "ORDER-12345"
}
}
}

// Filter by message status (only list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}

// Filter by multiple statuses using $in (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}

// Exclude specific statuses using $nin (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}

Struttura dell’ordinamento​

L’ordinamento si basa sul formato di ordinamento di MongoDB. 1 indica ordine crescente, -1 ordine decrescente.

// Sort by creation date descending (newest first)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}

// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}

Esempio di uso combinato​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"createdAt": -1
}
}
}

Questo esempio ordina i messaggi recapitati dal più recente al meno recente.

Suggerimenti pratici
  • Combina filtering e pagination per query mirate
  • La risposta include options.pagination.totalCount e options.pagination.totalPages per la navigazione
  • Il filtro message.status funziona solo nell’endpoint list-with-messages

Records — dettagli ed elenco dei record​

Elenca tutti i record di invio di un messaggio in blocco. Ogni record rappresenta un singolo messaggio inviato a un destinatario.

List — elenco dei record​

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

Parametri della richiesta​

ParametroTipoObbligatorioDescrizione
bulkMessageIdstringSìID del messaggio in blocco da elencare
optionsobjectNoOpzioni di paginazione, filtro e ordinamento. Per i dettagli vedi Struttura di options.

Richiesta — uso di base​

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

Richiesta — filtro per stato specifico​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "success"
}
}
}

Elenca solo i record di invio riusciti (record.status = "success").

Risposta​

{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"slug": "my-workspace",
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"createdAt": "2026-06-10T10:00:00.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}

List With Messages — elenco con dettagli dei messaggi​

Ha le stesse funzionalità dell’endpoint list (paginazione, filtri, ordinamento). L’unica differenza: se un record ha un messageId, viene restituito anche l’oggetto message corrispondente. Così puoi vedere lo stato del messaggio (delivered, read, error e così via) e il payload in un’unica query.

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

Richiesta — uso di base​

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

Richiesta — filtro per stato del messaggio​

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

Questo esempio recupera solo i messaggi con stato "delivered".

Richiesta — elenco dei messaggi non riusciti​

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

Serve a esaminare i messaggi che hanno incontrato errori di invio.

Risposta​

{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"userId": "user_123",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"message": {
"_id": "msg_789",
"status": "delivered",
"payload": {
"type": "template",
"template": {
"templateName": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z",
"deliveredAt": "2026-06-10T10:01:05.000Z"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}

Campi del record​

CampoTipoDescrizione
_idstringID del record
bulkMessageIdstringID del messaggio in blocco a cui appartiene il record
userIdstringID utente del destinatario
sessionIdstringID della sessione di conversazione
messageIdstringID del messaggio inviato (null se non ancora inviato)
referenceIdstringID di riferimento facoltativo (se indicato)
statusstringStato del record: pending, success, failed, cancelled
messageobjectDettagli del messaggio (solo in list-with-messages)

Confronto tra List e List-With-Messages​

Caratteristicalistlist-with-messages
PaginazioneSìSì
FiltriSì (solo campi del record)Sì (campi del record e del messaggio)
Oggetto messageNoSì (se esiste messageId)
PrestazioniVeloceMedie (esegue un JOIN)
Filtro message.statusNon disponibileDisponibile
Scenari d’uso
  • list: elenca rapidamente tutti i record, filtra per referenceId, controlla lo stato dei record
  • list-with-messages: consulta lo stato dei messaggi WhatsApp (delivered, read), esamina i payload dei messaggi
  • Esempi di filtro:
    • {"status": "failed"} — record di invio non riusciti
    • {"referenceId": "ORDER-123"} — un ID di riferimento specifico
    • {"message.status": "delivered"} — messaggi recapitati (solo list-with-messages)
    • {"message.status": "read"} — messaggi letti (solo list-with-messages)
    • {"message.status": "error"} — messaggi con errori (solo list-with-messages)
    • {"message.status": {"$in": ["delivered", "read"]}} — messaggi recapitati o letti (solo list-with-messages)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — messaggi esclusi quelli con errori e non inviati (solo list-with-messages)
    • {"status": {"$in": ["success", "pending"]}} — record riusciti o in sospeso
Note su prestazioni e uso
  • L’endpoint list è più veloce; preferiscilo per i controlli generali sullo stato
  • Usa list-with-messages quando servono i dettagli dei messaggi
  • Il numero massimo di record per pagina (pageItems) è 50; se non specificato, il valore predefinito è 50
  • Il filtro message.status funziona solo in list-with-messages
  • I record con messageId null avranno oggetti message null

Stop — annullare l’invio​

Interrompe l’invio in corso di un messaggio in blocco. Il job in coda viene annullato e tutti i record pending passano allo stato cancelled. I record già elaborati come success o failed non vengono modificati.

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

Questa azione non può essere annullata. Un invio interrotto non può essere ripreso.

Parametri della richiesta​

ParametroTipoObbligatorioDescrizione
bulkMessageIdstringSìID del messaggio in blocco da interrompere
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

Risposta​

Per una richiesta riuscita, il corpo della risposta è vuoto. Uno stato HTTP 200 indica che l’operazione si è conclusa con successo.

{}
suggerimento
  • Si possono interrompere solo i messaggi in blocco creati tramite questa API
  • Dopo aver interrotto un invio, puoi usare l’endpoint stats per verificare il numero di record annullati
  • Se il messaggio in blocco non viene trovato, l’API restituisce l’errore: bulkMessageNotFound