Referência da API

Homio Conversations

Uma API única para os seus sistemas enviarem mensagens de WhatsApp, gerenciarem contatos e dispararem cobranças aos seus clientes.

https://conversations.homio.com.br

00Visão geral

Com a Conversations API os seus sistemas enviam mensagens de WhatsApp, criam e atualizam contatos e disparam cobranças para os seus clientes. Você informa um contato e o conteúdo; a API cuida da entrega.

  • Base URL: https://conversations.homio.com.br
  • Toda requisição e resposta é JSON (Content-Type: application/json).
  • Cada rota exposta é uma escolha deliberada: nada fora da lista abaixo é acessível.

01Autenticação

Toda requisição precisa de uma API key. Envie no header x-api-key ou como Authorization: Bearer.

Header
x-api-key: sua_chave_aqui
Cada chave é amarrada a uma única location (a subconta de WhatsApp do cliente). Você nunca envia locationId — a API injeta a location da sua chave e ignora qualquer uma que você mandar. Ou seja: uma chave só consegue operar a própria location. Nunca é possível agir em nome de outro cliente.

Sem chave, ou com chave inválida, a resposta é 401.

02Enviar mensagem

Envia uma mensagem de texto e/ou mídia para um contato. Informe contactId ou phone e um message e/ou anexos. Se você informar só o phone e o contato ainda não existir, ele é criado automaticamente. Áudio, imagem, vídeo e documento são detectados pela extensão/tipo do arquivo, sem configuração.

A resposta traz os ids do contato, da conversa e da mensagem criados, além de contactCreated indicando se um novo contato foi gerado.

POST/v1/messages
CampoTipoDescrição
phonestringum dos 2Telefone E.164, ex. +5527999999999. Cria/atualiza o contato.
contactIdstringum dos 2Id de um contato já existente.
messagestring*Texto da mensagem. Obrigatório, a menos que haja anexo.
attachmentUrlsstring[]opcionalURLs públicas de arquivos, repassadas direto.
filesobject[]opcionalUploads inline: { filename, contentType, data } (data em base64). Para arquivos pequenos.
namestringopcionalNome usado ao criar o contato a partir do telefone.
Requisição
curl -X POST https://conversations.homio.com.br/v1/messages \
  -H "x-api-key: SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+5527999999999",
    "message": "Olá! Sua mensagem chegou. 👋"
  }'
Resposta 200
{
  "contactId": "8fW9FP6DMZ7IBkJhBH9H",
  "conversationId": "2EndKfJhpVhnVrglsu6C",
  "messageId": "ebfj3Ns6LhNR7VE9fmhT",
  "contactCreated": false,
  "attachments": []
}

Três formas de anexar

URL attachmentUrls base64 files (≤ ~4 MB) upload /v1/uploads (grandes)

03Upload de arquivo grande

Para mídia grande (vídeo, por exemplo), peça uma URL de upload assinada e envie os bytes direto para o storage, sem passar o arquivo pelo corpo da requisição. Depois, use a publicUrl retornada no attachmentUrls de /v1/messages.

POST/v1/uploads
CampoTipoDescrição
filenamestringobrig.Nome do arquivo, ex. boleto.pdf.
contentTypestringopcionalMIME, ex. application/pdf.
Resposta 200
{
  "signedUrl": "https://…/upload/sign/…",   // PUT dos bytes aqui
  "publicUrl": "https://…/whatsapp-media/…", // use no attachmentUrls
  "path": "outbound/…",
  "token": "…"
}
Fluxo: 1) POST /v1/uploads → 2) PUT o arquivo em signedUrl → 3) POST /v1/messages com attachmentUrls: [publicUrl].

04Upsert de contato

Cria ou atualiza um contato. Informe ao menos email ou phone (ou um id para atualizar um contato conhecido). Campos extras são repassados ao contato.

POST/v1/contacts/upsert
Requisição
curl -X POST https://conversations.homio.com.br/v1/contacts/upsert \
  -H "x-api-key: SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+5527999999999",
    "email": "cliente@exemplo.com",
    "firstName": "Maria"
  }'

Requer email ou phone (ou id). A locationId vem da sua chave.

05Garantir conversa

