Criar e pré-visualizar campanha
Cria uma campanha de mensagem em massa por template e confere o tamanho do público antes de enviar.
Uma campanha (broadcast) envia o mesmo template aprovado pela Meta a um público. Você escolhe o template, as variáveis e o público; a plataforma resolve a lista de destinatários, remove quem não pode receber e a guarda. Depois é só enviar. Use primeiro a pré-visualização para ver quantas pessoas realmente receberão.
Pré-visualizar o público
Resolve o público sem criar nada. Devolve o total que casou e o total que realmente receberá depois dos filtros de consentimento e de quem pediu para parar. Pode ser chamada a cada mudança de filtro.
/api/v1/admin/whatsapp/broadcasts/previewAdminConta quantas pessoas o público alcança e quantas receberão
Corpo da requisição
typestringobrigatórioall_customersusergrouplist_of_user_idsphone_listfiltersusergroup_idstringusergroup.user_idsarraylist_of_user_ids.phone_numbersarrayphone_list.filtersobjectfilters: tag, last_purchase_within_days, has_orders_count_min.Exemplo de requisição (Pré-visualizar o público)
curl -X POST "$BASE_URL/api/v1/admin/whatsapp/broadcasts/preview" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "filters",
"filters": {
"last_purchase_within_days": 90,
"has_orders_count_min": 2
}
}'Resposta (Pré-visualizar o público)
{
"matched_count": 1200,
"will_send_count": 820,
"marketing_optin_required": true
}Campos da resposta
matched_countintegerwill_send_countintegermatched_count menos quem não deu consentimento (se a loja exige) e quem pediu para parar.marketing_optin_requiredbooleantrue quando a loja só envia a quem deu consentimento de marketing.Erros (Pré-visualizar o público)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo inválido, type ausente ou desconhecido, ou usergroup_id ausente com usergroup. | {"error":"audience.type required"} |
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O módulo WhatsApp Commerce está desligado na loja, o usuário não é administrador ou não tem o privilégio exigido. | {"error":"module_disabled","module":"whatsapp-commerce"} ou {"error":"insufficient privileges","required":"manage_settings"} ou {"error":"admin access required"} |
Criar campanha
Resolve o público, aplica os filtros e grava a campanha com os destinatários. Por padrão fica em rascunho (R) e você chama a rota de envio. Com send_immediately, ela já entra em envio na mesma chamada. Não use send_immediately junto com scheduled_at.
/api/v1/admin/whatsapp/broadcastsAdminCria uma campanha como rascunho, ou já a coloca em envio
Corpo da requisição
namestringobrigatóriotemplate_namestringobrigatóriotemplate_languagestringpt_BR.template_paramsobject{"1":"...","2":"..."}. O mesmo valor vai para todos: não há personalização por destinatário.scheduled_atstringaudienceobjectobrigatórioQuem deve receber.
typestringobrigatórioall_customersusergrouplist_of_user_idsphone_listfiltersusergroup_idstringusergroup.user_idsarraylist_of_user_ids.phone_numbersarrayphone_list. Repetidos são descartados.filtersobjectCritérios, com filters. Todos se combinam.
tagstringlast_purchase_within_daysintegerhas_orders_count_minintegersend_immediatelybooleanpadrão: falsetrue cria e já coloca em envio.Exemplo de requisição (Criar campanha)
curl -X POST "$BASE_URL/api/v1/admin/whatsapp/broadcasts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Black Friday VIP",
"template_name": "black_friday_vip",
"template_language": "pt_BR",
"template_params": {
"1": "30%",
"2": "30/11"
},
"audience": {
"type": "filters",
"filters": {
"last_purchase_within_days": 90
}
},
"send_immediately": false
}'Resposta (Criar campanha)
{
"success": true,
"broadcast": {
"id": "f0fb5296-bc6b-46a8-a772-f5d5a78627fd",
"name": "Black Friday VIP",
"template_name": "black_friday_vip",
"template_language": "pt_BR",
"template_params": {
"1": "30%",
"2": "30/11"
},
"status": "R",
"created_by": "d4613dde-ac7a-431c-9232-50d8cd6ad5fc",
"total_recipients": 820,
"sent_count": 0,
"delivered_count": 0,
"read_count": 0,
"failed_count": 0,
"skipped_count": 130,
"audience": {
"type": "filters",
"filters": {
"last_purchase_within_days": 90
}
},
"created_at": "2026-10-11T21:50:00Z",
"updated_at": "2026-10-11T22:05:00Z"
},
"immediately_sent": false
}{
"success": true,
"broadcast": {
"id": "f0fb5296-bc6b-46a8-a772-f5d5a78627fd",
"name": "Black Friday VIP",
"template_name": "black_friday_vip",
"template_language": "pt_BR",
"template_params": {
"1": "30%",
"2": "30/11"
},
"status": "R",
"created_by": "d4613dde-ac7a-431c-9232-50d8cd6ad5fc",
"started_at": "2026-10-11T22:00:00Z",
"total_recipients": 820,
"sent_count": 400,
"delivered_count": 380,
"read_count": 210,
"failed_count": 5,
"skipped_count": 130,
"audience": {
"type": "filters",
"filters": {
"last_purchase_within_days": 90
}
},
"created_at": "2026-10-11T21:50:00Z",
"updated_at": "2026-10-11T22:05:00Z"
},
"immediately_sent": false,
"send_error": "whatsapp broadcast: cannot send in status ...",
"send_error_message": "Broadcast saved as draft. Press Send in the detail view to retry."
}Campos da resposta
successbooleantrue.broadcastobjectA campanha criada.
idstringnamestringtemplate_namestringtemplate_languagestringpt_BR.template_paramsobjectstatusstringRPADR rascunho, P enviando (também usada para enfileirada), A concluída, D cancelada.created_bystringscheduled_atstringstarted_atstringfinished_atstringtotal_recipientsintegersent_countintegerdelivered_countintegerread_countintegerfailed_countintegerskipped_countintegeraudienceobjectcreated_atstringupdated_atstringimmediately_sentbooleantrue se já entrou em envio.send_errorstringErros (Criar campanha)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo inválido; name ou template_name ausente; audience.type ausente; erro ao resolver o público; send_immediately com scheduled_at (código whatsapp.broadcasts.send_now_with_schedule); ou send_immediately com público vazio (código whatsapp.broadcasts.empty_audience). | {"error":"Failed to create broadcast: whatsapp broadcast: name and template_name required"} |
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O módulo WhatsApp Commerce está desligado na loja, o usuário não é administrador ou não tem o privilégio exigido. | {"error":"module_disabled","module":"whatsapp-commerce"} ou {"error":"insufficient privileges","required":"manage_settings"} ou {"error":"admin access required"} |