Pular para o conteúdo

Mensagens

Enviar texto, mídia e modelos; ver status.

Envie texto, mídia (imagem, vídeo, áudio, documento) ou modelo aprovado. O envio vai para a fila e responde 202 na hora; o status (pendente, enviada, entregue, lida, falhou) chega pelo webhook mensagem.status ou por GET /mensagens/{id}. Para consultar mensagens de toda a organização use GET /mensagens; também é possível listar mensagens de uma conversa.

O caminho de uma mensagem enviadaO seu sistema chama POST /mensagens. A API responde 202 na hora e põe a mensagem na fila (status pendente). A FORSI entrega à Meta (enviada); a Meta avisa quando chega ao aparelho (entregue) e quando a pessoa lê (lida). Se algo der errado, o status vira falhou, com o motivo. Cada mudança chega ao seu webhook como o evento mensagem.status; também dá para consultar com GET /mensagens/{id}.o seu webhook recebemensagem.statusSeu sistemaPOST /v1/mensagens202 na hora, com o idFORSI Chatpõe na fila de enviopendenteentrega à MetaMeta (WhatsApp)leva até o aparelhoenviadaa Meta confirmaCelular do clientechega e depois é lidaentreguelidaDeu errado?em qualquer etapa, com o motivofalhou
O caminho de uma mensagem enviada
  • Para quem: conversa_id (responder numa conversa que já existe) ou telefone (com DDI e DDD). Só um dos dois.
  • Pelo telefone, a conversa e o contato são criados se ainda não existirem; nome dá nome ao contato novo.
  • Pelo telefone, com mais de um WhatsApp conectado, mande caixa_id (veja GET /me), senão vem 422 caixa_obrigatoria. Com conversa_id a mensagem sai pela caixa da conversa (caixa_id e nome só valem com telefone).
  • responde_a_id cita uma mensagem da mesma conversa.
  • Na API oficial do WhatsApp, fora da janela de 24 horas desde a última mensagem do contato, só sai modelo aprovado (422 janela_fechada). Veja os modelos em GET /modelos.
  • Mídia vai por link https público (midia.url): o WhatsApp baixa dele na hora do envio. O texto vira a legenda.
  • Mande Idempotency-Key para poder repetir sem mandar duas vezes (veja Idempotência).
  • Limite próprio: 60 envios por minuto por chave e 120 por organização.
  • canal (opcional, só WhatsApp): auto (padrão, igual a omitir) segue a regra da caixa; oficial sai só pela API oficial da Meta; qr sai só pelo WhatsApp por QR. A escolha manual nunca troca de canal: se o canal escolhido não puder enviar, vem erro (422 canal_oficial_indisponivel, canal_oficial_sem_grupo, canal_qr_indisponivel, canal_qr_sem_modelo, canal_so_whatsapp; a janela de 24 h vale em oficial) ou, se cair depois de aceito, a mensagem fica falhou com o código em erro. Modelo só sai pela oficial. Repetir o mesmo id_cliente com outro canal dá 409 idempotencia_conflito.

Baixar mídia recebida#

Cada item de midia[] nas mensagens e nos webhooks mensagem.recebida / mensagem.enviada traz id estável, além de mime, nome_arquivo, tamanho e duracao_s quando disponíveis. Baixe os bytes por GET /mensagens/{id}/midia, autenticado com escopo mensagens:ler. Use ?item=<id-do-anexo> para escolher um anexo por esse id ou ?item=0 para escolher pelo índice começando em zero; sem item, baixa o primeiro.

  • A resposta 200 é o arquivo binário, com Content-Type e Content-Disposition. O endpoint aceita Range: bytes=... e responde 206 com Content-Range.
  • Se o download sob demanda estiver em andamento, recebe 202 com erro.codigo: midia_baixando e Retry-After (aguarde esse número de segundos antes de tentar de novo). Se não for possível obter o arquivo, recebe 409 midia_indisponivel.
  • Mensagem inexistente, de outra organização ou sem mídia responde 404.
