Markdown
Referência · envio

Enviar mensagens

Envie texto livre na janela de atendimento ou use um template aprovado, com os anexos e botões previstos no modelo.

POST/public/v1/messages
Escolha text ou template, nunca os dois. Os modelos dos exemplos são ilustrativos: consulte os templates do seu número e use os nomes e campos retornados.

Enviar um template (link para esta seção)

Este exemplo usa um modelo com duas variáveis numeradas: nome da pessoa e número do pedido. Pode ser enviado dentro ou fora da janela de atendimento.

cURL · enviar template
curl -X POST https://api.patrociniotech.com/public/v1/messages \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: aviso-pedido-8421-v1" \
  -d '{
  "to": "5521999999999",
  "phone_number_id": "SEU_NUMERO_ID",
  "template": "aviso_entrega",
  "language": "pt_BR",
  "variables": [
15 linhas

Resposta de envio aceito (link para esta seção)

JSON · HTTP 200
{
  "success": true,
  "data": {
    "message_id": "wamid.EXEMPLO",
    "status": "sent",
    "to": "5521999999999",
    "client_ref": "pedido-8421"
  }
}

sent confirma que a Meta aceitou o envio. Guarde message_id e acompanhe message.status no webhook para confirmar entrega, leitura ou falha.

Guarde também o to da resposta: ele identifica o destinatário reconhecido pela Meta. Mantenha o status no seu sistema a partir dos eventos; para conferir uma mensagem já identificada, use a consulta abaixo.

Consultar um envio sem reenviar (link para esta seção)

GET/public/v1/messages/{message_id}/status

Informe o message_id devolvido no envio. A consulta lê o estado registrado na Patrocinio Tech, não envia uma mensagem nem consulta o telefone na Meta. Somente mensagens de saída da empresa autenticada são acessíveis.

cURL · consultar status
curl "https://api.patrociniotech.com/public/v1/messages/wamid.EXEMPLO/status" \
  -H "Authorization: Bearer SUA_CHAVE"
JSON · estado registrado
{
  "success": true,
  "data": {
    "message_id": "wamid.EXEMPLO",
    "status": "delivered",
    "client_ref": "pedido-8421",
    "phone_number_id": "SEU_NUMERO_ID",
    "to": "5521999999999",
    "created_at": "2026-11-06T12:00:00Z",
    "message_at": "2026-11-06T12:00:00Z",
    "checked_at": "2026-11-06T12:01:00Z",
    "error": null
  }
}
CampoInterpretação
statussent, delivered, read, played, failed ou unknown. unknown indica ausência de um estado reconhecido; não é confirmação de falha.
errorSomente em failed: code numérico da Meta, quando preservado, reason estável da integração e message em português. O texto bruto não é exposto; code pode ser nulo.
created_at / message_atHorários UTC do registro e da mensagem/última tentativa. Não são o horário de entrega ou leitura; esses horários não são disponibilizados nesta consulta.
checked_atHorário desta consulta. Não comprova que chegou um novo evento da Meta nesse instante.
O webhook continua sendo o caminho principal. Use esta consulta para conciliar estados pendentes, com intervalo e tentativas limitados; ela também consome a cota de 600 requisições por minuto por chave. Codifique o identificador no caminho da URL com encodeURIComponent(message_id).

404 message_not_found pode significar identificador incorreto, registro ainda não persistido, removido pela retenção ou pertencente a outra conta. Não comprova que a mensagem deixou de ser enviada nem autoriza reenvio automático. Sem message_id, preserve a operação e a chave de idempotência para recuperar o aceite original.

Consultar quando o envio ficou sem resposta (link para esta seção)

GET/public/v1/messages/status

Se o POST terminou em timeout ou 5xx antes de devolver o message_id, consulte com a Idempotency-Key original. A leitura encontra inclusive a reserva da tentativa, sem enviar outra mensagem nem liberar a chave.

cURL · consultar pela chave original
curl "https://api.patrociniotech.com/public/v1/messages/status" \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Idempotency-Key: aviso-pedido-8421-v1"

Para uma mensagem já registrada, também é possível consultar por client_ref, de até 64 caracteres. Informe apenas uma das opções por chamada. Use uma referência por operação; se houver duas tentativas com a mesma referência, a API retorna 409 ambiguous_client_ref e não escolhe uma delas.

cURL · consultar pela referência
curl --get "https://api.patrociniotech.com/public/v1/messages/status" \
  -H "Authorization: Bearer SUA_CHAVE" \
  --data-urlencode "client_ref=pedido-8421"
data.resolutionO que significa
matchedA mensagem foi localizada no banco. data.message traz message_id, status, destinatário, horários e error, no mesmo formato da consulta por ID. message_id pode ser null em uma recusa anterior ao aceite.
acceptedExiste um aceite durável da Meta, mas o registro local não foi concluído. message traz o ID original e status sent; isso ainda não confirma entrega. Preserve a operação para reconciliação.
unconfirmedExiste uma reserva sem confirmação do envio. message é null. Não significa failed e não permite criar uma nova chave para enviar de novo.
JSON · tentativa ainda sem confirmação
{
  "success": true,
  "data": {
    "lookup": "idempotency_key",
    "resolution": "unconfirmed",
    "message": null,
    "checked_at": "2026-11-06T12:01:00Z",
    "retention": {
      "idempotency_days": 2,
      "messages_days": 365,
      "measured_from": "created_at"
    }
  }
}
Uma consulta por client_ref só encontra tentativas já persistidas. Para timeout antes desse registro, use a chave de idempotência. Em qualquer consulta, 404 message_not_found não comprova que o envio falhou: pode haver processamento em andamento ou remoção pela retenção.

retention informa os prazos configurados no momento da consulta, contados da criação. São dois dias para a reserva e 365 dias para mensagens por padrão; a manutenção é periódica. Mantenha seu histórico de operações e não use o fim desse prazo como autorização para repetir um envio incerto.

Repetir a operação com segurança (link para esta seção)

Gere uma Idempotency-Key por mensagem e salve-a antes de enviar. Em falha de conexão ou 5xx, repita com a mesma chave e o mesmo corpo.

ResultadoComo agir
200 · idempotent_replay: trueA resposta é de uma operação já aceita. Use o message_id retornado; a repetição não dispara outro envio.
409 · idempotency_in_flightA operação está em andamento ou sem confirmação. Aguarde e repita com a mesma chave. Se persistir, confira os eventos antes de iniciar outro envio.
409 · idempotency_conflictA chave pertence a outro conteúdo. Confira a operação original; use outra chave somente para uma nova mensagem intencional.
409 · idempotency_legacy_unverifiedO registro antigo não permite comparar o conteúdo. Verifique o envio original e os eventos antes de outra tentativa.
Não gere outra chave para contornar uma tentativa sem confirmação. A reserva não é liberada automaticamente após cinco minutos. A proteção dura pelo período de retenção; mantenha o histórico da operação também no seu sistema.

Dados recusados antes do envio podem ser corrigidos. Para tratar limites e indisponibilidade, use a política de novas tentativas.

Enviar texto livre (link para esta seção)

O contato precisa ter escrito para o mesmo número da empresa nas últimas 24 horas. Confirme a janela de atendimento quando necessário; ela não determina a gratuidade.

cURL · enviar texto livre
curl -X POST https://api.patrociniotech.com/public/v1/messages \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: texto-pedido-8421-v1" \
  -d '{
  "to": "5521999999999",
  "phone_number_id": "SEU_NUMERO_ID",
  "text": "Seu pedido saiu para entrega.",
  "client_ref": "pedido-8421"
}'

