vamobotDocs

Mensagens

Envie texto e mídia para um contato dentro da janela de 24 horas e consulte o status de uma mensagem.

Use POST /messages/send para responder um cliente que falou com a loja nas últimas 24 horas. Para falar com quem não escreveu, use um modelo aprovado.

A janela de 24 horas

O WhatsApp só aceita mensagens livres (texto, foto, vídeo, áudio, documento) até 24 horas depois da última mensagem do cliente. Cada mensagem nova do cliente reabre a janela por mais 24 horas.

SituaçãoO que acontece
Mariana escreveu há 3 horasA mensagem sai
Mariana escreveu há 26 horas422 whatsapp_window_closed: nada é enviado nem gravado
Contato importado que nunca escreveu422 whatsapp_window_closed

Para saber antes de enviar, olhe o campo lastInboundAt do contato: a janela está aberta se ele for de menos de 24 horas atrás.

POST /messages/send

Envia uma mensagem de texto, ou uma mídia com legenda, para um contato. Acesso: chave secreta com Leitura e escrita.

CampoTipoObrigatórioDescrição
contactIdstring (UUID)SimO contato que recebe
contentstringSimO texto, até 20.000 caracteres. Com mediaUrl, vira a legenda
mediaUrlstringNãoLink público (http:// ou https://) do arquivo. O WhatsApp baixa o arquivo desse link
mediaTypestringNãoTipo MIME (image/jpeg, video/mp4, audio/ogg, application/pdf) ou só image, video, audio, document. Sem ele, ou com outro valor, a mídia vai como documento
curl -X POST https://vamo.ai/api/v1/messages/send \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "contactId": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f",
    "content": "Oi, Mariana! Seu iPhone 15 saiu para entrega hoje. Código de rastreio: BR123456789.",
    "mediaUrl": "https://lojaaurora.com.br/notas/pedido-1042.pdf",
    "mediaType": "application/pdf"
  }'

Resposta 201

{
  "data": {
    "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "conversationId": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716",
    "senderType": "human",
    "content": "Oi, Mariana! Seu iPhone 15 saiu para entrega hoje. Código de rastreio: BR123456789.",
    "mediaUrl": "https://lojaaurora.com.br/notas/pedido-1042.pdf",
    "mediaType": "application/pdf",
    "waMessageId": "wamid.HBgNNTUxMTk4NzY1NDMyMRUCABEYEjQ1",
    "status": "sent",
    "source": "api",
    "createdAt": "2026-10-31T13:20:05.000Z"
  }
}

status: "sent" quer dizer que o WhatsApp aceitou a mensagem. Entregue e lida chegam depois: consulte GET /messages/:id ou assine os webhooks message.delivered e message.failed.

O que acontece ao enviar

  • A conversa. Cada contato tem uma única conversa. Se ela estava fechada ou adiada, é reaberta; se não existia, é criada (e dispara conversation.created).
  • A mensagem aparece na caixa de entrada como enviada pela equipe, com origem api. Ela dispara o webhook message.created.
  • A IA continua cuidando da conversa. Um envio pela API não conta como uma pessoa assumindo: a IA segue respondendo o cliente. Se havia um rascunho da IA esperando aprovação, ele é descartado, porque a sua mensagem passou a ser a mais recente.
  • Textos longos. Um texto com mais de 4.096 caracteres (o limite do WhatsApp) sai em várias mensagens, cortadas em parágrafos ou frases. Na API ele continua sendo uma mensagem só.
  • Falhas. Se o WhatsApp recusar, a resposta traz o erro (veja abaixo) e a tentativa fica gravada como failed na conversa, com o motivo. Se a recusa for antes de chegar ao WhatsApp (janela fechada, contato sem número), nada é gravado.

Repita com Idempotency-Key

Mande o cabeçalho Idempotency-Key com um valor único por mensagem. Se a requisição cair por tempo esgotado, repita com a mesma chave: se a primeira já tinha enviado, a mensagem não sai de novo e você recebe a mesma resposta. Veja Idempotência.

Erros

StatusCódigoQuando
400validation_errorFalta contactId ou content, contactId não é UUID, content passa de 20.000 caracteres, mediaUrl não é um link http(s)
404not_foundContact not found: o contato não existe ou é de outra organização
422whatsapp_window_closedA janela de 24 horas está fechada. Envie um modelo
422whatsapp_recipient_unavailableO número não recebe WhatsApp, ou o contato não tem número
409whatsapp_busyOutra mensagem para o mesmo contato está saindo agora. Tente em alguns segundos
409whatsapp_not_connectedO WhatsApp da loja não está conectado
429whatsapp_rate_limitedLimite de envio do WhatsApp. Espere os segundos de Retry-After
402whatsapp_billingO WhatsApp recusou por cobrança
502whatsapp_upstream_errorO WhatsApp não processou. Tente mais tarde

Os erros vêm no formato de sempre:

{
  "error": {
    "code": "whatsapp_window_closed",
    "message": "The 24-hour customer service window is closed. Send an approved template instead."
  }
}

A lista completa está em Erros.

GET /messages/:id

Consulta uma mensagem, com o status atual e o motivo de uma falha. Acesso: chave secreta (leitura).

curl https://vamo.ai/api/v1/messages/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"

Resposta 200

{
  "data": {
    "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "conversationId": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716",
    "senderType": "human",
    "content": "Oi, Mariana! Seu iPhone 15 saiu para entrega hoje. Código de rastreio: BR123456789.",
    "mediaUrl": "https://lojaaurora.com.br/notas/pedido-1042.pdf",
    "mediaType": "application/pdf",
    "status": "read",
    "source": "api",
    "waMessageId": "wamid.HBgNNTUxMTk4NzY1NDMyMRUCABEYEjQ1",
    "errorCode": null,
    "errorMessage": null,
    "createdAt": "2026-10-31T13:20:05.000Z"
  }
}

Quando status é failed, errorCode traz o código do WhatsApp (por exemplo 131047, janela fechada) e errorMessage a explicação. Rascunhos da IA que ainda esperam aprovação, ou que foram descartados, respondem 404.

Campos da mensagem

CampoValores
senderTypecustomer (o cliente), ai (o agente de IA), human (a equipe ou a API)
statussending, sent, delivered, read, failed
sourcechat (a conversa normal: cliente, IA e caixa de entrada), api, automation, campaign, business_app (enviada pelo app WhatsApp Business no celular)

Nesta página