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
defaultPayloaddla wszystkich odbiorców ze scalaniem zpayloadkonkretnego odbiorcy (isMerge) - Zaplanowana wysyłka (
scheduleAt) - Wskazywanie odbiorców za pomocą
username(numer telefonu),userIdlubsessionId - Wysyłanie wielu wiadomości do tego samego użytkownika w jednym żądaniu masowym
- Opcjonalny
referenceIddo śledzenia rekordów w systemach zewnętrznych - Automatyczne przypisanie rozmów do użytkownika lub grupy roboczej po wysłaniu (
action)
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
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
channelUsername | string | Tak | Numer kanału WhatsApp używany do wysłania wiadomości (np. "908506669933") |
connectorBrand | string | Tak | Marka konektora kanału. Obecnie obsługiwana wartość: "whatsapp" |
title | string | Nie | Tytuł kampanii. Używany do wyświetlania w panelu. Domyślnie: "-" |
scheduleAt | string (ISO 8601) | Nie | Zaplanowana data i godzina wysyłki (np. "2026-06-10T10:00:00.000Z"). Jeśli pominięto, wiadomości są wysyłane natychmiast. |
defaultPayload | object | Warunkowo* | Domyślny ładunek szablonu stosowany do wszystkich odbiorców. Wymagany, jeśli odbiorca nie podaje własnego payload. |
recipients | array | Tak | Lista odbiorców. Minimum 1, maksimum 5 000 odbiorców. |
action | object | Nie | Dział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.
| Pole | Typ | Opis |
|---|---|---|
username | string | Numer telefonu odbiorcy (np. "905554443322"). Jeśli użytkownik nie istnieje w systemie, zostanie utworzony automatycznie. |
userId | string | Identyfikator istniejącego użytkownika w systemie. |
sessionId | string | Identyfikator istniejącej sesji rozmowy w systemie. |
referenceId | string | Opcjonalny 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. |
payload | object | Ładunek szablonu dla konkretnego odbiorcy (opcjonalny). Jeśli isMerge: true, jest scalany z defaultPayload. |
isMerge | boolean | Zastępuje zachowanie scalania dla tego odbiorcy (opcjonalne). Jeśli pominięto, używane jest defaultPayload.isMerge. |
Struktura działania
| Pole | Typ | Opis |
|---|---|---|
action.key | string | "assign-to-user" przypisuje rozmowę do konkretnego agenta; "assign-to-workgroup" przypisuje ją do grupy roboczej. |
action.value | string | Identyfikator 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
}
| Pole | Typ | Wymagany | Opis |
|---|---|---|---|
type | string | Tak | Typ ładunku. Dla wiadomości szablonowych: "template" |
template.templateName | string | Tak* | Nazwa szablonu zarejestrowanego w Meta. W ładunkach odbiorców jest opcjonalna, gdy używane jest isMerge: true (dziedziczona z ładunku domyślnego). |
template.languageCode | string | Nie | Kod języka szablonu (np. "tr", "en", "tr-TR", "en-US"). Musi dokładnie odpowiadać językowi zarejestrowanemu w Meta. |
template.variables | array | Nie | Lista zmiennych stosowanych do komponentów szablonu. Szczegóły poniżej. |
isMerge | boolean | Nie | true: ładunek odbiorcy jest głęboko scalany z defaultPayload. false lub pominięte: ładunek odbiorcy całkowicie zastępuje defaultPayload. |
- Jeśli
defaultPayload.isMerge: truei odbiorca podaje własnypayload, stosowane jest głębokie scalanie. - Przy głębokim scalaniu odbiorca może podać tylko
variables;templateNameilanguageCodesą dziedziczone z ładunku domyślnego. - Pole
isMergeodbiorcy zastępujedefaultPayload.isMerge. - Jeśli odbiorca nie podaje
payload, zawsze używany jestdefaultPayload.
Struktura zmiennych
Każdy element tablicy variables odpowiada komponentowi szablonu. Typ komponentu (type) może wystąpić w tablicy tylko raz.
| type | Opis | parameters | cards |
|---|---|---|---|
"HEADER" | Komponent nagłówka szablonu. Zmienna tekstowa lub adres URL multimediów (obraz, wideo, dokument) | Tak | — |
"BODY" | Zmienne tekstu treści szablonu | Tak | — |
"BUTTONS" | Zmienne dynamicznego sufiksu URL dla przycisków | Tak | — |
"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" }
- 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"]
}
Komponent CAROUSEL
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"]
}
]
}
]
}
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" }
]
}'
- Odbiorcy podani przez
usernamesą 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
isMergenie jest podane, każdy odbiorca bezpośrednio używadefaultPayload
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" }]
}
- 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}}, aparameters[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"]
}
]
}
}
}
]
}
- Dzięki
isMerge: truetemplateNamenie musi być powtarzane w ładunku każdego odbiorcy - Tablica
variableskaż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 jestdefaultPayload.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"]
}
]
}
}
}
]
}
- Parametry
BUTTONSsą 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}}, toparameters[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" }
}
]
}
}
}
]
}
scheduleAtnależy podać w strefie czasowej UTC (np. dla godziny 10:00 czasu tureckiego użyj07: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
actionrozmowy 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
| Status | Opis |
|---|---|
Channel not found | Nie znaleziono zweryfikowanego kanału pasującego do channelUsername i connectorBrand |
Channel is not verified | Dopasowany kanał istnieje, ale nie został jeszcze zweryfikowany |
invalidRequest | Dla odbiorcy podano kilka identyfikatorów lub brakuje wymaganego ładunku |
channelNotFound | Nie znaleziono aktywnego kanału pasującego do podanego channelId |
schema-error | Pole 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
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
bulkMessageId | string | Tak | Identyfikator 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
| Pole | Typ | Opis |
|---|---|---|
stats.pending | number | Liczba rekordów nadal oczekujących w kolejce |
stats.success | number | Liczba rekordów pomyślnie przekazanych do wysyłki |
stats.failed | number | Liczba rekordów, w których wystąpił błąd dostarczania |
stats.cancelled | number | Liczba anulowanych rekordów |
stats.total | number | Łączna liczba rekordów (pending + success + failed + cancelled) |
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.
- endpoint stats: pokazuje status zadania wysyłki (pending, success, failed, cancelled)
- endpoint message-stats: pokazuje rzeczywisty status wiadomości (
pending,sending,sent,delivered,read,erroritd.) - 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).
- 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
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
bulkMessageId | string | Tak | Identyfikator 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
| Pole | Typ | Opis |
|---|---|---|
pending | number | Wiadomości jeszcze niewysłane |
sending | number | Wiadomości aktualnie wysyłane |
sent | number | Wiadomości przekazane do WhatsApp, jeszcze niedostarczone |
delivered | number | Wiadomości dostarczone na telefon odbiorcy |
read | number | Wiadomości przeczytane przez odbiorcę |
deleted | number | Usunięte wiadomości |
warning | number | Wiadomości z ostrzeżeniami |
error | number | Wiadomości z błędami |
unknown | number | Wiadomości o nieznanym statusie |
not-sended | number | Wiadomości, których nie udało się wysłać |
no-message | number | Rekordy bez wiadomości (nadal w kolejce) |
total | number | Łączna liczba rekordów |
- Wysoka wartość
no-messageoznacza, że wysyłka nadal trwa - Wartość
deliveredpokazuje pomyślnie dostarczone wiadomości - Wartość
readmoż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
| Pole | Typ | Wymagany | Opis |
|---|---|---|---|
pagination | object | Nie | Ustawienia paginacji |
filtering | object | Nie | Kryteria filtrowania |
sorting | object | Nie | Ustawienia sortowania (np. {"createdAt": -1}) |
Struktura paginacji
| Pole | Typ | Domyślnie | Opis |
|---|---|---|---|
currentPage | number | 1 | Numer strony do pobrania |
pageItems | number | 50 | Liczba 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.
- Połącz
filteringipagination, aby tworzyć precyzyjne zapytania - Odpowiedź zawiera
options.pagination.totalCountioptions.pagination.totalPagesdo nawigacji - Filtr
message.statusdziała tylko w endpoincielist-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
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
bulkMessageId | string | Tak | Identyfikator wiadomości masowej do wyświetlenia |
options | object | Nie | Opcje 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
| Pole | Typ | Opis |
|---|---|---|
_id | string | Identyfikator rekordu |
bulkMessageId | string | Identyfikator wiadomości masowej, do której należy rekord |
userId | string | Identyfikator użytkownika-odbiorcy |
sessionId | string | Identyfikator sesji rozmowy |
messageId | string | Identyfikator wysłanej wiadomości (null, jeśli jeszcze nie wysłano) |
referenceId | string | Opcjonalny identyfikator referencyjny (jeśli podany) |
status | string | Status rekordu: pending, success, failed, cancelled |
message | object | Szczegóły wiadomości (tylko w list-with-messages) |
Porównanie List i List-With-Messages
| Cecha | list | list-with-messages |
|---|---|---|
| Paginacja | Tak | Tak |
| Filtrowanie | Tak (tylko pola rekordu) | Tak (pola rekordu i wiadomości) |
| Obiekt message | Nie | Tak (jeśli istnieje messageId) |
| Wydajność | Szybko | Średnio (wykonuje JOIN) |
| Filtr message.status | Niedostępny | Dostępny |
- 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
- Endpoint
listjest 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.statusdziała tylko wlist-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
Tej operacji nie można cofnąć. Zatrzymanej wysyłki nie można wznowić.
Parametry żądania
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
bulkMessageId | string | Tak | Identyfikator 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.
{}
- 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