Pular para o conteúdo principal

Documentação da Bulk Template Message API — v2

Esta API permite enviar mensagens de template a vários destinatários simultaneamente pelo canal de WhatsApp.

O envio das mensagens é processado de forma assíncrona; a requisição da API retorna imediatamente um bulkOperationId, enquanto as mensagens são colocadas em fila e processadas em segundo plano.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js
Formato da resposta

Todos os endpoints deste documento são custom functions. O corpo da resposta HTTP traz os campos da própria função (_id, title, pathString…) e a resposta real do endpoint em result. Os exemplos de resposta deste documento mostram o conteúdo de result:

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

Migração da v1​

A v2 funciona lado a lado com a v1, então você pode migrar no seu próprio ritmo. Os endpoints da v1 (/api/bulk-message/…, /api/bulk-message-records/…) serão desativados; novas integrações devem usar a v2.

  1. Mude os caminhos dos endpoints para a v2: …/api/bulk-message/… passa a ser …/api/v2/bulk-operation/…, e …/api/bulk-message-records/… passa a ser …/api/v2/bulk-operation-items/…. O corpo da requisição de send não muda; uma única requisição agora aceita até 100.000 destinatários em vez de 5.000.
  2. Envie bulkOperationId em vez de bulkMessageId nas requisições.
  3. Substitua stats.js por show.js.
  4. Leia as respostas com os novos nomes de campos da tabela abaixo.

Os endpoints da v2 só reconhecem operações em massa criadas com o send da v2. Para acompanhar uma mensagem em massa criada com a v1 antes da migração, continue usando os endpoints da v1 para ela.

Endpoints​

v1v2O que muda na resposta
bulk-message/send.jsv2/bulk-operation/send.js{ bulkMessageId } passa a ser { bulkOperationId }
bulk-message/stats.jsv2/bulk-operation/show.js{ bulkMessage, stats } passa a ser { bulkOperation }
bulk-message/message-stats.jsv2/bulk-operation/message-stats.jsOs contadores ficam na raiz em vez de em messageStats
bulk-message/stop.jsv2/bulk-operation/stop.jsNada
bulk-message-records/list.jsv2/bulk-operation-items/list.jsbulkMessageRecords passa a ser bulkOperationItems
bulk-message-records/list-with-messages.jsv2/bulk-operation-items/list-with-messages.jsO mesmo que list, e cada item também traz session

Nomes dos campos​

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 (mensagem em massa)bulkOperation (operação em massa)
bulkMessageRecord (registro)bulkOperationItem (item)
bulkMessageId nas requisições, na resposta de send e nos registrosbulkOperationId
username / userId / sessionId do registro, como enviadospayload.username / payload.userId / payload.sessionId
referenceId do registropayload.referenceId
payload do registro (o payload de template do destinatário)payload.payload
userId, sessionId, messageId do registro após o envioresult.userId, result.sessionId, result.messageId
status de registro successsucceeded
errorMessage nos registros com falhaerror.message, ao lado de error.code e error.retryable
—position (o índice do destinatário em recipients)
filtro {"status": "success"}{"status": "succeeded"}
filtro {"referenceId": "…"}{"payload.referenceId": "…"}
erros de send schema-error, invalidRequestzod-schema-error, com o caminho do campo inválido na mensagem

Principais recursos​

  • Envie mensagens de template em massa para 1 a 100.000 destinatários em uma única requisição
  • Variáveis personalizadas para cada destinatário (HEADER, BODY, BUTTONS, CAROUSEL)
  • defaultPayload compartilhado por todos os destinatários, com mesclagem do payload específico de cada destinatário (isMerge)
  • Envio agendado (scheduleAt)
  • Indique os destinatários por username (número de telefone), userId ou sessionId
  • Envie várias mensagens ao mesmo usuário em uma única requisição em massa
  • referenceId opcional para acompanhar registros em sistemas externos
  • Atribua automaticamente as conversas a um usuário ou grupo de trabalho após o envio (action)
