API · Atualizado em 12/10/2026

Enviar mensagens pela API: texto, mídia e modelos

Envie texto, imagem, áudio, vídeo, documento, localização, contato e modelos em um ticket, reaja, responda uma mensagem e reenvie falhas.

Você envia mensagens dentro de um ticket, usando o id da conversa. Para falar com um contato que ainda não tem ticket, abra um ticket antes ou use um modelo com mensagem ativa.

Quando usar

  • Quando seu sistema responde um cliente em um ticket aberto, como confirmação de pedido ou envio de comprovante.
  • Quando precisa enviar arquivo, localização ou cartão de contato por integração.
  • Quando quer reagir a uma mensagem do cliente ou reenviar uma mensagem que falhou.

Pré-requisitos

  • Uma chave com mensagens:escrever para enviar e mensagens:ler para consultar. Veja Escopos e permissões.
  • O id do ticket (conversa). Para achar, use GET /v1/conversations?contato_id=... ou a resposta de abrir ticket.

Rotas

MétodoRotaEscopoO que faz
POST/v1/conversations/:id/messagesmensagens:escreverEnvia texto, mídia, localização, contato ou modelo
POST/v1/conversations/:id/messages/attachmentsmensagens:escreverEnvia até 10 arquivos, uma mensagem por arquivo
POST/v1/conversations/:id/messages/:messageId/reactionmensagens:escreverReage a uma mensagem, ou remove a reação
POST/v1/conversations/:id/messages/:messageId/resendmensagens:escreverReenvia uma mensagem que falhou
GET/v1/conversations/:id/messagesmensagens:lerLista as mensagens do ticket
POST/v1/attachmentsmensagens:escreverEnvia um arquivo e devolve o id do anexo

Passo a passo: enviar um texto

  1. Tenha o id do ticket.
  2. Chame a rota de envio:
curl -s -X POST https://http.pipebr.app/v1/conversations/b3a1c9de-0000-4000-8000-000000000100/messages \
  -H "Authorization: Bearer $PIPE_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"texto": "Seu pedido 1234 saiu para entrega."}'
  1. A resposta é 201. A mensagem entra numa fila de entrega e nasce como pendente:
{
  "id": "b3a1c9de-0000-4000-8000-000000000200",
  "stateDelivery": "pendente",
  "insideOfWindow": true,
  "categoryCobranca": null,
  "content": "Seu pedido 1234 saiu para entrega.",
  "type": "texto",
  "warning": null
}

O estado muda depois para enviada, entregue, lida ou falhou, conforme o canal confirma. Acompanhe por webhook (evento mensagem.estado_entrega_alterado) ou lendo as mensagens do ticket.

Campos do corpo

CampoPara que serve
textoO texto da mensagem, ou a legenda quando há anexo
typetexto, imagem, audio, video, documento, localizacao, contato ou template. Com anexo, o Pipe define o tipo pelo arquivo
template_idId de um modelo aprovado do canal do ticket
parametrosValores das variáveis do corpo do modelo, na ordem {{1}}, {{2}}
parametros_botoesValores de botões que pedem um dado, por índice do botão, como {"0": "CUPOM10"}
attachmentIdId devolvido por POST /v1/attachments
localizacao{ latitude, longitude, nome?, endereco? }, quando type é localizacao
contatosLista de 1 a 10 cartões { nome, telefones }, quando type é contato
mediaUrlLink público para o cabeçalho de mídia de um modelo
agentIdAtendente que assina a mensagem. Sem ele, a mensagem sai como do sistema
resposta_pronta_idMarca a mensagem como vinda de uma resposta pronta
replyToMessageIdId de uma mensagem do mesmo contato para citar (responder)

Enviar um arquivo

  1. Envie o arquivo cru no corpo, com o Content-Type dele. O parâmetro nome dá o nome do arquivo:
curl -s -X POST "https://http.pipebr.app/v1/attachments?nome=comprovante.pdf" \
  -H "Authorization: Bearer $PIPE_CHAVE" \
  -H "Content-Type: application/pdf" \
  --data-binary @comprovante.pdf
  1. Guarde o id da resposta:
{
  "id": "b3a1c9de-0000-4000-8000-000000000300",
  "mime": "application/pdf",
  "bytes": 48213,
  "tipo": "documento",
  "link": "https://http.pipebr.app/v1/attachments/b3a1c9de-0000-4000-8000-000000000300?expires=0&signature=exemplo",
  "durationSec": null,
  "maxByMessage": 10
}
  1. Envie a mensagem com o anexo e, se quiser, uma legenda:
curl -s -X POST https://http.pipebr.app/v1/conversations/b3a1c9de-0000-4000-8000-000000000100/messages \
  -H "Authorization: Bearer $PIPE_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"attachmentId": "b3a1c9de-0000-4000-8000-000000000300", "texto": "Segue o comprovante."}'

Para vários arquivos de uma vez, use POST .../messages/attachments com {"attachmentIds": ["...", "..."], "texto": "..."}. A resposta traz messages, uma por arquivo. Se um arquivo for recusado, nenhum é enviado.

