Przejdź do głównej zawartości

Dokumentacja Bulk Template Message API — v2

To API umożliwia jednoczesne wysyłanie wiadomości szablonowych do wielu odbiorców przez kanał WhatsApp.

Dostarczanie wiadomości odbywa się asynchronicznie: żądanie API natychmiast zwraca bulkOperationId, a wiadomości są kolejkowane i przetwarzane w tle.

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

Każdy endpoint w tym dokumencie jest funkcją niestandardową (custom function). Treść odpowiedzi HTTP zawiera własne pola funkcji (_id, title, pathString…), a właściwą odpowiedź endpointu w polu result. Przykłady odpowiedzi w tym dokumencie pokazują zawartość result:

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

Migracja z v1​

v2 działa równolegle z v1, więc możesz przeprowadzić migrację we własnym tempie. Endpointy v1 (/api/bulk-message/…, /api/bulk-message-records/…) zostaną wycofane; nowe integracje powinny korzystać z v2.

  1. Zmień ścieżki endpointów na v2: …/api/bulk-message/… zmienia się na …/api/v2/bulk-operation/…, a …/api/bulk-message-records/… na …/api/v2/bulk-operation-items/…. Treść żądania send się nie zmienia; jedno żądanie przyjmuje teraz do 100 000 odbiorców zamiast 5 000.
  2. W żądaniach wysyłaj bulkOperationId zamiast bulkMessageId.
  3. Zastąp stats.js przez show.js.
  4. Odczytuj odpowiedzi z użyciem nowych nazw pól z tabeli poniżej.

Endpointy v2 znają tylko operacje masowe utworzone za pomocą send w v2. Aby śledzić wiadomość masową utworzoną w v1 przed migracją, nadal używaj dla niej endpointów v1.

Endpointy​

v1v2Co zmienia się w odpowiedzi
bulk-message/send.jsv2/bulk-operation/send.js{ bulkMessageId } zmienia się na { bulkOperationId }
bulk-message/stats.jsv2/bulk-operation/show.js{ bulkMessage, stats } zmienia się na { bulkOperation }
bulk-message/message-stats.jsv2/bulk-operation/message-stats.jsLiczniki są na najwyższym poziomie zamiast w messageStats
bulk-message/stop.jsv2/bulk-operation/stop.jsNic
bulk-message-records/list.jsv2/bulk-operation-items/list.jsbulkMessageRecords zmienia się na bulkOperationItems
bulk-message-records/list-with-messages.jsv2/bulk-operation-items/list-with-messages.jsTo samo co w list, a każdy element zawiera też session

Nazwy pól​

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 (wiadomość masowa)bulkOperation (operacja masowa)
bulkMessageRecord (rekord)bulkOperationItem (element)
bulkMessageId w żądaniach, w odpowiedzi send i w rekordachbulkOperationId
username / userId / sessionId rekordu w postaci wysłanejpayload.username / payload.userId / payload.sessionId
referenceId rekordupayload.referenceId
payload rekordu (ładunek szablonu odbiorcy)payload.payload
userId, sessionId, messageId rekordu po wysłaniuresult.userId, result.sessionId, result.messageId
status rekordu successsucceeded
errorMessage w nieudanych rekordacherror.message, obok error.code i error.retryable
—position (indeks odbiorcy w recipients)
filtr {"status": "success"}{"status": "succeeded"}
filtr {"referenceId": "…"}{"payload.referenceId": "…"}
błędy send schema-error, invalidRequestzod-schema-error, ze ścieżką nieprawidłowego pola w komunikacie

Kluczowe funkcje​

  • Wysyłanie wiadomości szablonowych do 1–100 000 odbiorców w jednym żądaniu
  • Spersonalizowane zmienne dla każdego odbiorcy (HEADER, BODY, BUTTONS, CAROUSEL)
  • Wspólny defaultPayload dla wszystkich odbiorców ze scalaniem z payload konkretnego odbiorcy (isMerge)
  • Zaplanowana wysyłka (scheduleAt)
  • Wskazywanie odbiorców za pomocą username (numer telefonu), userId lub sessionId
  • Wysyłanie wielu wiadomości do tego samego użytkownika w jednym żądaniu masowym
  • Opcjonalny referenceId do śledzenia rekordów w systemach zewnętrznych
  • Automatyczne przypisanie rozmów do użytkownika lub grupy roboczej po wysłaniu (action)