aviso

Esta API só pode enviar templates que tenham sido aprovados pela Meta.

O nome do template e o código de idioma devem corresponder exatamente ao template cadastrado no Meta Business Manager.

Parâmetros da requisição​

Parâmetros de nível superior​

ParâmetroTipoObrigatórioDescrição
channelUsernamestringSimNúmero do canal de WhatsApp usado para enviar a mensagem (por exemplo "908506669933")
connectorBrandstringSimMarca do conector do canal. Valor atualmente aceito: "whatsapp"
titlestringNãoTítulo da campanha. Usado para exibição no painel. Padrão: "-"
scheduleAtstring (ISO 8601)NãoData e hora do envio agendado (por exemplo "2026-06-10T10:00:00.000Z"). Se omitido, as mensagens são enviadas imediatamente.
defaultPayloadobjectCondicional*Payload de template padrão aplicado a todos os destinatários. Obrigatório se um destinatário não informar o próprio payload.
recipientsarraySimLista de destinatários. Mínimo de 1, máximo de 100.000 destinatários.
actionobjectNãoAção aplicada à conversa após o envio. assign-to-user ou assign-to-workgroup.

*Se todos os destinatários informarem o próprio payload, o defaultPayload é opcional.

Estrutura do destinatário​

Para cada destinatário, deve ser informado exatamente um entre username, userId ou sessionId. Não é possível usar vários identificadores juntos, e omitir todos resultará em erro.

Para enviar várias mensagens ao mesmo usuário em uma única requisição em massa, adicione o mesmo identificador à lista de destinatários várias vezes.

CampoTipoDescrição
usernamestringNúmero de telefone do destinatário (por exemplo "905554443322"). Se o usuário não existir no sistema, ele é criado automaticamente.
userIdstringID de um usuário existente no sistema.
sessionIdstringID de uma sessão de conversa existente no sistema.
referenceIdstringID de referência opcional (máximo de 256 caracteres) para correspondência com registros de sistemas externos (CRM, pedido, ticket etc.). Deve ser único dentro do envio em massa, se informado.
payloadobjectPayload de template específico do destinatário (opcional). Se isMerge: true, ele é mesclado com o defaultPayload.
isMergebooleanSubstitui o comportamento de mesclagem para este destinatário (opcional). Se omitido, usa-se o defaultPayload.isMerge.

Estrutura da ação​

CampoTipoDescrição
action.keystring"assign-to-user" atribui a conversa a um atendente específico; "assign-to-workgroup" atribui a um grupo de trabalho.
action.valuestringID do usuário ou do grupo de trabalho de destino.

Estrutura do payload do template​

defaultPayload e o payload específico de cada destinatário têm a mesma estrutura. Para mensagens de template, é preciso informar type: "template".

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
CampoTipoObrigatórioDescrição
typestringSimTipo do payload. Para mensagens de template: "template"
template.templateNamestringSim*Nome do template cadastrado na Meta. Opcional nos payloads de destinatário quando se usa isMerge: true (herda do padrão).
template.languageCodestringNãoCódigo de idioma do template (por exemplo "tr", "en", "tr-TR", "en-US"). Deve corresponder exatamente ao idioma cadastrado na Meta.
template.variablesarrayNãoLista de variáveis aplicadas aos componentes do template. Detalhada abaixo.
isMergebooleanNãotrue: o payload do destinatário é mesclado em profundidade com o defaultPayload. false ou omitido: o payload do destinatário substitui completamente o defaultPayload.
Comportamento de isMerge
  • Se defaultPayload.isMerge: true e o destinatário informar o próprio payload, é aplicada uma mesclagem em profundidade.
  • Com a mesclagem em profundidade, o destinatário pode informar apenas variables; templateName e languageCode são herdados do payload padrão.
  • O campo isMerge do destinatário substitui o defaultPayload.isMerge.
  • Se um destinatário não informar um payload, o defaultPayload é sempre usado.

Estrutura das variáveis​

