Webhooks
Receba avisos da OctoSolve no seu sistema quando algo acontecer, com assinatura e reenvio automático.
Webhooks
Com a API você pergunta para a OctoSolve. Com webhook, a OctoSolve avisa você: toda vez que algo acontece na sua conta, mandamos uma requisição POST para o endereço que você cadastrar.
Serve para coisas como registrar o agendamento no seu sistema, avisar o time num canal interno quando cair um lead, ou disparar uma automação no Make ou no n8n quando um pagamento for confirmado.
Você cadastra os endereços em Configurações, aba API e integrações.
Eventos disponíveis
Cada endereço cadastrado escolhe quais eventos quer receber. Não é tudo ou nada.
| Evento | Quando dispara |
|---|---|
contact.created | Um contato novo foi criado |
contact.updated | Um contato foi alterado |
appointment.created | Um agendamento foi criado |
appointment.updated | Um agendamento foi remarcado ou teve dados alterados |
appointment.cancelled | Um agendamento foi cancelado |
payment.confirmed | Um pagamento foi confirmado |
conversation.handoff | Uma conversa passou do agente para uma pessoa do seu time |
Mensagens de conversa não geram evento nesta versão, de propósito: o volume é alto e o conteúdo é sensível.
Formato do envio
Todo evento chega com a mesma casca:
O data muda conforme o tipo. Campos podem vir null.
contact.created e contact.updated
Mesmo formato do contato na API: id, telefone, nome, email, cidade, data_nascimento, observacoes, tags, status, ig_username, telegram_username, updated_at.
O telefone pode vir null: contato que chegou pelo Instagram ou pelo Telegram se identifica por usuário.
appointment.created, appointment.updated e appointment.cancelled
| Campo | Tipo |
|---|---|
id | uuid |
contact_id | uuid |
data_hora | datetime |
status | string |
duracao_minutos | int ou null |
servico_id | uuid ou null |
profissional_id | uuid ou null |
valor | número ou null |
pago | booleano ou null |
motivo_cancelamento | string ou null |
created_at | datetime ou null |
payment.confirmed
| Campo | Tipo |
|---|---|
id | uuid |
contact_id | uuid ou null |
appointment_id | uuid ou null |
valor_brl | número |
tipo | string |
status | string |
paid_at | datetime ou null |
created_at | datetime |
conversation.handoff
| Campo | Tipo |
|---|---|
conversation_id | uuid |
contact_id | uuid |
canal | string |
motivo | string |
ocorrido_em | datetime |
Nenhum trecho da conversa é enviado.
Cabeçalhos
| Cabeçalho | Para que serve |
|---|---|
X-Octo-Event | Tipo do evento |
X-Octo-Timestamp | Momento do envio, em segundos Unix |
X-Octo-Signature | Assinatura no formato sha256=<hex> |
X-Octo-Delivery | Identificador desta tentativa de envio |
Verificar a assinatura
Verifique sempre. Sem isso, qualquer um que descubra a sua URL pode fingir ser a OctoSolve.
A assinatura é um HMAC SHA256 do texto {timestamp}.{corpo}, usando o secret do endereço como chave. O corpo é o texto cru recebido, antes de virar objeto.
Rejeite envios com X-Octo-Timestamp de mais de 5 minutos atrás, para bloquear reenvio malicioso.
Python
Node
No Express, guarde o corpo cru com express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }). Se você assinar em cima do JSON já convertido e convertido de volta, a assinatura não vai bater.
O mesmo evento pode chegar duas vezes
Esta é a parte mais importante desta página.
A entrega é pelo menos uma vez. Em falha de rede ou reenvio, o mesmo evento pode chegar repetido. O seu sistema precisa aguentar isso.
Como resolver: guarde o campo id do evento (o evt_...) e ignore o que você já processou. Esse id é estável, inclusive quando você clica em Reenviar no painel.
A ordem também não é garantida. Uma tentativa que falhou e foi reenviada pode chegar depois de um evento mais novo. Se a ordem importa para você, use o created_at do evento, não a ordem de chegada.
Se o seu endereço não responder
Consideramos entregue quando a resposta é 2xx. Qualquer outra coisa é falha.
Tentamos de novo, com espaço crescente entre as tentativas:
| Tentativa | Depois de |
|---|---|
| 2ª | 1 minuto |
| 3ª | 5 minutos |
| 4ª | 30 minutos |
| 5ª | 2 horas |
| 6ª | 6 horas |
| última | 24 horas |
Algumas respostas não são tentadas de novo, porque insistir não adiantaria:
3xx(redirecionamento): não seguimos redirecionamento, por segurança. Cadastre o endereço final.4xx, com exceção de408e429: quer dizer que o endereço existe mas recusou. Corrija e reenvie pelo painel.
Respondemos ao Retry-After quando ele pede um tempo maior que o nosso, até o limite de 24 horas.
Endereço desligado automaticamente
Depois de 20 tentativas seguidas com falha, desligamos o endereço e avisamos você no painel. É proteção contra endereço abandonado gerando fila infinita.
Ele não é apagado: você conserta o seu lado e clica em reativar.
Requisitos do endereço
| Regra | Motivo |
|---|---|
Precisa ser https:// na porta 443 | Evento trafega com dado do seu cliente |
| Não pode apontar para rede interna | Proteção contra uso da OctoSolve para atacar redes privadas |
| Não pode ter usuário e senha na URL | Formato usado para enganar leitor humano |
| Responda rápido, em até 10 segundos | Passou disso, tratamos como falha e tentamos de novo |
Responda 200 assim que receber e processe depois, em segundo plano. Não deixe o processamento inteiro dentro da requisição.
Limites por plano
| Plano | Webhooks | Endereços |
|---|---|---|
| Starter | não | 0 |
| Plus | sim | 5 |
| Pro | sim | 10 |
| Enterprise | sim | sob medida |
O limite de requisições por minuto da página de Limites vale para a API. Envio de webhook é nosso, não consome a sua cota.
Receita para Make ou n8n
- Crie um cenário (Make) ou workflow (n8n) começando com Webhook ou Webhook Trigger.
- Copie a URL que a ferramenta gerar.
- Na OctoSolve, vá em Configurações, aba API e integrações, e cadastre essa URL escolhendo os eventos.
- Copie o secret que aparece uma única vez e guarde.
- No fluxo, adicione um passo que confira a assinatura (as duas ferramentas têm nó de código; use o exemplo em Node acima).
- Adicione um passo que ignore evento com
idjá visto, guardando os ids num Data Store (Make) ou numa tabela (n8n). - Só depois disso, ligue o passo que faz o trabalho de verdade.
Os passos 5 e 6 parecem burocracia, mas são o que separa uma automação que funciona de uma que duplica cobrança no fim de semana.
Testar
Enquanto você monta, aponte para um coletor público (como o webhook.site) para ver o formato real do evento chegando. Depois troque para o seu endereço definitivo e rotacione o secret, porque o antigo passou por um serviço de terceiro.