ostrzeżenie

To API może wysyłać tylko szablony zatwierdzone przez Meta.

Nazwa szablonu i kod języka muszą dokładnie odpowiadać szablonowi zarejestrowanemu w Meta Business Manager.

Parametry żądania​

Parametry najwyższego poziomu​

ParametrTypWymaganyOpis
channelUsernamestringTakNumer kanału WhatsApp używany do wysłania wiadomości (np. "908506669933")
connectorBrandstringTakMarka konektora kanału. Obecnie obsługiwana wartość: "whatsapp"
titlestringNieTytuł kampanii. Używany do wyświetlania w panelu. Domyślnie: "-"
scheduleAtstring (ISO 8601)NieZaplanowana data i godzina wysyłki (np. "2026-06-10T10:00:00.000Z"). Jeśli pominięto, wiadomości są wysyłane natychmiast.
defaultPayloadobjectWarunkowo*Domyślny ładunek szablonu stosowany do wszystkich odbiorców. Wymagany, jeśli odbiorca nie podaje własnego payload.
recipientsarrayTakLista odbiorców. Minimum 1, maksimum 100 000 odbiorców.
actionobjectNieDziałanie zastosowane do rozmowy po wysłaniu. assign-to-user lub assign-to-workgroup.

*Jeśli każdy odbiorca podaje własny payload, defaultPayload jest opcjonalny.

Struktura odbiorcy​

Dla każdego odbiorcy należy podać dokładnie jeden z parametrów username, userId lub sessionId. Nie można używać kilku identyfikatorów jednocześnie, a pominięcie wszystkich spowoduje błąd.

Aby wysłać wiele wiadomości do tego samego użytkownika w jednym żądaniu masowym, dodaj ten sam identyfikator do listy odbiorców wielokrotnie.

PoleTypOpis
usernamestringNumer telefonu odbiorcy (np. "905554443322"). Jeśli użytkownik nie istnieje w systemie, zostanie utworzony automatycznie.
userIdstringIdentyfikator istniejącego użytkownika w systemie.
sessionIdstringIdentyfikator istniejącej sesji rozmowy w systemie.
referenceIdstringOpcjonalny identyfikator referencyjny (maks. 256 znaków) do dopasowania z rekordami systemów zewnętrznych (CRM, zamówienie, zgłoszenie itp.). Jeśli podany, musi być unikalny w obrębie wysyłki masowej.
payloadobjectŁadunek szablonu dla konkretnego odbiorcy (opcjonalny). Jeśli isMerge: true, jest scalany z defaultPayload.
isMergebooleanZastępuje zachowanie scalania dla tego odbiorcy (opcjonalne). Jeśli pominięto, używane jest defaultPayload.isMerge.

Struktura działania​

PoleTypOpis
action.keystring"assign-to-user" przypisuje rozmowę do konkretnego agenta; "assign-to-workgroup" przypisuje ją do grupy roboczej.
action.valuestringIdentyfikator docelowego użytkownika lub grupy roboczej.

Struktura ładunku szablonu​

