Enviar mensagens
Envie texto livre na janela de atendimento ou use um template aprovado, com os anexos e botões previstos no modelo.
/public/v1/messagestext 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 -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": [Resposta de envio aceito (link para esta seção)
{
"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)
/public/v1/messages/{message_id}/statusInforme 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 "https://api.patrociniotech.com/public/v1/messages/wamid.EXEMPLO/status" \
-H "Authorization: Bearer SUA_CHAVE"{
"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
}
}| Campo | Interpretação |
|---|---|
| status | sent, delivered, read, played, failed ou unknown. unknown indica ausência de um estado reconhecido; não é confirmação de falha. |
| error | Somente 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_at | Horá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_at | Horário desta consulta. Não comprova que chegou um novo evento da Meta nesse instante. |
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)
/public/v1/messages/statusSe 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 "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 --get "https://api.patrociniotech.com/public/v1/messages/status" \
-H "Authorization: Bearer SUA_CHAVE" \
--data-urlencode "client_ref=pedido-8421"| data.resolution | O que significa |
|---|---|
| matched | A 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. |
| accepted | Existe 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. |
| unconfirmed | Existe 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. |
{
"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"
}
}
}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.
| Resultado | Como agir |
|---|---|
| 200 · idempotent_replay: true | A resposta é de uma operação já aceita. Use o message_id retornado; a repetição não dispara outro envio. |
| 409 · idempotency_in_flight | A 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_conflict | A chave pertence a outro conteúdo. Confira a operação original; use outra chave somente para uma nova mensagem intencional. |
| 409 · idempotency_legacy_unverified | O registro antigo não permite comparar o conteúdo. Verifique o envio original e os eventos antes de outra tentativa. |
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 -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 -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": [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 -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"
}'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
| Campo | Regra |
|---|---|
| to | Obrigató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_id | ID do seu número conectado. Sem ele, a API usa o número padrão da conta. |
| text | Texto livre de até 4.096 caracteres. Exige janela aberta e não pode ser combinado com campos de template. |
| template | Nome do modelo aprovado. Use em vez de text. |
| language | Idioma do modelo. Padrão: pt_BR. |
| reply_to_message_id | Opcional. ID da mensagem recebida que será citada na resposta. |
Variáveis e cabeçalho
| Campo | Regra |
|---|---|
| variables | Um valor por variável do corpo. Até 20 valores de 1.024 caracteres; a quantidade exigida vem do modelo. |
| variable_names | Nomes associados aos valores em variables, para modelos NAMED. Use a ordem da listagem ou mantenha cada par nome/valor correspondente. |
| header_media | Obrigató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_text | Até 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
| Campo | Regra |
|---|---|
| button_url_param | Valor da parte variável de um botão de link. Até 200 caracteres; a API aceita um link dinâmico por template. |
| button_url_index | Posição do botão de link na lista, começando em zero. Padrão: 0. |
| coupon_code / coupon_index | Código de até 15 caracteres e posição do botão de cupom COPY_CODE. Não use para autenticação. |
| otp_code | Código de autenticação de até 15 caracteres, sem espaços ou caracteres de controle. variables pode ser omitido. |
| otp_index | Para autenticação, use 0 ou omita. Não combine OTP com anexo, cupom, link dinâmico ou PIX. |
| pix_order | Pedido 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.
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 -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": {| Em pix_order | Uso |
|---|---|
| reference_id | Referência da cobrança no seu sistema. Até 64 caracteres. |
| pix_code | Copia e cola completo gerado pelo seu PSP para esta cobrança. Não use o texto ilustrativo acima. |
| merchant_name / key / key_type | Nome do recebedor, chave PIX e tipo: CNPJ, CPF, EMAIL, PHONE ou EVP. |
| items | Até 30 itens com name, amount unitário em centavos e quantity. |
| tax / total_amount | tax é opcional, com padrão 0. Se total_amount for informado, deve ser igual a Σ(amount × quantity) + tax. |
| Limite numérico | Cada 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_id | goods_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.
/public/v1/validatecurl -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.