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)
defaultPayloadcondiviso da tutti i destinatari, con unione delpayloadspecifico di ciascun destinatario (isMerge)- Invio programmato (
scheduleAt) - Indicazione dei destinatari tramite
username(numero di telefono),userIdosessionId - Invio di più messaggi allo stesso utente all’interno di una singola richiesta in blocco
referenceIdfacoltativo per collegare i record a sistemi esterni- Assegnazione automatica delle conversazioni a un utente o a un gruppo di lavoro dopo l’invio (
action)
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
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
channelUsername | string | Sì | Numero del canale WhatsApp usato per inviare il messaggio (ad es. "908506669933") |
connectorBrand | string | Sì | Marca del connettore del canale. Valore attualmente supportato: "whatsapp" |
title | string | No | Titolo della campagna. Usato per la visualizzazione nella dashboard. Predefinito: "-" |
scheduleAt | string (ISO 8601) | No | Data e ora di invio programmato (ad es. "2026-06-10T10:00:00.000Z"). Se omesso, i messaggi vengono inviati subito. |
defaultPayload | object | Condizionale* | Payload predefinito del template applicato a tutti i destinatari. Obbligatorio se un destinatario non fornisce un proprio payload. |
recipients | array | Sì | Elenco dei destinatari. Minimo 1, massimo 5.000 destinatari. |
action | object | No | Azione 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.
| Campo | Tipo | Descrizione |
|---|---|---|
username | string | Numero di telefono del destinatario (ad es. "905554443322"). Se l’utente non esiste nel sistema, viene creato automaticamente. |
userId | string | ID di un utente esistente nel sistema. |
sessionId | string | ID di una sessione di conversazione esistente nel sistema. |
referenceId | string | ID 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. |
payload | object | Payload del template specifico del destinatario (facoltativo). Se isMerge: true, viene unito a defaultPayload. |
isMerge | boolean | Sostituisce il comportamento di unione per questo destinatario (facoltativo). Se omesso, viene usato defaultPayload.isMerge. |
Struttura dell’azione
| Campo | Tipo | Descrizione |
|---|---|---|
action.key | string | "assign-to-user" assegna la conversazione a un operatore specifico; "assign-to-workgroup" la assegna a un gruppo di lavoro. |
action.value | string | ID 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
}
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | Tipo di payload. Per i messaggi template: "template" |
template.templateName | string | Sì* | Nome del template registrato in Meta. Facoltativo nei payload dei destinatari quando si usa isMerge: true (viene ereditato dal payload predefinito). |
template.languageCode | string | No | Codice lingua del template (ad es. "tr", "en", "tr-TR", "en-US"). Deve corrispondere esattamente alla lingua registrata in Meta. |
template.variables | array | No | Elenco delle variabili applicate ai componenti del template. Dettagli più avanti. |
isMerge | boolean | No | true: il payload del destinatario viene unito in profondità a defaultPayload. false oppure omesso: il payload del destinatario sostituisce completamente defaultPayload. |
- Se
defaultPayload.isMerge: truee il destinatario fornisce un propriopayload, viene applicata un’unione in profondità. - Con l’unione in profondità, il destinatario può fornire solo
variables;templateNameelanguageCodevengono ereditati dal payload predefinito. - Il campo
isMergedel destinatario sostituiscedefaultPayload.isMerge. - Se un destinatario non fornisce un
payload, viene sempre usatodefaultPayload.
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.
| type | Descrizione | parameters | cards |
|---|---|---|---|
"HEADER" | Componente di intestazione del template. Variabile di testo o URL multimediale (immagine, video, documento) | Sì | — |
"BODY" | Variabili di testo del corpo del template | Sì | — |
"BUTTONS" | Variabili del suffisso URL dinamico per i pulsanti | Sì | — |
"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" }
- 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"]
}
Componente CAROUSEL
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"]
}
]
}
]
}
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" }
]
}'
- I destinatari indicati tramite
usernamevengono creati automaticamente se non esistono già nel sistema - Tutti i destinatari usano lo stesso
defaultPayload; non servono dati specifici per destinatario - Quando
isMergenon è indicato, ogni destinatario usa direttamentedefaultPayload
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" }]
}
- 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}}, mentreparameters[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"]
}
]
}
}
}
]
}
- Grazie a
isMerge: true,templateNamenon deve essere ripetuto nel payload di ogni destinatario - L’array
variablesdi ogni destinatario è del tutto indipendente - L’URL del contenuto multimediale dell’intestazione deve essere accessibile pubblicamente
- Se
typeè omesso nel payload del destinatario, viene ereditatodefaultPayload.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"]
}
]
}
}
}
]
}
- I parametri di
BUTTONSvengono 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" }
}
]
}
}
}
]
}
scheduleAtdeve essere indicato nel fuso orario UTC (ad es., per le 10:00 ora della Turchia, usa07: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
| Stato | Descrizione |
|---|---|
Channel not found | Non è stato trovato alcun canale verificato corrispondente a channelUsername e connectorBrand |
Channel is not verified | Il canale corrispondente esiste ma non è ancora stato verificato |
invalidRequest | Per un destinatario sono stati indicati più identificativi oppure manca un payload obbligatorio |
channelNotFound | Non è stato trovato alcun canale attivo corrispondente al channelId indicato |
schema-error | Un 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
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
bulkMessageId | string | Sì | 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
| Campo | Tipo | Descrizione |
|---|---|---|
stats.pending | number | Numero di record ancora in attesa nella coda |
stats.success | number | Numero di record elaborati con successo per l’invio |
stats.failed | number | Numero di record che hanno incontrato un errore di invio |
stats.cancelled | number | Numero di record annullati |
stats.total | number | Numero totale di record (pending + success + failed + cancelled) |
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.
- 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,errore 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).
- 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
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
bulkMessageId | string | Sì | 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
| Campo | Tipo | Descrizione |
|---|---|---|
pending | number | Messaggi non ancora inviati |
sending | number | Messaggi in corso di invio |
sent | number | Messaggi consegnati a WhatsApp, non ancora recapitati |
delivered | number | Messaggi recapitati al telefono del destinatario |
read | number | Messaggi letti dal destinatario |
deleted | number | Messaggi eliminati |
warning | number | Messaggi con avvisi |
error | number | Messaggi con errori |
unknown | number | Messaggi con stato sconosciuto |
not-sended | number | Messaggi che non è stato possibile inviare |
no-message | number | Record senza ancora un messaggio (ancora in coda) |
total | number | Numero totale di record |
- Un valore alto di
no-messageindica che l’invio è ancora in corso - Il valore di
deliveredindica i messaggi recapitati con successo - Il valore di
readpuò 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
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
pagination | object | No | Impostazioni di paginazione |
filtering | object | No | Criteri di filtro |
sorting | object | No | Impostazioni di ordinamento (ad es. {"createdAt": -1}) |
Struttura della paginazione
| Campo | Tipo | Predefinito | Descrizione |
|---|---|---|---|
currentPage | number | 1 | Numero della pagina da recuperare |
pageItems | number | 50 | Numero 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.
- Combina
filteringepaginationper query mirate - La risposta include
options.pagination.totalCounteoptions.pagination.totalPagesper la navigazione - Il filtro
message.statusfunziona solo nell’endpointlist-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
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
bulkMessageId | string | Sì | ID del messaggio in blocco da elencare |
options | object | No | Opzioni 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
| Campo | Tipo | Descrizione |
|---|---|---|
_id | string | ID del record |
bulkMessageId | string | ID del messaggio in blocco a cui appartiene il record |
userId | string | ID utente del destinatario |
sessionId | string | ID della sessione di conversazione |
messageId | string | ID del messaggio inviato (null se non ancora inviato) |
referenceId | string | ID di riferimento facoltativo (se indicato) |
status | string | Stato del record: pending, success, failed, cancelled |
message | object | Dettagli del messaggio (solo in list-with-messages) |
Confronto tra List e List-With-Messages
| Caratteristica | list | list-with-messages |
|---|---|---|
| Paginazione | Sì | Sì |
| Filtri | Sì (solo campi del record) | Sì (campi del record e del messaggio) |
| Oggetto message | No | Sì (se esiste messageId) |
| Prestazioni | Veloce | Medie (esegue un JOIN) |
| Filtro message.status | Non disponibile | Disponibile |
- 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
- L’endpoint
listè più veloce; preferiscilo per i controlli generali sullo stato - Usa
list-with-messagesquando servono i dettagli dei messaggi - Il numero massimo di record per pagina (pageItems) è 50; se non specificato, il valore predefinito è 50
- Il filtro
message.statusfunziona solo inlist-with-messages - I record con messageId null avranno oggetti
messagenull
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
Questa azione non può essere annullata. Un invio interrotto non può essere ripreso.
Parametri della richiesta
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
bulkMessageId | string | Sì | 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.
{}
- Si possono interrompere solo i messaggi in blocco creati tramite questa API
- Dopo aver interrotto un invio, puoi usare l’endpoint
statsper verificare il numero di record annullati - Se il messaggio in blocco non viene trovato, l’API restituisce l’errore:
bulkMessageNotFound