Envio de mensagens

Envie mensagens de texto e templates (HSM) da Meta via WhatsApp. O contato é criado automaticamente se ainda não existir. O connection_id é opcional — sem ele, a conexão padrão da empresa é usada.

escopo: messages:send

Envia uma mensagem de texto via WhatsApp (UAZAPI ou Meta Cloud). O campo `to` aceita um telefone ou o código de um grupo ou comunidade do WhatsApp (`<id>@g.us`).

  • Envio para grupo: use em `to` o código do grupo, por exemplo `{ "to": "120363322649858630@g.us", "message": "Bom dia, pessoal!" }`. O código aparece em `external_chat_id` de GET /api/v1/contacts?is_group=true. A resposta traz também `group_jid` com o grupo que recebeu a mensagem.
  • Envio para comunidade: use em `to` o código da comunidade, por exemplo `{ "to": "120363302307113947@g.us", "message": "Aviso para todos" }`. A mensagem vai para o grupo de avisos da comunidade, e `group_jid` na resposta traz o código desse grupo de avisos.
  • Grupo e comunidade só saem por conexão UAZAPI ativa e conectada cujo número participa do grupo; conexão pela API oficial da Meta não envia para grupos. Sem `connection_id`, a API usa a única conexão que participa do grupo; se houver mais de uma, usa a última conexão em que o grupo conversou e, sem ela, responde 422 `CONNECTION_REQUIRED` para você escolher.
  • Um grupo de que o número da conexão já saiu ainda pode aparecer como grupo da empresa: nesse caso o provedor recusa e a resposta é 502 `PROVIDER_ERROR` com o detalhe do provedor.

Modelo de envio

Corpo da requisição
{
  "to": "5548999990000",
  "message": "Olá! Seu pedido foi confirmado.",
  "connection_id": "<opcional — UUID da conexão>"
}

Resposta (200)

Corpo da resposta
{
  "success": true,
  "data": {
    "wamid": "<id-da-meta-ou-provider>",
    "provider": "uazapi",
    "message_id": "<uuid>",
    "contact_id": "<uuid>"
  }
}

Erros

StatusCódigoQuando ocorre
400MISSING_FIELDCampo obrigatório ausente no corpo (to, message)
400INVALID_PHONENúmero de telefone não pôde ser normalizado
403CONTACT_OPTED_OUTContato pediu para não receber mensagens (opted_out_at)
403CONTACT_BLOCKEDContato bloqueado
403EXTERNAL_AI_DISABLEDIA externa desligada para o contato (o operador assumiu o atendimento). Só volta quando alguém religar pelo menu de IA no inbox; templates por /api/v1/send/template não são afetados
403GROUP_ANNOUNCE_ONLYGrupo em que só administradores enviam e o número da conexão não é administrador
404NOT_FOUNDconnection_id enviado não pertence à empresa
404GROUP_NOT_FOUNDCódigo de grupo ou comunidade em `to` não encontrado nesta empresa (ou o grupo de avisos da comunidade ainda não foi sincronizado)
409AMBIGUOUS_CONTACTO telefone ou o código de grupo está associado a mais de um contato
422CONNECTION_REQUIREDEnvio para grupo sem conexão possível: o connection_id informado não participa do grupo ou está desconectado, nenhuma conexão UAZAPI ativa e conectada participa dele, ou há mais de uma e é preciso escolher pelo connection_id
502PROVIDER_ERRORFalha no envio pelo provedor (UAZAPI/Meta), ou falha ao consultar as comunidades no provedor
502DELIVERY_UNCERTAINA Meta respondeu com erro, mas a mensagem pode ter chegado — não reenvie automaticamente. A mensagem fica registrada no histórico como `failed` com `error_type: "delivery_uncertain"`; confira com o contato antes de reenviar
503CONTACT_STATE_UNAVAILABLENão foi possível ler o estado do contato (indisponibilidade transitória) — re-tente após Retry-After; não é um estado do contato

Exemplo

curl
curl -s -X POST -H "Authorization: Bearer <sua-key>" -H "Content-Type: application/json" \
  -d '{"to":"5548999990000","message":"Olá! Seu pedido foi confirmado.","connection_id":"<opcional — UUID da conexão>"}' \
  https://www.prosalab.com/api/v1/send/message
