Pular para o conteúdo

Muda → Sistema externo

Enviar eventos do Muda para sua API

Crie uma assinatura na Central de Webhooks, escolha os eventos e receba cada entrega com assinatura HMAC, identificadores de correlação e tentativas controladas.

Início rápido

Primeira entrega ponta a ponta

Prepare o receptor antes de ativar a assinatura. Assim, o primeiro evento já pode ser validado e confirmado.

  1. 1

    Disponibilize um endpoint HTTPS

    O destino deve ser público, usar HTTPS na porta 443 e aceitar POST com application/json. Redirecionamentos e endereços de rede privada são bloqueados.
  2. 2

    Crie a assinatura no Muda

    Abra Configurações → Integrações e API → Central de Webhooks. Informe a URL, escolha a conexão e selecione os eventos necessários.
  3. 3

    Guarde o segredo exibido

    A credencial deve ficar em um cofre de segredos no servidor receptor. Nunca a exponha no frontend, em logs ou no repositório.
  4. 4

    Valide a assinatura e responda rápido

    Verifique os bytes brutos antes de interpretar o JSON. Persista ou enfileire o evento e responda 2xx; o trabalho pesado deve acontecer de forma assíncrona.

    Receptor Node.js / Express

    javascript

    import express from 'express';
    import { verifyMudaWebhook } from './verify-muda-webhook.js';
    
    const app = express();
    app.post(
      '/webhooks/muda',
      express.raw({ type: 'application/json', limit: '256kb' }),
      async (req, res) => {
      const rawBody = req.body.toString('utf8');
      const signature = req.header('x-muda-webhook-signature');
      const idempotencyKey = req.header('idempotency-key');
    
      if (!verifyMudaWebhook(rawBody, signature, process.env.MUDA_WEBHOOK_SECRET)) {
        return res.status(401).json({ error: 'invalid_signature' });
      }
      if (!idempotencyKey) {
        return res.status(400).json({ error: 'missing_idempotency_key' });
      }
    
      try {
        const event = JSON.parse(rawBody);
        // Use uma restricao unica por Idempotency-Key. A funcao deve retornar
        // "duplicate" (sem erro) quando a chave ja tiver sido persistida.
        const result = await persistWebhookEvent({ idempotencyKey, event });
        if (result === 'duplicate') {
          return res.status(200).json({ received: true, duplicate: true });
        }
        return res.status(202).json({ received: true });
      } catch (error) {
        return res.status(503).json({ error: 'durable_persistence_failed' });
      }
    });
  5. Acompanhe o histórico

    Confirme o status, duração, número da tentativa e resposta do destino. Falhas temporárias entram em retry automaticamente.

Autenticidade

Valide HMAC antes de confiar no evento

A assinatura usa SHA-256 sobre timestamp + "." + corpo bruto. Rejeite timestamps fora da tolerância de 300 segundos.

Verificação HMAC com comparação constante

javascript

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyMudaWebhook(rawBody, signatureHeader, secret) {
  const parts = Object.fromEntries(
    String(signatureHeader || '').split(',').map((part) => part.trim().split('='))
  );
  const timestamp = Number(parts.t);
  if (!Number.isSafeInteger(timestamp)) return false;

  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > 300) return false;
  if (!/^[a-f0-9]{64}$/i.test(parts.v1 || '')) return false;

  const expected = createHmac('sha256', secret)
    .update(timestamp + '.' + rawBody)
    .digest('hex');
  const receivedBytes = Buffer.from(parts.v1, 'hex');
  const expectedBytes = Buffer.from(expected, 'hex');

  return receivedBytes.length === expectedBytes.length
    && timingSafeEqual(receivedBytes, expectedBytes);
}

HTTP

Cabeçalhos enviados em cada tentativa

Cabeçalhos enviados em cada tentativa de webhook
CabeçalhoFinalidade
Idempotency-KeyIdentificador estável da entrega, mantido entre tentativas
X-Muda-Delivery-IdIdentificador operacional da entrega
X-Muda-Event-IdMesmo id do envelope do evento
X-Muda-Event-TypeTipo canônico do catálogo
X-Muda-Event-VersionVersão 2026-07-01
X-Muda-Request-IdCorrelação para diagnóstico
X-Muda-Webhook-Secret-VersionVersão da credencial usada
X-Muda-Webhook-Signaturet=<unix>,v1=<hmac hexadecimal>
X-Muda-Webhook-TimestampTimestamp Unix usado na assinatura

Assinaturas

Escolha somente os eventos necessários