Cada item do array variables corresponde a um componente do template. Um tipo de componente (type) pode aparecer apenas uma vez no array.

typeDescriçãoparameterscards
"HEADER"Componente de cabeçalho do template. Variável de texto ou URL de mídia (imagem, vídeo, documento)Sim—
"BODY"Variáveis de texto do corpo do templateSim—
"BUTTONS"Variáveis de sufixo de URL dinâmico para botõesSim—
"CAROUSEL"Componentes de cartão para templates de carrossel—Sim

Formatos dos parâmetros​

O campo parameters pode ser informado em três formatos diferentes:

// 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" }
Qual formato devo usar?
  • Se o seu template da Meta usa marcadores como {{1}}, {{2}}, use o formato de array ou o de objeto com chaves numéricas.
  • Se o seu template usa marcadores nomeados, como {{firstName}} ou {{orderTotal}}, use o formato de objeto com chaves nomeadas.
  • Ao usar arrays, a ordem importa: o primeiro elemento corresponde a {{1}}, o segundo a {{2}}, e assim por diante.

Componente HEADER​

Use o componente HEADER quando o cabeçalho do template contiver mídia (imagem, vídeo, documento) ou texto dinâmico.

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

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

Componente BODY​

Usado para variáveis de texto dinâmicas dentro do corpo do 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​

Usado para botões com sufixos de URL dinâmicos. Se o template contiver vários botões de URL, apenas os botões com variáveis são indexados em sequência (botões sem variáveis ou botões FLOW são ignorados).

// 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"]
}

Em templates de carrossel, as variáveis dos componentes são definidas separadamente para cada cartão.

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

O tamanho do array cards deve corresponder exatamente ao número de cartões definidos no template.

Exemplos​

1. Template simples — sem variáveis, mesmo conteúdo para todos os destinatários​

Esta é a forma mais simples de enviar um template estático, sem variáveis, a vários destinatários.

{
"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" }
]
}'
dica
  • Os destinatários indicados por username são criados automaticamente se ainda não existirem no sistema
  • Todos os destinatários usam o mesmo defaultPayload; nenhum dado específico por destinatário é necessário
  • Quando isMerge não é especificado, cada destinatário usa diretamente o defaultPayload

2. Template com variáveis de corpo compartilhadas​

O mesmo template é enviado a todos os destinatários com valores de variáveis idênticos. O template contém marcadores como {{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" }]
}
dica
  • Neste exemplo, o corpo do template pode conter um texto como: "Aproveite {{1}} de desconto na nossa campanha! Oferta válida até {{2}}."
  • parameters[0] substitui {{1}}, enquanto parameters[1] substitui {{2}}

3. Template personalizado — variáveis por destinatário com isMerge​

Valores de variáveis diferentes são usados para cada destinatário. Ao definir isMerge: true no defaultPayload, os destinatários só precisam informar variables; templateName e languageCode são herdados do payload padrão.

Neste exemplo, o template inclui um cabeçalho de mídia e variáveis de corpo personalizadas.

{
"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"]
}
]
}
}
}
]
}
dica
  • Graças a isMerge: true, templateName não precisa ser repetido no payload de cada destinatário
  • O array variables de cada destinatário é totalmente independente
  • A URL da mídia do cabeçalho deve ser publicamente acessível
  • Se type for omitido no payload do destinatário, defaultPayload.type é herdado

4. Variável de botão de URL​

Use o componente BUTTONS quando o template contiver um botão com sufixo de URL dinâmico. Por exemplo, um código de rastreamento acrescentado à URL 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"]
}
]
}
}
}
]
}
dica
  • Os parâmetros de BUTTONS são associados conforme a ordem dos botões que contêm variáveis
  • Botões FLOW e botões sem variáveis são ignorados; a indexação se aplica apenas aos botões de URL dinâmica
  • Se a URL do botão do template for https://example.com/track/{{1}}, então parameters[0] substitui {{1}}

5. Envio agendado​