Enviar um template com PDF (link para esta seção)

O cabeçalho DOCUMENT exige o arquivo em cada envio. Este exemplo combina um PDF, variáveis nomeadas e um botão de link dinâmico.

cURL · enviar template com PDF
curl -X POST https://api.patrociniotech.com/public/v1/messages \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: bilhete-pedido-8421-v1" \
  -d '{
  "to": "5521999999999",
  "phone_number_id": "SEU_NUMERO_ID",
  "template": "entrega_pedido_documento",
  "language": "pt_BR",
  "variable_names": [
26 linhas
A Meta precisa acessar o link sem uma sessão de navegador. Use HTTPS e mantenha o arquivo disponível durante o envio. A amostra da aprovação não substitui o documento do pedido; para enviar sem PDF, selecione um template sem esse cabeçalho.

Enviar um código de autenticação (link para esta seção)

Use um modelo AUTHENTICATION com botão OTP. A API preenche o corpo e o botão nativo com o mesmo otp_code. O índice suportado é 0.

cURL · autenticação
curl -X POST https://api.patrociniotech.com/public/v1/messages \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: verificacao-operacao-1234-v1" \
  -d '{
  "to": "5521999999999",
  "phone_number_id": "SEU_NUMERO_ID",
  "template": "codigo_verificacao",
  "language": "pt_BR",
  "otp_code": "123456",
  "otp_index": 0,
  "client_ref": "operacao-1234"
}'
Gere o código no seu servidor e valide prazo, destinatário, operação, uso único e tentativas. O texto de expiração do template não invalida o código nem apaga a mensagem. Veja validade do código e prazo de entrega.

