Przejdź do głównej zawartości

Dokumentacja Bulk Template Message API

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 bulkMessageId, a wiadomości są kolejkowane i przetwarzane w tle.

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

Kluczowe funkcje​

  • Wysyłanie wiadomości szablonowych do 1–5 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 5 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/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" }
]
}'
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 bulkMessageId, którego można użyć do śledzenia procesu wysyłki:

{
"bulkMessageId": "abc123xyz789"
}

Odpowiedzi z błędami​

StatusOpis
Channel not foundNie znaleziono zweryfikowanego kanału pasującego do channelUsername i connectorBrand
Channel is not verifiedDopasowany kanał istnieje, ale nie został jeszcze zweryfikowany
invalidRequestDla odbiorcy podano kilka identyfikatorów lub brakuje wymaganego ładunku
channelNotFoundNie znaleziono aktywnego kanału pasującego do podanego channelId
schema-errorPole w treści żądania nie przeszło walidacji schematu (brak wymaganego pola, nieprawidłowy typ lub nieobsługiwana wartość)

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


Stats — statystyki dostarczania​

Pobiera aktualny status dostarczania wiadomości masowej. Zwraca liczby rekordów oczekujących, zakończonych powodzeniem, nieudanych i anulowanych.

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

Parametry żądania​

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

Odpowiedź​

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

Pola Stats​

PoleTypOpis
stats.pendingnumberLiczba rekordów nadal oczekujących w kolejce
stats.successnumberLiczba rekordów pomyślnie przekazanych do wysyłki
stats.failednumberLiczba rekordów, w których wystąpił błąd dostarczania
stats.cancellednumberLiczba anulowanych rekordów
stats.totalnumberŁączna liczba rekordów (pending + success + failed + cancelled)
notatka

stats.success 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.

Stats a Message Stats
  • endpoint stats: pokazuje status zadania wysyłki (pending, success, failed, cancelled)
  • endpoint message-stats: pokazuje rzeczywisty status wiadomości (pending, sending, sent, delivered, read, error itd.)
  • Zadanie może zakończyć się powodzeniem, a wiadomość może jeszcze nie zostać dostarczona ani przeczytana

Identyfikator referencyjny​

referenceId to opcjonalne pole, którego możesz używać do dopasowywania rekordów dostarczania do identyfikatora z własnego systemu w celach śledzenia (np. numer zamówienia, identyfikator zgłoszenia).

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 wiadomości masowej
  • Może być ponownie użyty w różnych wiadomościach masowych

Message Stats — status wiadomości WhatsApp​

Pobiera statystyki statusu wiadomości dla wiadomości masowej. W odróżnieniu od endpointu stats pokazuje rzeczywisty message.status każdego rekordu zamiast statusu zadania.

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/bulk-message/message-stats.js

Parametry żądania​

ParametrTypWymaganyOpis
bulkMessageIdstringTakIdentyfikator wiadomości masowej do sprawdzenia
{
"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"
}'

Odpowiedź​

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

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-messagenumberRekordy bez wiadomości (nadal w kolejce)
totalnumberŁączna liczba rekordów
Wskazówki dotyczące użycia
  • Wysoka wartość no-message 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. {"createdAt": -1})

Struktura paginacji​

PoleTypDomyślnieOpis
currentPagenumber1Numer strony do pobrania
pageItemsnumber50Liczba rekordów na stronę (maksimum: 50)

Struktura filtrowania​

Filtrowanie odbywa się w formacie zapytań MongoDB. Można filtrować według pól rekordu. W endpoincie list-with-messages można też filtrować według pól wiadomości (np. message.status).

// Filtrowanie według statusu rekordu
{
"options": {
"filtering": {
"status": "success"
}
}
}

// Filtrowanie według referenceId
{
"options": {
"filtering": {
"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"]
}
}
}
}

Struktura sortowania​

Sortowanie odbywa się w formacie sortowania MongoDB. 1 oznacza rosnąco, -1 malejąco.

// Sortowanie według daty utworzenia malejąco (najnowsze najpierw)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}

// Sort by multiple fields
// Sortowanie według wielu pól
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}

Przykład połączonego użycia​

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

Ten przykład sortuje dostarczone wiadomości od najnowszych do najstarszych.

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

Records — szczegóły i lista rekordów​

Wyświetla wszystkie rekordy dostarczania dla wiadomości masowej. Każdy rekord reprezentuje jedną wiadomość wysłaną do odbiorcy.

List — lista rekordów​

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

Parametry żądania​

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

Żądanie — podstawowe użycie​

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

Żądanie — filtrowanie według konkretnego statusu​

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

Wyświetla tylko rekordy z udaną wysyłką (record.status = "success").

Odpowiedź​

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

Ma te same funkcje co endpoint list (paginacja, filtrowanie, sortowanie). Jedyna różnica: jeśli rekord ma messageId, zwracany jest także powiązany obiekt message. 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/bulk-message-records/list-with-messages.js

Żądanie — podstawowe użycie​

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

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

{
"bulkMessageId": "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​

{
"bulkMessageId": "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ź​

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

Pola rekordu​

PoleTypOpis
_idstringIdentyfikator rekordu
bulkMessageIdstringIdentyfikator wiadomości masowej, do której należy rekord
userIdstringIdentyfikator użytkownika-odbiorcy
sessionIdstringIdentyfikator sesji rozmowy
messageIdstringIdentyfikator wysłanej wiadomości (null, jeśli jeszcze nie wysłano)
referenceIdstringOpcjonalny identyfikator referencyjny (jeśli podany)
statusstringStatus rekordu: pending, success, failed, cancelled
messageobjectSzczegóły wiadomości (tylko w list-with-messages)

Porównanie List i List-With-Messages​

Cechalistlist-with-messages
PaginacjaTakTak
FiltrowanieTak (tylko pola rekordu)Tak (pola rekordu i wiadomości)
Obiekt messageNieTak (jeśli istnieje messageId)
WydajnośćSzybkoŚrednio (wykonuje JOIN)
Filtr message.statusNiedostępnyDostępny
Scenariusze użycia
  • list: szybkie wyświetlanie wszystkich rekordów, filtrowanie według referenceId, sprawdzanie statusów rekordów
  • list-with-messages: podgląd statusów wiadomości WhatsApp (delivered, read), sprawdzanie ładunków wiadomości
  • Przykłady filtrowania:
    • {"status": "failed"} — rekordy nieudanej wysyłki
    • {"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)
    • {"status": {"$in": ["success", "pending"]}} — rekordy 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 rekordów na stronę (pageItems) to 50; domyślnie 50, jeśli nie podano
  • Filtr message.status działa tylko w list-with-messages
  • Rekordy z pustym messageId będą miały puste obiekty message

Stop — anulowanie wysyłki​

Zatrzymuje trwającą wysyłkę masową. Zadanie w kolejce zostaje anulowane, a wszystkie rekordy pending otrzymują status cancelled. Rekordy już przetworzone jako success lub failed nie są zmieniane.

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

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

Parametry żądania​

ParametrTypWymaganyOpis
bulkMessageIdstringTakIdentyfikator wiadomości masowej do zatrzymania
{
"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"
}'

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 wiadomości masowe utworzone za pomocą tego API
  • Po zatrzymaniu wysyłki możesz użyć endpointu stats, aby sprawdzić liczbę anulowanych rekordów
  • Jeśli nie znaleziono wiadomości masowej, API zwraca błąd: bulkMessageNotFound