Agende o envio de uma mensagem para uma data e hora futuras. scheduleAt deve ser informado como um timestamp ISO 8601 em 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" }
}
]
}
}
}
]
}
dica
  • scheduleAt deve ser informado no fuso horário UTC (por exemplo, para 10:00 no horário da Turquia, use 07:00:00.000Z)
  • Este exemplo usa o formato de parâmetros nomeados; o template deve conter marcadores como {{name}} e {{discountRate}}
  • Com action, as conversas criadas pelo envio da mensagem são atribuídas automaticamente ao grupo de trabalho especificado

Resposta​

Uma requisição bem-sucedida retorna um bulkOperationId, que pode ser usado para acompanhar o processo de envio:

{
"bulkOperationId": "abc123xyz789"
}

Respostas de erro​

StatusDescrição
recipients field is requiredO campo recipients não foi enviado
Channel not foundNenhum canal verificado correspondente a channelUsername e connectorBrand foi encontrado
Channel is not verifiedO canal correspondente existe, mas ainda não foi verificado
zod-schema-errorUm campo do corpo da requisição falhou na validação do esquema (campo obrigatório ausente, tipo incorreto, valor não aceito, mais de um identificador em um destinatário ou payload ausente). A mensagem indica o campo, por exemplo recipients.0.referenceId: referenceId must be unique

O bulkOperationId retornado pode ser usado com os endpoints abaixo para consultar as estatísticas de envio e interromper o processo de envio.


Show — status e estatísticas da operação em massa​

Obtém a operação em massa com o seu status atual e os contadores de envio dos seus itens, na chave bulkOperation.

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

Parâmetros da requisição​

ParâmetroTipoObrigatórioDescrição
bulkOperationIdstringSimID da operação em massa a acompanhar (retornado por 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"
}'

Resposta​

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

Campos de show​

Os campos ficam em bulkOperation.

CampoTipoDescrição
statusstringStatus da operação em massa: preparing, scheduled, pending, running, stopping, stopped, completed, failed
progress.totalnumberNúmero total de itens
progress.pendingnumberItens ainda aguardando na fila
progress.succeedednumberItens processados com sucesso para envio
progress.failednumberItens que tiveram um erro de envio
progress.cancellednumberItens cancelados por stop
progress.unknownnumberItens cujo resultado não pôde ser determinado
result.outcomestringResultado final depois que a operação em massa termina: success, partial, all-failed, cancelled, unknown
result.hasErrorsbooleantrue se pelo menos um item falhou
scheduleAtstringHorário do envio agendado (somente para operações em massa agendadas)
startedAt, completedAtstringQuando o envio começou e terminou
observação

progress.succeeded indica que a mensagem foi repassada com sucesso pelo sistema. Isso não garante que a Meta entregou a mensagem ao destinatário. As atualizações de status posteriores geradas pela Meta (como delivered, read ou failed) não afetam esse contador e não são refletidas aqui.

Show e Message Stats
  • Endpoint show: mostra o status de envio dos itens (pending, succeeded, failed, cancelled, unknown)
  • Endpoint message-stats: mostra o status real da mensagem (pending, sending, sent, delivered, read, error etc.)
  • Um item pode estar succeeded, mas a mensagem ainda pode não ter sido entregue/lida

ID de referência​

O referenceId é um campo opcional que você pode usar para associar os itens de envio a um ID do seu próprio sistema para fins de acompanhamento (por exemplo, número do pedido, ID do ticket). Ele é retornado em cada item como payload.referenceId.

Se informado, ele deve ser único dentro do envio em massa (máximo de 256 caracteres).

Importante
  • Não é obrigatório
  • Não pode ser duplicado dentro da mesma operação em massa
  • Pode ser reutilizado em operações em massa diferentes

Message Stats — status das mensagens do WhatsApp​

Obtém as estatísticas de status das mensagens de uma operação em massa. Diferentemente do endpoint show, este mostra o message.status real das mensagens enviadas, em vez do status do item.