Formatos aceitos no WhatsApp

TipoRegra
ImagemJPEG ou PNG, até 5 MB. Outros formatos (GIF, WebP) ou arquivos maiores vão como documento, e o campo warning avisa
ÁudioAAC, AMR, MP3, M4A ou OGG com Opus, até 16 MB. OGG precisa ser Opus e mono. WAV, WMA e MIDI são recusados com 422
VídeoMP4 ou 3GP, até 16 MB. AVI, MOV e WebM são recusados com 422
DocumentoAté 100 MB

Um áudio audio/webm com Opus é convertido para OGG no servidor e sai como nota de voz. O link do anexo vale por 15 minutos.

Enviar um modelo

Fora da janela de 24 horas, só modelos aprovados saem. Informe o template_id do canal do ticket e os valores das variáveis:

curl -s -X POST https://http.pipebr.app/v1/conversations/b3a1c9de-0000-4000-8000-000000000100/messages \
  -H "Authorization: Bearer $PIPE_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"template_id": "b3a1c9de-0000-4000-8000-000000000400", "parametros": ["Maria", "1234"]}'

Para listar os modelos do canal e ver status e variáveis, use Consultar cadastros. Modelo desativado dá 409 template_inativo; modelo não aprovado dá 409 template_nao_aprovado.

Localização e contato

{ "type": "localizacao", "localizacao": { "latitude": -23.55, "longitude": -46.63, "nome": "Loja Girassol" } }
{ "type": "contato", "contatos": [ { "nome": "Loja Girassol", "telefones": ["+5511955550000"] } ] }

Cartão de contato só funciona no WhatsApp. Cada cartão aceita de 1 a 5 telefones em formato internacional.

Reagir e reenviar

Reação com emoji (a empresa reage à mensagem do cliente). Envie null para remover:

curl -s -X POST https://http.pipebr.app/v1/conversations/b3a1c9de-0000-4000-8000-000000000100/messages/b3a1c9de-0000-4000-8000-000000000201/reaction \
  -H "Authorization: Bearer $PIPE_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"emoji": "👍"}'

A reação exige janela de 24 horas aberta, mensagem com menos de 30 dias e canal WhatsApp. Repetir o mesmo emoji não envia de novo (queued: false).

Para reenviar uma mensagem em estado falhou, chame POST .../messages/:messageId/resend. A resposta traz o id e o novo estado_entrega.

Ler as mensagens do ticket

GET /v1/conversations/:id/messages aceita limit, cursor, order_by=criada_em[desc], direction (entrada, saida ou interna) e estado_entrega (pendente, enviando, enviada, entregue, lida, reproduzida ou falhou). Cada item traz type, content, stateDelivery, errorCode, errorText (em português, para os códigos conhecidos da Meta), midia, respondeA, reacoes e encaminhada.

Resultado esperado

A mensagem aparece no ticket, no Desk, como enviada pelo sistema (ou pelo atendente informado em agentId) e chega ao cliente pelo canal.

Problemas comuns

  • 409 janela_fechada: passaram mais de 24 horas desde a última mensagem do cliente. Envie um modelo aprovado.
  • 422 text_too_long: o texto passa de 4096 caracteres (1024 em legenda). Divida em mais de uma mensagem.
  • 422 de formato de mídia: o WhatsApp não aceita aquele tipo de arquivo. Converta antes de enviar.
  • 404 no ticket: o ticket não existe ou é de outro fluxo, para chaves de fluxo.
  • Mensagem falhou: leia errorText para saber o motivo e a ação sugerida. Depois reenvie com /resend.

Boas práticas

  • Use Idempotency-Key para não duplicar a mensagem se precisar repetir a chamada.
  • Prefira o upload de anexos a depender de links externos, que podem sair do ar antes da entrega.
  • Respeite o ritmo da chave: 20 chamadas por segundo por padrão.

Limitações

  • A API de conversas não envia menus nem botões interativos livres. Para menus e respostas rápidas na conversa automática, use o Builder. Botões de modelo funcionam por parametros_botoes.
  • Enviar a um contato sem ticket não é possível por esta rota.

Próximos passos

Perguntas frequentes

Posso enviar mensagem para um contato que não tem ticket?

Não por esta rota. Ela envia dentro de um ticket. Para iniciar a conversa, use um modelo aprovado com a mensagem ativa, ou abra um ticket para o contato antes.

Por que recebo 409 janela_fechada?

No WhatsApp, texto livre só pode ser enviado em até 24 horas depois da última mensagem do cliente. Fora da janela, só sai modelo aprovado pela Meta.

Como envio uma imagem ou PDF?

Primeiro envie o arquivo para POST /v1/attachments e guarde o id. Depois chame o envio de mensagem com attachmentId e, se quiser, texto como legenda.

Qual o tamanho máximo do texto?

4096 caracteres. A legenda de mídia no WhatsApp aceita 1024. Acima disso, a resposta é 422 text_too_long.