escopo: messages:send

Envia uma mensagem de template/HSM aprovado na Meta Cloud. Template com variável (corpo, cabeçalho ou botão de URL) exige o array components — sem ele a Meta recebe o template sem preenchimento.

  • components é repassado à Meta EXATAMENTE como enviado — esta rota não monta, valida nem completa nenhum componente. Template com variável enviado sem components chega à Meta sem preenchimento; a falha é da Meta, não desta rota.
  • Botão de URL dinâmica: a Meta aceita UMA variável por botão, e apenas no FIM de uma URL já aprovada — o valor enviado em parameters[0].text é concatenado à base aprovada. index é a posição do botão no template ("0" para o primeiro), enviado como STRING. URL fora da base aprovada faz a Meta rejeitar o envio inteiro.
  • Não há endpoint para listar templates aprovados, e template_name/language_code NÃO são validados contra o catálogo antes do envio. Nome inexistente, idioma errado ou template não aprovado só falham na Meta e voltam como 502 PROVIDER_ERROR genérico — confira o nome e o idioma no Gerenciador da Meta antes de disparar.
  • Exige conexão WhatsApp Meta Cloud. Informando connection_id, ele PRECISA ser Meta Cloud; sem ele, a conexão Meta Cloud conectada da empresa é resolvida automaticamente. Conexão de outro tipo também volta como 502, não 400.
  • A mensagem é gravada com o template_name usado no disparo, o que permite auditar e deduplicar envios por template.

Modelo de envio

Corpo da requisição
{
  "to": "5548999990000",
  "template_name": "renovacao_proposta",
  "language_code": "pt_BR",
  "connection_id": "<opcional — UUID da conexão>",
  "components": [
    {
      "type": "body",
      "parameters": [
        {
          "type": "text",
          "text": "Maria"
        }
      ]
    },
    {
      "type": "button",
      "sub_type": "url",
      "index": "0",
      "parameters": [
        {
          "type": "text",
          "text": "aB3xK9"
        }
      ]
    }
  ]
}

Resposta (200)

Corpo da resposta
{
  "success": true,
  "data": {
    "wamid": "<id-da-meta>",
    "provider": "meta_cloud",
    "message_id": "<uuid>",
    "contact_id": "<uuid>"
  }
}

Erros

StatusCódigoQuando ocorre
400MISSING_FIELDCampo obrigatório ausente (to, template_name, language_code)
400INVALID_PHONENúmero de telefone não pôde ser normalizado
403CONTACT_OPTED_OUTContato pediu para não receber mensagens (opted_out_at)
403CONTACT_BLOCKEDContato bloqueado
404NOT_FOUNDconnection_id enviado não pertence à empresa
409DUPLICATE_SENDMesmo template ao mesmo contato dentro da janela (MARKETING: 24h por nome; UTILITY/AUTH: conteúdo idêntico em 10 min) — data traz message_id, sent_at e next_eligible_at; NÃO re-tente antes de next_eligible_at. data ausente quando a recusa vem de dois POSTs simultâneos (envio anterior ainda em voo)
502PROVIDER_ERRORFalha no envio pela Meta — template/idioma não aprovado, components inválido, URL fora da base aprovada ou conexão que não é Meta Cloud
502DELIVERY_UNCERTAINA Meta respondeu com erro, mas a mensagem pode ter chegado — não reenvie automaticamente. O envio entra no histórico como `failed` com `error_type: "delivery_uncertain"` e conta para o DUPLICATE_SEND dentro da janela
503CONTACT_STATE_UNAVAILABLENão foi possível ler o estado do contato (indisponibilidade transitória) — re-tente após Retry-After; não é um estado do contato

Exemplo

curl
curl -s -X POST -H "Authorization: Bearer <sua-key>" -H "Content-Type: application/json" \
  -d '{"to":"5548999990000","template_name":"renovacao_proposta","language_code":"pt_BR","connection_id":"<opcional — UUID da conexão>","components":[{"type":"body","parameters":[{"type":"text","text":"Maria"}]},{"type":"button","sub_type":"url","index":"0","parameters":[{"type":"text","text":"aB3xK9"}]}]}' \
  https://www.prosalab.com/api/v1/send/template
Envio de mensagens — Prosalab Developers