Status possíveis das mensagens: 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

Parâmetros da requisição​

ParâmetroTipoObrigatórioDescrição
bulkOperationIdstringSimID da operação em massa a consultar
{
"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"
}'

Resposta​

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

Campos de message stats​

CampoTipoDescrição
pendingnumberMensagens ainda não enviadas
sendingnumberMensagens sendo enviadas no momento
sentnumberMensagens entregues ao WhatsApp, ainda não entregues ao destinatário
deliverednumberMensagens entregues ao telefone do destinatário
readnumberMensagens lidas pelo destinatário
deletednumberMensagens excluídas
warningnumberMensagens com avisos
errornumberMensagens com erros
unknownnumberMensagens com status desconhecido
not-sendednumberMensagens que não puderam ser enviadas
no-messagenumberItens sem mensagem (ainda na fila, com falha ou cancelados)
totalnumberTotal de itens
Dicas de uso
  • Uma contagem alta de no-message enquanto a operação em massa está running indica que o envio ainda está em andamento
  • A contagem de delivered mostra as mensagens entregues com sucesso
  • A contagem de read pode ser usada para medir o engajamento da campanha
  • Você pode consultar este endpoint periodicamente para acompanhamento em tempo real

Estrutura de options — paginação, filtragem e ordenação​

O parâmetro options usado nos endpoints list e list-with-messages oferece uma estrutura padrão para paginação, filtragem e ordenação.

Campos de options​

CampoTipoObrigatórioDescrição
paginationobjectNãoConfigurações de paginação
filteringobjectNãoCritérios de filtragem
sortingobjectNãoConfigurações de ordenação (por exemplo, {"position": 1})

Estrutura de paginação​

Se pagination não for enviado, é retornada a primeira página com até 50 itens. Se for enviado, currentPage é obrigatório.

CampoTipoPadrãoDescrição
currentPagenumber—Número da página a obter (obrigatório quando pagination é enviado)
pageItemsnumber50Número de itens por página (máximo: 50)

Estrutura de filtragem​

A filtragem usa o formato de consulta do MongoDB sobre os campos do item, com os nomes de campos exatamente como aparecem na resposta (por exemplo status, payload.referenceId, result.messageId). No endpoint list-with-messages, também é possível filtrar pelos campos da mensagem (por exemplo, message.status).

// Filter by item status
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}

// Filter by referenceId
{
"options": {
"filtering": {
"payload.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"]
}
}
}
}

// List items that have no message (only list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}

Estrutura de ordenação​

A ordenação usa o formato de ordenação do MongoDB. 1 significa crescente e -1 significa decrescente. position é a ordem do destinatário no array recipients da requisição (a partir de 0).

// Sort in the order the recipients were sent in the request
{
"options": {
"sorting": {
"position": 1
}
}
}

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

Exemplo de uso combinado​

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

Este exemplo lista a segunda página das mensagens entregues, na ordem dos destinatários.

Dicas práticas
  • Combine filtering e pagination para consultas direcionadas
  • A resposta inclui options.pagination.totalCount e options.pagination.totalPages para navegação
  • O filtro message.status só funciona no endpoint list-with-messages

Items — detalhes e listagem de itens​

Lista todos os itens de envio de uma operação em massa. Cada item representa uma entrada do array recipients.

List — lista de itens​

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

Parâmetros da requisição​

ParâmetroTipoObrigatórioDescrição
bulkOperationIdstringSimID da operação em massa a listar
optionsobjectNãoOpções de paginação, filtragem e ordenação. Veja Estrutura de options para mais detalhes.

Requisição — uso básico​

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

Requisição — filtrar por um status específico​

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

Lista apenas os itens de envio com falha, com o motivo em error.

Resposta​