defaultPayload i payload konkretnego odbiorcy mają tę samą strukturę. W przypadku wiadomości szablonowych należy podać type: "template".

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
PoleTypWymaganyOpis
typestringTakTyp ładunku. Dla wiadomości szablonowych: "template"
template.templateNamestringTak*Nazwa szablonu zarejestrowanego w Meta. W ładunkach odbiorców jest opcjonalna, gdy używane jest isMerge: true (dziedziczona z ładunku domyślnego).
template.languageCodestringNieKod języka szablonu (np. "tr", "en", "tr-TR", "en-US"). Musi dokładnie odpowiadać językowi zarejestrowanemu w Meta.
template.variablesarrayNieLista zmiennych stosowanych do komponentów szablonu. Szczegóły poniżej.
isMergebooleanNietrue: ładunek odbiorcy jest głęboko scalany z defaultPayload. false lub pominięte: ładunek odbiorcy całkowicie zastępuje defaultPayload.
Zachowanie isMerge
  • Jeśli defaultPayload.isMerge: true i odbiorca podaje własny payload, stosowane jest głębokie scalanie.
  • Przy głębokim scalaniu odbiorca może podać tylko variables; templateName i languageCode są dziedziczone z ładunku domyślnego.
  • Pole isMerge odbiorcy zastępuje defaultPayload.isMerge.
  • Jeśli odbiorca nie podaje payload, zawsze używany jest defaultPayload.

Struktura zmiennych​

Każdy element tablicy variables odpowiada komponentowi szablonu. Typ komponentu (type) może wystąpić w tablicy tylko raz.

typeOpisparameterscards
"HEADER"Komponent nagłówka szablonu. Zmienna tekstowa lub adres URL multimediów (obraz, wideo, dokument)Tak—
"BODY"Zmienne tekstu treści szablonuTak—
"BUTTONS"Zmienne dynamicznego sufiksu URL dla przyciskówTak—
"CAROUSEL"Komponenty kart dla szablonów karuzeli—Tak

Formaty parametrów​

Pole parameters można podać w trzech różnych formatach:

// Format 1: Tablica (według indeksu) — dla symboli zastępczych takich jak {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]

// Format 2: Obiekt (klucze numeryczne) — alternatywna reprezentacja dla {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }

// Format 3: Obiekt (klucze nazwane) — dla symboli zastępczych takich jak {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
Którego formatu użyć?
  • Jeśli Twój szablon Meta używa symboli zastępczych takich jak {{1}}, {{2}}, użyj formatu tablicy lub obiektu z kluczami numerycznymi.
  • Jeśli Twój szablon używa nazwanych symboli zastępczych, takich jak {{firstName}} lub {{orderTotal}}, użyj formatu obiektu z kluczami nazwanymi.
  • Przy użyciu tablic kolejność ma znaczenie: pierwszy element odpowiada {{1}}, drugi {{2}} i tak dalej.

Komponent HEADER​

Użyj komponentu HEADER, gdy nagłówek szablonu zawiera multimedia (obraz, wideo, dokument) lub tekst dynamiczny.

// Nagłówek multimedialny (adres URL obrazu)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}

// Zmienna nagłówka tekstowego
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}

Komponent BODY​

Służy do dynamicznych zmiennych tekstowych w treści szablonu.

// Format tablicy — gdy szablon używa {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}

// Format nazwany — gdy szablon używa {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}

Komponent BUTTONS​

Służy do przycisków z dynamicznymi sufiksami URL. Jeśli szablon zawiera wiele przycisków URL, kolejno indeksowane są tylko przyciski ze zmiennymi (przyciski bez zmiennych oraz przyciski FLOW są pomijane).

// Zmienna sufiksu pojedynczego przycisku URL
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}

// Zmienne sufiksów wielu przycisków URL (pierwszy przycisk URL, drugi przycisk URL)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}

W szablonach karuzeli zmienne komponentów definiuje się osobno dla każdej karty.

{
"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"]
}
]
}
]
}
ostrzeżenie

Długość tablicy cards musi dokładnie odpowiadać liczbie kart zdefiniowanych w szablonie.

Przykłady​

1. Prosty szablon — bez zmiennych, ta sama treść dla wszystkich odbiorców​

To najprostszy sposób wysłania statycznego szablonu bez zmiennych do wielu odbiorców.

{
"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" }
]
}'
wskazówka
  • Odbiorcy podani przez username są tworzeni automatycznie, jeśli jeszcze nie istnieją w systemie
  • Wszyscy odbiorcy używają tego samego defaultPayload; nie są wymagane żadne dane specyficzne dla odbiorcy
  • Gdy isMerge nie jest podane, każdy odbiorca bezpośrednio używa defaultPayload

