API

Webhooks

Receber notificações de eventos em tempo real via webhooks.

Webhooks

Em breve na API pública

O gerenciamento de webhooks via API (/api/v1/webhooks) ainda não está disponível. Por enquanto, webhooks podem ser configurados diretamente pelo painel do Ecosys Auto em Configurações → Webhooks.

Para dúvidas, entre em contato: suporte@ecosysauto.ai

Webhooks permitem que você receba notificações em tempo real sobre eventos importantes: novos veículos cadastrados, negócios ganhos/perdidos, atividades vencendo e muito mais.

Como Funciona

┌─────────────────────┐     ┌─────────────────────┐     ┌─────────────────────┐
│    Evento Ocorre    │────>│     Ecosys Auto      │────>│   Seu Servidor      │
│  (ex: negócio       │     │   envia POST        │     │   processa e        │
│   ganho)            │     │   para sua URL      │     │   responde 200 OK   │
└─────────────────────┘     └─────────────────────┘     └─────────────────────┘
  1. Um evento ocorre na plataforma (veículo cadastrado, negócio ganho, etc.)
  2. O Ecosys Auto envia um POST para a URL configurada
  3. Seu servidor processa o evento e responde com 200 OK
  4. Se falhar, tentamos novamente com backoff exponencial

Eventos Disponíveis

Eventos de Veículos

EventoQuando é Disparado
vehicle.createdNovo veículo cadastrado
vehicle.updatedDados/fase/preço alterados
vehicle.soldStatus alterado para vendido
vehicle.phase_changedVeículo movido no kanban
vehicle.price_changedPreço atualizado
vehicle.removedVeículo arquivado

Eventos de Negócios

EventoQuando é Disparado
deal.createdNovo negócio criado
deal.updatedDados ou fase alterados
deal.phase_changedNegócio movido no pipeline
deal.wonMarcado como ganho
deal.lostMarcado como perdido

Eventos de Clientes

EventoQuando é Disparado
client.createdNovo cliente cadastrado
client.updatedDados alterados
client.deactivatedCliente desativado

Eventos de Atividades

EventoQuando é Disparado
activity.createdNova atividade criada
activity.completedAtividade concluída
activity.due_soon24h antes do vencimento
activity.overduePrazo expirado

Eventos Financeiros

EventoQuando é Disparado
financial.createdNovo registro financeiro
financial.paidPagamento confirmado
financial.overdueVencimento expirado

Formato do Payload

Todas as notificações seguem este formato:

{
  "id": "evt_abc123def456",
  "type": "vehicle.created",
  "api_version": "v1",
  "created_at": "2026-02-04T14:30:00Z",
  "data": {
    "object": {
      "id": "uuid-do-veiculo",
      "title": "Honda Civic EXL 2.0 2024",
      "brand": "Honda",
      "model": "Civic",
      "price": 142900.00,
      "phase": "entrada",
      "status": "ativo",
      "created_at": "2026-02-04T14:30:00Z"
    },
    "previous_attributes": null
  },
  "team_id": "uuid-do-time",
  "webhook_id": "uuid-do-webhook"
}

Para eventos de atualização, previous_attributes contém os valores anteriores:

{
  "id": "evt_update123",
  "type": "vehicle.updated",
  "data": {
    "object": {
      "id": "uuid-do-veiculo",
      "phase": "em-vitrine",
      "price": 139900.00
    },
    "previous_attributes": {
      "phase": "entrada",
      "price": 142900.00
    }
  }
}

Verificando a Assinatura

Para garantir que a notificação veio do Ecosys Auto, verifique a assinatura no header X-Ecosys-Auto-Signature.

Headers Enviados

HeaderDescrição
X-Ecosys-Auto-SignatureAssinatura HMAC-SHA256
X-Ecosys-Auto-TimestampTimestamp Unix do envio
X-Ecosys-Auto-Event-IdID único do evento
Content-Typeapplication/json

Verificação em Node.js

import crypto from 'crypto';
import express from 'express';

const app = express();
const WEBHOOK_SECRET = process.env.ECOSYS_AUTO_WEBHOOK_SECRET;

app.use('/webhook', express.raw({ type: 'application/json' }));

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-ecosys-auto-signature'];
  const timestamp = req.headers['x-ecosys-auto-timestamp'];
  const payload = req.body.toString();

  // Verificar timestamp (previne replay attacks — janela de 5 minutos)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    return res.status(401).json({ error: 'Timestamp expirado' });
  }

  // Calcular assinatura esperada
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSignature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(signedPayload)
    .digest('hex');

  // Comparação segura (previne timing attacks)
  if (!crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  )) {
    return res.status(401).json({ error: 'Assinatura inválida' });
  }

  // Processar evento de forma assíncrona
  const event = JSON.parse(payload);

  switch (event.type) {
    case 'vehicle.created':
      // Publicar no portal de anúncios, enviar notificação, etc.
      break;
    case 'deal.won':
      // Atualizar métricas, gerar contrato, etc.
      break;
    case 'activity.overdue':
      // Enviar alerta, criar ticket, etc.
      break;
  }

  // Responda RAPIDAMENTE com 200 OK
  res.status(200).json({ received: true });
});

Verificação em Python

import hmac
import hashlib
import time
import os
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = os.environ['ECOSYS_AUTO_WEBHOOK_SECRET']

@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Ecosys-Auto-Signature')
    timestamp = request.headers.get('X-Ecosys-Auto-Timestamp')
    payload = request.get_data(as_text=True)

    # Verificar timestamp
    now = int(time.time())
    if abs(now - int(timestamp)) > 300:
        return jsonify({'error': 'Timestamp expirado'}), 401

    # Calcular assinatura
    signed_payload = f"{timestamp}.{payload}"
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode(),
        signed_payload.encode(),
        hashlib.sha256
    ).hexdigest()

    # Comparação segura
    if not hmac.compare_digest(signature, expected_signature):
        return jsonify({'error': 'Assinatura inválida'}), 401

    event = request.json
    # Processar evento...

    return jsonify({'received': True}), 200

Política de Retentativas

Se sua URL não responder com 2xx, tentaremos novamente:

TentativaIntervalo
1aImediato
2a5 minutos
3a30 minutos
4a2 horas
5a12 horas
6a24 horas

Após 6 tentativas falhas consecutivas, o webhook é desativado automaticamente. Você receberá um email de alerta.

Boas Práticas

  • Responda rapidamente — Retorne 200 OK em até 5 segundos
  • Processe assincronamente — Use filas (Bull, Celery, etc.) para tarefas demoradas
  • Implemente idempotência — O mesmo evento pode ser entregue mais de uma vez (salve o id do evento)
  • Verifique a assinatura — Sempre valide a autenticidade antes de processar
  • Use HTTPS — Obrigatório para receber webhooks

Roadmap

Planejamos disponibilizar os seguintes endpoints para gerenciar webhooks via API:

GET    /api/v1/webhooks         — Listar webhooks configurados
POST   /api/v1/webhooks         — Criar webhook
PUT    /api/v1/webhooks/:id     — Atualizar webhook
DELETE /api/v1/webhooks/:id     — Remover webhook

On this page