{
"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 com detalhes das mensagens​

Tem os mesmos recursos do endpoint list (paginação, filtragem, ordenação). A diferença: cada item também traz os objetos message e session relacionados, quando existem. Isso permite ver o status da mensagem (delivered, read, error etc.) e o payload em uma única consulta.

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

Requisição — uso básico​

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

Requisição — filtrar por status da mensagem​

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

Este exemplo obtém apenas as mensagens com status "delivered".

Requisição — listar mensagens com falha​

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

Usado para revisar as mensagens que tiveram erros de envio.

Resposta​

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

Campos do item​

CampoTipoDescrição
_idstringID do item
bulkOperationIdstringID da operação em massa à qual este item pertence
positionnumberOrdem do destinatário no array recipients da requisição, a partir de 0
payloadobjectO destinatário exatamente como foi enviado na requisição (username / userId / sessionId, referenceId, payload, isMerge)
statusstringStatus do item: pending, succeeded, failed, cancelled, unknown
errorobjectSomente em itens failed: code, message e retryable
result.userIdstringID do usuário destinatário
result.sessionIdstringID da sessão de conversa
result.messageIdstringID da mensagem enviada (ausente se nenhuma mensagem foi enviada)
completedAtstringQuando o item foi processado
messageobjectDetalhes da mensagem (somente em list-with-messages)
sessionobjectDetalhes da conversa (somente em list-with-messages)

Comparação entre List e List-With-Messages​

Recursolistlist-with-messages
PaginaçãoSimSim
FiltragemSim (somente campos do item)Sim (campos do item e da mensagem)
Message / SessionNãoSim (se existirem)
DesempenhoRápidoMédio (executa JOIN)
Filtro message.statusIndisponívelDisponível
Cenários de uso
  • list: liste rapidamente todos os itens, filtre por referenceId, verifique os status dos itens
  • list-with-messages: veja os status das mensagens do WhatsApp (delivered, read), inspecione os payloads das mensagens
  • Exemplos de filtragem:
    • {"status": "failed"} — itens de envio com falha
    • {"payload.referenceId": "ORDER-123"} — um ID de referência específico
    • {"message.status": "delivered"} — mensagens entregues (somente list-with-messages)
    • {"message.status": "read"} — mensagens lidas (somente list-with-messages)
    • {"message.status": "error"} — mensagens com erros (somente list-with-messages)
    • {"message.status": {"$in": ["delivered", "read"]}} — mensagens entregues ou lidas (somente list-with-messages)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — mensagens, exceto as com erro e as não enviadas (somente list-with-messages)
    • {"message": {"$exists": false}} — itens sem mensagem (somente list-with-messages)
    • {"status": {"$in": ["succeeded", "pending"]}} — itens bem-sucedidos ou pendentes
Observações sobre desempenho e uso
  • O endpoint list é mais rápido; prefira-o para verificações gerais de status
  • Use list-with-messages quando os detalhes da mensagem forem necessários
  • O máximo de itens por página (pageItems) é 50; o padrão é 50 se não for especificado
  • O filtro message.status só funciona em list-with-messages
  • Itens sem result.messageId não têm objeto message

Stop — cancelar o envio​

Interrompe o envio em andamento de uma operação em massa. Todos os itens pending passam para o status cancelled e a operação em massa fica stopped. Os itens que já foram processados como succeeded ou failed não são afetados. Uma operação em massa agendada também pode ser interrompida antes do horário de scheduleAt.

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

Esta ação não pode ser desfeita. Um envio interrompido não pode ser retomado.

Parâmetros da requisição​

ParâmetroTipoObrigatórioDescrição
bulkOperationIdstringSimID da operação em massa a interromper
{
"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"
}'

Resposta​

Em uma requisição bem-sucedida, o corpo da resposta fica vazio. Um status HTTP 200 indica que a operação foi concluída com sucesso.

{}
dica
  • Somente as operações em massa criadas por esta API podem ser interrompidas
  • Depois de interromper um envio, você pode usar o endpoint show para verificar o número de itens cancelados (bulkOperation.progress.cancelled)
  • Se a operação em massa não for encontrada, a API retorna o erro: Bulk operation not found.