2. Szablon ze wspólnymi zmiennymi treści​

Ten sam szablon jest wysyłany do wszystkich odbiorców z identycznymi wartościami zmiennych. Szablon zawiera symbole zastępcze takie jak {{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" }]
}
wskazówka
  • W tym przykładzie treść szablonu może brzmieć: "Skorzystaj ze zniżki {{1}} w naszej kampanii! Oferta ważna do {{2}}."
  • parameters[0] zastępuje {{1}}, a parameters[1] zastępuje {{2}}

3. Spersonalizowany szablon — zmienne dla każdego odbiorcy z isMerge​

Dla każdego odbiorcy używane są inne wartości zmiennych. Po ustawieniu isMerge: true w defaultPayload odbiorcy muszą podać tylko variables; templateName i languageCode są dziedziczone z ładunku domyślnego.

W tym przykładzie szablon zawiera zarówno nagłówek multimedialny, jak i spersonalizowane zmienne treści.

{
"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"]
}
]
}
}
}
]
}
wskazówka
  • Dzięki isMerge: true templateName nie musi być powtarzane w ładunku każdego odbiorcy
  • Tablica variables każdego odbiorcy jest całkowicie niezależna
  • Adres URL multimediów nagłówka musi być publicznie dostępny
  • Jeśli w ładunku odbiorcy pominięto type, dziedziczone jest defaultPayload.type

4. Zmienna przycisku URL​

Użyj komponentu BUTTONS, gdy szablon zawiera przycisk z dynamicznym sufiksem URL, na przykład numer przesyłki dołączony do bazowego adresu URL 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"]
}
]
}
}
}
]
}
wskazówka
  • Parametry BUTTONS są dopasowywane według kolejności przycisków zawierających zmienne
  • Przyciski FLOW i przyciski bez zmiennych są pomijane; indeksowanie dotyczy tylko dynamicznych przycisków URL
  • Jeśli adres URL przycisku szablonu to https://example.com/track/{{1}}, to parameters[0] zastępuje {{1}}

5. Zaplanowana wysyłka​

Zaplanuj wysłanie wiadomości w przyszłości. scheduleAt należy podać jako znacznik czasu ISO 8601 UTC.

{
"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" }
}
]
}
}
}
]
}
wskazówka
  • scheduleAt należy podać w strefie czasowej UTC (np. dla godziny 10:00 czasu tureckiego użyj 07:00:00.000Z)
  • W tym przykładzie użyto formatu parametrów nazwanych; szablon powinien zawierać symbole zastępcze takie jak {{name}} i {{discountRate}}
  • Dzięki action rozmowy utworzone przez wysłanie wiadomości są automatycznie przypisywane do wskazanej grupy roboczej

Odpowiedź​

Pomyślne żądanie zwraca bulkOperationId, którego można użyć do śledzenia procesu wysyłki:

{
"bulkOperationId": "abc123xyz789"
}

Odpowiedzi z błędami​

StatusOpis
recipients field is requiredNie wysłano pola recipients
Channel not foundNie znaleziono zweryfikowanego kanału pasującego do channelUsername i connectorBrand
Channel is not verifiedDopasowany kanał istnieje, ale nie został jeszcze zweryfikowany
zod-schema-errorPole w treści żądania nie przeszło walidacji schematu (brak wymaganego pola, nieprawidłowy typ, nieobsługiwana wartość, więcej niż jeden identyfikator u odbiorcy lub brak payload). Komunikat wskazuje pole, np. recipients.0.referenceId: referenceId must be unique

Zwrócony bulkOperationId można wykorzystać w poniższych endpointach do sprawdzania statystyk dostarczania i zatrzymywania wysyłki.


Show — status i statystyki operacji masowej​

Pobiera operację masową wraz z jej aktualnym statusem i licznikami dostarczania jej elementów, pod kluczem bulkOperation.

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

Parametry żądania​

ParametrTypWymaganyOpis
bulkOperationIdstringTakIdentyfikator operacji masowej do śledzenia (zwrócony z 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"
}'