Responder numa conversa que já existe
{
  "conversa_id": "495a7cae-128c-4b66-adbc-807b3959c129",
  "tipo": "texto",
  "texto": "Perfeito, remarquei para quinta às 10h."
}
Imagem com legenda
{
  "telefone": "+55 31 98888-7777",
  "tipo": "imagem",
  "midia": {"url":"https://seu-sistema.com.br/arquivos/orcamento.jpg"},
  "texto": "Segue o orçamento."
}
Documento (PDF)
{
  "conversa_id": "495a7cae-128c-4b66-adbc-807b3959c129",
  "tipo": "documento",
  "midia": {
    "url": "https://seu-sistema.com.br/arquivos/orcamento.pdf",
    "nome_arquivo": "Orçamento.pdf"
  }
}
Modelo aprovado (abre a conversa fora da janela de 24 h)
{
  "telefone": "+55 31 98888-7777",
  "caixa_id": "7a9d53e9-9d1b-4122-923b-fac67958f445",
  "tipo": "modelo",
  "modelo": {"nome":"lembrete_consulta","idioma":"pt_BR","corpo":["Maria","9h"]}
}
Escolher o canal (só pela API oficial, sem cair para o QR)
{
  "conversa_id": "495a7cae-128c-4b66-adbc-807b3959c129",
  "tipo": "texto",
  "texto": "Seu pedido saiu para entrega.",
  "canal": "oficial"
}

Endpoints#

Códigos de erro#

Além dos gerais (chave, limite, JSON), estes podem vir em erro.codigo nas rotas daqui. Todos estão em Erros.

Códigos de erro
codigoO que significa
tipo_invalidotipo deve ser texto, imagem, video, audio, documento ou modelo.
texto_vazioMensagem de texto precisa de texto.
texto_longoTexto longo demais (máximo de 4096 caracteres).
midia_invalidaLink de mídia inválido: use https com um endereço público.
midia_indisponivelO arquivo desta mídia está indisponível.
midia_baixandoO download desta mídia está na fila. Tente novamente após Retry-After.
janela_fechadaA janela de 24 horas desta conversa está fechada. Na API oficial do WhatsApp, só um modelo aprovado reabre a conversa.
conta_restritaA Meta restringiu esta conta do WhatsApp por spam. Nada foi enviado: erro.ate diz até quando (erro.retry_after_s e o cabeçalho Retry-After, em segundos), erro.escopo o que está barrado e erro.motivo o código. Quem administra pode desligar a trava em Configurações > API.
caixa_obrigatoriaA organização tem mais de um WhatsApp conectado: informe caixa_id (veja GET /me).
caixa_sem_conexaoNenhum WhatsApp conectado nesta caixa.
caixa_inexistenteCaixa não encontrada (veja GET /me).
canal_sem_iniciarEste canal não permite começar conversa por telefone. Use uma caixa de WhatsApp.
modelo_sem_api_oficialModelos só saem pela API oficial do WhatsApp. Conecte a API oficial nesta caixa.
modelo_inexistenteModelo não encontrado nesta caixa (veja GET /modelos).
telefone_invalidoTelefone inválido. Mande com DDI e DDD.
conversa_inexistenteConversa não encontrada.
mensagem_inexistenteMensagem não encontrada.
canal_oficial_indisponivelcanal "oficial": a API oficial do WhatsApp não está conectada nesta caixa. Nada foi enviado pelo QR.
canal_oficial_sem_grupocanal "oficial": a API oficial do WhatsApp não envia para grupo. Use "qr" ou omita o campo.
canal_qr_indisponivelcanal "qr": o WhatsApp por QR não está conectado nesta caixa. Nada foi enviado pela API oficial.
canal_qr_sem_modelocanal "qr": modelos só saem pela API oficial do WhatsApp. Use "oficial" ou omita o campo.
canal_so_whatsappcanal "oficial"/"qr" só vale em caixa de WhatsApp. Omita o campo (ou use "auto").