Pular para o conteúdo
POST/mensagens

Enviar mensagem

mensagens:enviaraceita Idempotency-Key

Texto, mídia (imagem, vídeo, áudio, documento) ou modelo aprovado. Vai para a fila de envio e responde 202 na hora; acompanhe pelo webhook mensagem.status ou por GET /mensagens/{id}. Na API oficial, fora da janela de 24 h só modelo. Envie Idempotency-Key ou id_cliente (UUID) para identificar o envio.

POST /mensagens

curl -X POST "https://chat.forsi.com.br/api/v1/mensagens" \
  -H "Authorization: Bearer $FORSI_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-4821" \
  -d '{
    "telefone": "+55 31 98888-7777",
    "tipo": "texto",
    "texto": "Olá! Sua consulta está confirmada para amanhã às 9h."
  }'
Resposta 202
{
  "dados": {
    "mensagem_id": "4e8cb5d0-2d89-4fc2-93bb-c8e5e17d4629",
    "conversa_id": "495a7cae-128c-4b66-adbc-807b3959c129",
    "contato_id": "08054a7f-a752-481e-9915-cf4cf944df39",
    "caixa_id": "7a9d53e9-9d1b-4122-923b-fac67958f445",
    "conversa_nova": true,
    "estado": "pendente"
  }
}

Corpo da requisição#

JSON. Mande com Content-Type: application/json.

  • id_clienteuuidopcional

    UUID estável do envio; substitui Idempotency-Key.

  • conversa_iduuidopcional

    Responder numa conversa que já existe. Ou use telefone.

  • telefonestringopcional

    Com DDI e DDD. Acha o contato com ou sem o 9º dígito.

    • mín. 8 caracteres
    • até 30 caracteres
    • ex.: +55 31 98888-7777
  • caixa_iduuidopcional

    Obrigatório quando a organização tem mais de um WhatsApp conectado.

  • nomestringopcional

    Nome do contato, se ele ainda não tiver.

    • até 120 caracteres
  • tipo"texto" | "imagem" | "video" | "audio" | "documento" | "modelo"opcional
    • padrão "texto"
  • textostringopcional

    Texto (ou legenda da mídia).

    • até 4096 caracteres
  • midiaobjectopcional
    —
  • midia.urlstringobrigatório

    Link público https do arquivo. O WhatsApp baixa dele na hora do envio.

    • até 2000 caracteres
  • midia.mimestringopcional
    • até 100 caracteres
  • midia.nome_arquivostringopcional

    Nome que o contato vê (documentos).

    • até 200 caracteres
  • modeloobjectopcional
    —
  • modelo.iduuidopcional

    Id do modelo (GET /modelos). Ou use nome + idioma.

  • modelo.nomestringopcional
    • até 512 caracteres
  • modelo.idiomastringopcional
    • até 15 caracteres
    • ex.: pt_BR
  • modelo.corpolista de string ou objeto livreopcional

    Valores das variáveis do corpo: lista na ordem ({{1}}, {{2}}...) ou objeto por nome.

  • modelo.cabecalhoobjectopcional
    —
  • modelo.botoesobjeto livreopcional

    Final do link (ou código) por índice do botão: {"0": "abc123"}.

  • responde_a_iduuidopcional

    Id de uma mensagem desta conversa para citar.

  • canal"auto" | "oficial" | "qr"opcional

    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. Manual nunca troca de canal: se o escolhido não puder enviar, dá erro.

Resposta#

202 com {"dados": ...}: EnvioAceito.

  • mensagem_iduuidopcional
    —
  • conversa_iduuidopcional
    —
  • contato_iduuid ou nullopcional
    —
  • caixa_iduuidopcional
    —
  • conversa_novabooleanopcional
    —
  • estado"pendente"opcional
    —

Erros#

Todo erro vem como {"erro": {"codigo", "mensagem"}}. Trate pelo codigo: ele não muda.

Status de erro desta operação
StatusQuando
401Chave ausente ou inválida (resposta igual para qualquer motivo).
403Plano sem API, escopo insuficiente ou https/origem recusados.
409Conflito (repetido, Idempotency-Key com outro corpo).
422Dados inválidos ou regra de negócio (ex.: janela_fechada; conta_restrita = a Meta restringiu a conta por spam: erro traz os campos de RestricaoMeta, como ate, escopo, motivo e retry_after_s).
429Limite de requisições. Veja Retry-After.
Códigos de erro que esta área pode devolver22
  • 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").

Os erros que valem para qualquer rota (chave, limite, JSON) estão em Erros.