Referência dos campos (link para esta seção)

Envie somente os campos documentados. Nomes desconhecidos, inclusive dentro de header_media e pix_order, retornam 422 invalid_request. Os detalhes indicam o campo a corrigir; ele não é ignorado para prosseguir com valores padrão.

Destinatário e conteúdo

CampoRegra
toObrigatório. Telefone internacional, com DDI e DDD, somente dígitos. Ex.: 5521999999999 (Brasil) ou 351912345678 (Portugal). O envio não acrescenta o país automaticamente.
phone_number_idID do seu número conectado. Sem ele, a API usa o número padrão da conta.
textTexto livre de até 4.096 caracteres. Exige janela aberta e não pode ser combinado com campos de template.
templateNome do modelo aprovado. Use em vez de text.
languageIdioma do modelo. Padrão: pt_BR.
reply_to_message_idOpcional. ID da mensagem recebida que será citada na resposta.

Variáveis e cabeçalho

CampoRegra
variablesUm valor por variável do corpo. Até 20 valores de 1.024 caracteres; a quantidade exigida vem do modelo.
variable_namesNomes associados aos valores em variables, para modelos NAMED. Use a ordem da listagem ou mantenha cada par nome/valor correspondente.
header_mediaObrigatório se o modelo exigir mídia. Objeto com type (document, image ou video), link HTTP(S) válido, sem usuário/senha ou espaços, e filename opcional para documento.
header_textAté 200 caracteres. Obrigatório se o cabeçalho de texto tiver uma variável; omita para cabeçalho fixo ou de mídia.

Botões e autenticação

CampoRegra
button_url_paramValor da parte variável de um botão de link. Até 200 caracteres; a API aceita um link dinâmico por template.
button_url_indexPosição do botão de link na lista, começando em zero. Padrão: 0.
coupon_code / coupon_indexCódigo de até 15 caracteres e posição do botão de cupom COPY_CODE. Não use para autenticação.
otp_codeCódigo de autenticação de até 15 caracteres, sem espaços ou caracteres de controle. variables pode ser omitido.
otp_indexPara autenticação, use 0 ou omita. Não combine OTP com anexo, cupom, link dinâmico ou PIX.
pix_orderPedido para um template de cobrança, com botão ORDER_DETAILS. Veja o exemplo abaixo.

Valores de variáveis não aceitam quebras de linha, tabulações ou mais de quatro espaços consecutivos. Nenhum valor é cortado para caber: a API informa o erro para você corrigir.

Marketing, consentimento e saída da lista (link para esta seção)

A API permite enviar um template MARKETING a um contato com aceite pending ou sem cadastro local. Isso não registra consentimento como accepted. Conserve no seu sistema a origem da lista e a evidência de que a pessoa espera essa comunicação.