Filtrar na origem reduz tráfego, custo de processamento e superfície de dados no sistema receptor.

32 eventos encontrados

Leads

lead.added

Lead adicionado

Disponível para assinatura
lead.updated

Lead editado

Disponível para assinatura
lead.deleted

Lead excluido

Disponível para assinatura
lead.restored

Lead restaurado

Disponível para assinatura
lead.stage_changed

Etapa do lead alterada

Disponível para assinatura
lead.responsible_changed

Responsavel do lead alterado

Disponível para assinatura

Contatos

contact.added

Contato adicionado

Disponível para assinatura
contact.updated

Contato editado

Disponível para assinatura
contact.deleted

Contato excluido

Disponível para assinatura
contact.restored

Contato restaurado

Disponível para assinatura
contact.responsible_changed

Responsavel do contato alterado

Disponível para assinatura

Empresas

company.added

Empresa adicionada

Disponível para assinatura
company.updated

Empresa editada

Disponível para assinatura
company.deleted

Empresa excluida

Disponível para assinatura
company.restored

Empresa restaurada

Disponível para assinatura
company.responsible_changed

Responsavel da empresa alterado

Disponível para assinatura

Tarefas

task.added

Tarefa adicionada

Disponível para assinatura
task.updated

Tarefa editada

Disponível para assinatura
task.deleted

Tarefa excluida

Disponível para assinatura
task.responsible_changed

Responsavel da tarefa alterado

Disponível para assinatura

Leads de entrada

incoming_lead.added

Lead de entrada adicionado

Disponível para assinatura
incoming_lead.updated

Lead de entrada editado

Disponível para assinatura
incoming_lead.deleted

Lead de entrada excluido

Disponível para assinatura

Mensagens

message.incoming

Mensagem recebida

Disponível para assinatura

Conversas

talk.added

Conversa adicionada

Disponível para assinatura
talk.updated

Conversa editada

Disponível para assinatura

Notas

note.lead_added

Nota adicionada ao lead

Disponível para assinatura
note.contact_added

Nota adicionada ao contato

Disponível para assinatura
note.company_added

Nota adicionada a empresa

Disponível para assinatura

Produtos

product.added

Produto adicionado

Disponível para assinatura
product.updated

Produto editado

Disponível para assinatura
product.deleted

Produto excluido

Disponível para assinatura

Confiabilidade

Retries, circuit breaker e reenvio

Tentativas automáticas

Falhas temporárias recebem novas tentativas com backoff, sem mudar a chave idempotente.

Circuit breaker

Falhas consecutivas pausam pressão sobre o destino até que ele volte a responder.

Histórico operacional

Cada tentativa registra status, duração, request id e erro resumido, sem expor segredo.

Contrato do receptor

Como o Muda interpreta sua resposta

Interpretação das respostas HTTP do receptor
RespostaResultadoComportamento
2xxEntrega confirmadaNão haverá nova tentativa para esta entrega.
400–499 (exceto 408 / 425 / 429)Rejeição permanenteRevise autenticação, rota ou contrato antes de reativar.
408 / 425 / 429Falha temporáriaO Muda agenda nova tentativa respeitando sua política.
500–599Falha temporária do destinoO Muda agenda nova tentativa com backoff.
TimeoutDestino não respondeu no limiteA conexão é encerrada e a entrega entra em retry.

Diagnóstico

Solução de problemas

Assinatura inválida

Confirme que o segredo correto foi usado e que a verificação recebeu exatamente o corpo bruto da requisição.

Timestamp expirado

Sincronize o relógio via NTP e use o timestamp do cabeçalho, não o momento do processamento assíncrono.

Entregas duplicadas

Use Idempotency-Key como chave única e confirme duplicatas com uma resposta 2xx.

Timeout recorrente

Responda após persistir/enfileirar. Não execute integrações lentas dentro da requisição.

Assinatura pausada

Revise o histórico, corrija o destino e reative somente depois de um teste saudável.

Checklist

Receptor pronto para produção

  • A URL usa HTTPS público e não redireciona para redes privadas.
  • O segredo está em um cofre e existe procedimento de rotação.
  • A assinatura é validada antes do JSON ser interpretado.
  • O timestamp expirado e assinaturas inválidas são rejeitados com 401.
  • Idempotency-Key possui restrição única no armazenamento do receptor.
  • Logs guardam request id e duração, mas não guardam segredo ou payload sensível.

Monitore p95/p99 de resposta, taxa de 5xx e volume de retries. A confirmação rápida protege o sistema receptor e reduz latência de entrega.