Odpowiedź​

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

Pola Show​

Pola znajdują się w bulkOperation.

PoleTypOpis
statusstringStatus operacji masowej: preparing, scheduled, pending, running, stopping, stopped, completed, failed
progress.totalnumberŁączna liczba elementów
progress.pendingnumberElementy nadal oczekujące w kolejce
progress.succeedednumberElementy pomyślnie przekazane do wysyłki
progress.failednumberElementy, w których wystąpił błąd dostarczania
progress.cancellednumberElementy anulowane przez stop
progress.unknownnumberElementy, których wyniku nie udało się ustalić
result.outcomestringWynik końcowy po zakończeniu operacji masowej: success, partial, all-failed, cancelled, unknown
result.hasErrorsbooleantrue, jeśli co najmniej jeden element się nie powiódł
scheduleAtstringZaplanowany czas wysyłki (tylko dla zaplanowanych operacji masowych)
startedAt, completedAtstringKiedy wysyłka się rozpoczęła i zakończyła
notatka

progress.succeeded oznacza, że wiadomość została pomyślnie przekazana przez system. Nie gwarantuje, że Meta dostarczyła wiadomość do odbiorcy. Kolejne aktualizacje statusu generowane przez Meta (takie jak delivered, read lub failed) nie wpływają na ten licznik i nie są tu odzwierciedlane.

Show a Message Stats
  • endpoint show: pokazuje status dostarczania elementów (pending, succeeded, failed, cancelled, unknown)
  • endpoint message-stats: pokazuje rzeczywisty status wiadomości (pending, sending, sent, delivered, read, error itd.)
  • Element może mieć status succeeded, a wiadomość może jeszcze nie zostać dostarczona ani przeczytana

Identyfikator referencyjny​

referenceId to opcjonalne pole, którego możesz używać do dopasowywania elementów wysyłki do identyfikatora z własnego systemu w celach śledzenia (np. numer zamówienia, identyfikator zgłoszenia). Jest zwracany w każdym elemencie jako payload.referenceId.

Jeśli zostanie podany, musi być unikalny w obrębie wysyłki masowej (maks. 256 znaków).

Ważne
  • Użycie nie jest wymagane
  • Nie może być zduplikowany w tej samej operacji masowej
  • Może być ponownie użyty w różnych operacjach masowych

Message Stats — status wiadomości WhatsApp​

Pobiera statystyki statusu wiadomości dla operacji masowej. W odróżnieniu od endpointu show pokazuje rzeczywisty message.status wysłanych wiadomości zamiast statusu elementu.

Możliwe statusy wiadomości: 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

Parametry żądania​

ParametrTypWymaganyOpis
bulkOperationIdstringTakIdentyfikator operacji masowej do sprawdzenia
{
"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"
}'

Odpowiedź​

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

Pola Message Stats​

PoleTypOpis
pendingnumberWiadomości jeszcze niewysłane
sendingnumberWiadomości aktualnie wysyłane
sentnumberWiadomości przekazane do WhatsApp, jeszcze niedostarczone
deliverednumberWiadomości dostarczone na telefon odbiorcy
readnumberWiadomości przeczytane przez odbiorcę
deletednumberUsunięte wiadomości
warningnumberWiadomości z ostrzeżeniami
errornumberWiadomości z błędami
unknownnumberWiadomości o nieznanym statusie
not-sendednumberWiadomości, których nie udało się wysłać
no-messagenumberElementy bez wiadomości (nadal w kolejce, nieudane lub anulowane)
totalnumberŁączna liczba elementów
Wskazówki dotyczące użycia
  • Wysoka wartość no-message, gdy operacja masowa ma status running, oznacza, że wysyłka nadal trwa
  • Wartość delivered pokazuje pomyślnie dostarczone wiadomości
  • Wartość read można wykorzystać do pomiaru zaangażowania w kampanię
  • Możesz okresowo odpytywać ten endpoint, aby śledzić wysyłkę w czasie rzeczywistym