Uma recusa de promoções em qualquer número da mesma empresa, ou um bloqueio no número de envio, impede novos envios de marketing com 422 marketing_not_allowed. Não há parâmetro para ignorar essa exclusão. A consulta de janela e preferência permite conferir o bloqueio antes; a API verifica novamente ao enviar.

Nas campanhas do painel, incluir contatos com aceite pendente exige confirmação de risco. Essa opção não transforma pendência em aceite e não inclui quem pediu para sair. A API de envio individual não recebe essa opção de campanha.

Uma saída de promoções não impede um aviso legítimo de pedido com template UTILITY ou um código solicitado com AUTHENTICATION. Use a categoria correspondente ao conteúdo; mudar a categoria não é uma forma de reenviar a promoção recusada.

Relacionar o envio ao seu pedido (link para esta seção)

client_ref é opcional, tem até 64 caracteres e volta nos eventos de status. Use um identificador único da operação, como pedido-8421-entrega-v1, para consultá-la depois. Ele ajuda na conciliação, mas não substitui a Idempotency-Key nem impede envios duplicados.

Guarde também message_id e phone_number_id: um pedido pode ter várias mensagens e mais de um número de envio.

Cobrança PIX (link para esta seção)

Disponível para template de detalhes do pedido e conta com pagamentos habilitados na Meta. Os valores são inteiros JSON em centavos; strings, decimais e booleanos são recusados. A API confere a soma dos itens e da taxa, sem arredondar valores.

Ver exemplo de cobrança e campos de pagamento
cURL · cobrança PIX
curl -X POST https://api.patrociniotech.com/public/v1/messages \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cobranca-pedido-8421-v1" \
  -d '{
  "to": "5521999999999",
  "phone_number_id": "SEU_NUMERO_ID",
  "template": "cobranca_emissao",
  "language": "pt_BR",
  "pix_order": {
26 linhas
Em pix_orderUso
reference_idReferência da cobrança no seu sistema. Até 64 caracteres.
pix_codeCopia e cola completo gerado pelo seu PSP para esta cobrança. Não use o texto ilustrativo acima.
merchant_name / key / key_typeNome do recebedor, chave PIX e tipo: CNPJ, CPF, EMAIL, PHONE ou EVP.
itemsAté 30 itens com name, amount unitário em centavos e quantity.
tax / total_amounttax é opcional, com padrão 0. Se total_amount for informado, deve ser igual a Σ(amount × quantity) + tax.
Limite numéricoCada valor e o total calculado devem caber em 9.007.199.254.740.991 centavos, limite de inteiro seguro da integração. Isso não substitui os limites da Meta ou do seu PSP.
goods_type / retailer_idgoods_type: digital-goods (padrão) ou physical-goods. retailer_id é opcional em cada item; sem ele, a posição identifica o item.

Validar um telefone (link para esta seção)

Se o cadastro contém apenas DDD e telefone, informe o país em country (ISO de duas letras) nesta consulta antes de enviar. Para um telefone já internacional, use + e DDI, ou envie somente os dígitos e omita country. Não presuma que todos os clientes usam o DDI 55.

POST/public/v1/validate
cURL · validar formato
curl -X POST https://api.patrociniotech.com/public/v1/validate \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"to": "(21) 99999-9999", "country": "BR"}'

Use o to normalizado quando data.valid for true. Essa consulta valida o formato; não confirma existência no WhatsApp nem autorização para envio.

valid=true não significa que a mensagem será entregue. Um telefone digitado errado pode ter formato válido. A Cloud API não oferece uma consulta prévia para confirmar se o destinatário tem WhatsApp.

Após enviar, guarde message_id e client_ref. Considere a entrega confirmada apenas ao receber message.status com delivered ou read. O aceite inicial sent ainda pode terminar em failed.

Se chegar error.reason=recipient_unreachable com error.code=131026, registre a falha e confira o telefone com o cliente por outro canal. Esse código não comprova ausência de WhatsApp. Evite repetições automáticas e variações do número sem confirmação.