Garante, de forma idempotente, que existe uma conversa para um contato (criando o contato a partir do telefone, se preciso). Útil quando você quer o handle da conversa antes de enviar. A maioria dos envios não precisa disso: /v1/messages já resolve a conversa sozinho.

POST/v1/conversations/ensure
Resposta 200
{
  "contactId": "8fW9FP6DMZ7IBkJhBH9H",
  "conversationId": "2EndKfJhpVhnVrglsu6C",
  "contactCreated": false,
  "conversationCreated": false
}

Requer contactId ou phone.

06Como a cobrança funciona

As rotas de cobrança enviam mensagens de boleto montadas a partir de templates reutilizáveis, e guardam um registro de cada boleto para consultas futuras. São restritas às locations habilitadas para cobrança (chaves de outras locations recebem 403).

O fluxo tem duas partes:

  • Defina os templates uma vez — textos com variáveis ({{valor}}, {{vencimento}}…), via CRUD de templates.
  • Envie a cobrança referenciando o templateId mais os dados do boleto — a API renderiza o texto, anexa o PDF, envia e faz o upsert do registro do boleto (1 linha por boleto).

07Templates de cobrança

Cada chave gerencia apenas os próprios templates (escopados pela location). O id é um slug único dentro da location, usado depois como templateId no envio.

Variáveis disponíveis no corpo do template

{{nome}} {{valor}} R$ (de centavos) {{vencimento}} DD/MM/AAAA {{boleto}} {{banco}} {{agencia}} {{status}} {{cpf}}
GET/v1/billing/templates

Lista todos os seus templates. Retorna { "templates": [...] }.

POST/v1/billing/templates

Cria um template.

Requisição
{
  "id": "lembrete_vencimento",
  "name": "Lembrete de vencimento",
  "body": "Olá {{nome}}, seu boleto do {{banco}} de {{valor}} vence em {{vencimento}}."
}
GET/v1/billing/templates/:id

Retorna um template pelo id.

PUT/v1/billing/templates/:id

Atualiza name, body e/ou active (todos opcionais).

DELETE/v1/billing/templates/:id

Remove o template (hard delete). Retorna { "deleted": "id" }.

08Enviar cobrança

Renderiza o template com os dados do boleto, anexa o PDF e envia. O boleto é gravado (upsert por boletoNumber) para consulta.

POST/v1/billing/messages
CampoTipoDescrição
templateIdstringobrig.Id do template a renderizar.
boletoNumberstringobrig.Identificador do boleto (chave do registro).
phonestringobrig.Telefone do cliente (E.164).
statusenumopcionalaberto · vencido · pago · cancelado
amountCentsintegeropcionalValor em centavos (ex. 15990 = R$ 159,90).
dueDatedateopcionalVencimento, AAAA-MM-DD.
cpf · bank · agency · namestringopcionalDados do boleto/cliente, usados no template.
pdfUrl ou pdfstring / objectopcionalPDF do boleto: URL pública, ou { filename, contentType, data } (base64).
Requisição
curl -X POST https://conversations.homio.com.br/v1/billing/messages \
  -H "x-api-key: SUA_CHAVE" -H "Content-Type: application/json" \
  -d '{
    "templateId": "lembrete_vencimento",
    "boletoNumber": "3205002226420...",
    "dueDate": "2026-07-20",
    "status": "aberto",
    "amountCents": 15990,
    "phone": "+5527999999999",
    "name": "Maria", "bank": "Banco do Brasil", "agency": "0001",
    "pdfUrl": "https://exemplo.com/boleto.pdf"
  }'
Resposta 200
{
  "boletoNumber": "3205002226420...",
  "messageId": "j9kEEdFFNsM5UiXfI4zX",
  "renderedMessage": "Olá Maria, seu boleto do Banco do Brasil de R$ 159,90 vence em 20/07/2026.",
  "pdfUrl": "https://…/boleto.pdf",
  "sentCount": 1
}

09Erros

Respostas de erro são JSON no formato { "error": "...", "message": "..." }.

StatusSignificado
401Sem chave, ou chave inválida.
403Rota indisponível para a location da sua chave (ex.: cobrança numa location não habilitada).
404Recurso não encontrado (ex.: template inexistente).
409Conflito (ex.: criar um template com id já existente).
422Validação: falta um campo obrigatório ou o valor é inválido.
502Erro no upstream (token/entrega). Reenvie; se persistir, fale com o suporte.