Struktura Options — paginacja, filtrowanie i sortowanie​

Parametr options używany w endpointach list i list-with-messages zapewnia standardową strukturę paginacji, filtrowania i sortowania.

Pola Options​

PoleTypWymaganyOpis
paginationobjectNieUstawienia paginacji
filteringobjectNieKryteria filtrowania
sortingobjectNieUstawienia sortowania (np. {"position": 1})

Struktura paginacji​

Jeśli pagination nie zostanie wysłane, zwracana jest pierwsza strona z maksymalnie 50 elementami. Jeśli zostanie wysłane, currentPage jest wymagane.

PoleTypDomyślnieOpis
currentPagenumber—Numer strony do pobrania (wymagany, gdy wysyłane jest pagination)
pageItemsnumber50Liczba elementów na stronę (maksimum: 50)

Struktura filtrowania​

Filtrowanie odbywa się w formacie zapytań MongoDB według pól elementu, z nazwami pól dokładnie takimi, jak w odpowiedzi (np. status, payload.referenceId, result.messageId). W endpoincie list-with-messages można też filtrować według pól wiadomości (np. message.status).

// Filtrowanie według statusu elementu
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}

// Filtrowanie według referenceId
{
"options": {
"filtering": {
"payload.referenceId": "ORDER-12345"
}
}
}

// Filtrowanie według statusu wiadomości (tylko list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}

// Filtrowanie według wielu statusów za pomocą $in (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}

// Wykluczenie wybranych statusów za pomocą $nin (operator MongoDB)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}

// Lista elementów bez wiadomości (tylko list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}

Struktura sortowania​

Sortowanie odbywa się w formacie sortowania MongoDB. 1 oznacza rosnąco, -1 malejąco. position to pozycja odbiorcy w tablicy recipients żądania (licząc od 0).

// Sortowanie w kolejności odbiorców przesłanych w żądaniu
{
"options": {
"sorting": {
"position": 1
}
}
}

// Sortowanie według wielu pól
{
"options": {
"sorting": {
"status": 1,
"position": 1
}
}
}

Przykład połączonego użycia​

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

Ten przykład wyświetla drugą stronę dostarczonych wiadomości w kolejności odbiorców.

Praktyczne wskazówki
  • Połącz filtering i pagination, aby tworzyć precyzyjne zapytania
  • Odpowiedź zawiera options.pagination.totalCount i options.pagination.totalPages do nawigacji
  • Filtr message.status działa tylko w endpoincie list-with-messages

Items — szczegóły i lista elementów​

Wyświetla wszystkie elementy wysyłki operacji masowej. Każdy element odpowiada jednej pozycji tablicy recipients.

List — lista elementów​

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

Parametry żądania​

ParametrTypWymaganyOpis
bulkOperationIdstringTakIdentyfikator operacji masowej do wyświetlenia
optionsobjectNieOpcje paginacji, filtrowania i sortowania. Szczegóły w sekcji Struktura Options.

Żądanie — podstawowe użycie​

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

Żądanie — filtrowanie według konkretnego statusu​

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

Wyświetla tylko nieudane elementy wysyłki, z przyczyną w error.

Odpowiedź​

{
"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 — lista ze szczegółami wiadomości​

Ma te same funkcje co endpoint list (paginacja, filtrowanie, sortowanie). Różnica: każdy element zawiera też powiązane obiekty message i session, jeśli istnieją. Dzięki temu w jednym zapytaniu zobaczysz status wiadomości (delivered, read, error itd.) oraz ładunek.

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

Żądanie — podstawowe użycie​

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

Żądanie — filtrowanie według statusu wiadomości​

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

Ten przykład pobiera tylko wiadomości o statusie "delivered".

Żądanie — lista nieudanych wiadomości​

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

Służy do przeglądania wiadomości, w których wystąpiły błędy dostarczania.

Odpowiedź​

{
"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": {}
}
}

Pola elementu​

PoleTypOpis
_idstringIdentyfikator elementu
bulkOperationIdstringIdentyfikator operacji masowej, do której należy element
positionnumberPozycja odbiorcy w tablicy recipients żądania, licząc od 0
payloadobjectOdbiorca dokładnie w takiej postaci, w jakiej został wysłany w żądaniu (username / userId / sessionId, referenceId, payload, isMerge)
statusstringStatus elementu: pending, succeeded, failed, cancelled, unknown
errorobjectTylko w elementach failed: code, message i retryable
result.userIdstringIdentyfikator użytkownika-odbiorcy
result.sessionIdstringIdentyfikator sesji rozmowy
result.messageIdstringIdentyfikator wysłanej wiadomości (brak, jeśli nie wysłano wiadomości)
completedAtstringKiedy element został przetworzony
messageobjectSzczegóły wiadomości (tylko w list-with-messages)
sessionobjectSzczegóły rozmowy (tylko w list-with-messages)

Porównanie List i List-With-Messages​

Cechalistlist-with-messages
PaginacjaTakTak
FiltrowanieTak (tylko pola elementu)Tak (pola elementu i wiadomości)
Message / SessionNieTak (jeśli istnieją)
WydajnośćSzybkoŚrednio (wykonuje JOIN)
Filtr message.statusNiedostępnyDostępny
Scenariusze użycia
  • list: szybkie wyświetlanie wszystkich elementów, filtrowanie według referenceId, sprawdzanie statusów elementów
  • list-with-messages: podgląd statusów wiadomości WhatsApp (delivered, read), sprawdzanie ładunków wiadomości
  • Przykłady filtrowania:
    • {"status": "failed"} — nieudane elementy wysyłki
    • {"payload.referenceId": "ORDER-123"} — konkretny identyfikator referencyjny
    • {"message.status": "delivered"} — dostarczone wiadomości (tylko list-with-messages)
    • {"message.status": "read"} — przeczytane wiadomości (tylko list-with-messages)
    • {"message.status": "error"} — wiadomości z błędami (tylko list-with-messages)
    • {"message.status": {"$in": ["delivered", "read"]}} — wiadomości dostarczone lub przeczytane (tylko list-with-messages)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — wiadomości z wyłączeniem błędów i niewysłanych (tylko list-with-messages)
    • {"message": {"$exists": false}} — elementy bez wiadomości (tylko list-with-messages)
    • {"status": {"$in": ["succeeded", "pending"]}} — elementy zakończone powodzeniem lub oczekujące
Wydajność i uwagi dotyczące użycia
  • Endpoint list jest szybszy; preferuj go do ogólnego sprawdzania statusów
  • Używaj list-with-messages, gdy potrzebne są szczegóły wiadomości
  • Maksymalna liczba elementów na stronę (pageItems) to 50; domyślnie 50, jeśli nie podano
  • Filtr message.status działa tylko w list-with-messages
  • Elementy bez result.messageId nie mają obiektu message

Stop — anulowanie wysyłki​

Zatrzymuje trwającą wysyłkę operacji masowej. Wszystkie elementy pending otrzymują status cancelled, a operacja masowa przechodzi w stan stopped. Elementy już przetworzone jako succeeded lub failed nie są zmieniane. Zaplanowaną operację masową można też zatrzymać przed czasem scheduleAt.

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

Tej operacji nie można cofnąć. Zatrzymanej wysyłki nie można wznowić.

Parametry żądania​

ParametrTypWymaganyOpis
bulkOperationIdstringTakIdentyfikator operacji masowej do zatrzymania
{
"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"
}'

Odpowiedź​

W przypadku pomyślnego żądania treść odpowiedzi jest pusta. Kod HTTP 200 oznacza, że operacja zakończyła się powodzeniem.

{}
wskazówka
  • Zatrzymać można tylko operacje masowe utworzone za pomocą tego API
  • Po zatrzymaniu wysyłki możesz użyć endpointu show, aby sprawdzić liczbę anulowanych elementów (bulkOperation.progress.cancelled)
  • Jeśli nie znaleziono operacji masowej, API zwraca błąd: Bulk operation not found.