API

Webhooks

Receba notificações em tempo real sobre eventos na plataforma Nobur.

Webhooks

Webhooks permitem que seu sistema receba notificações automáticas quando eventos ocorrem na plataforma Nobur. Em vez de consultar a API periodicamente (polling), seu endpoint recebe uma requisição HTTP POST em tempo real.

Como Funciona

  1. Você registra uma URL de endpoint e os eventos desejados
  2. Quando um evento ocorre, o Nobur envia um POST para sua URL
  3. Seu endpoint retorna 2xx para confirmar o recebimento
  4. Se a entrega falhar, o Nobur tenta novamente com backoff exponencial

Eventos Disponíveis

EventoDescrição
broker.createdCorretor criado
broker.updatedCorretor atualizado
broker.deletedCorretor excluído
property.createdImóvel criado
property.updatedImóvel atualizado
property.deletedImóvel excluído
party.createdParte criada
party.updatedParte atualizada
party.deletedParte excluída
proposal.createdProposta criada
proposal.updatedProposta atualizada
proposal.deletedProposta excluída
contract.createdContrato criado
contract.updatedContrato atualizado
contract.deletedContrato excluído
document.createdDocumento criado
document.updatedDocumento atualizado
document.deletedDocumento excluído

Registrando um Webhook

curl -X POST https://api.nobur.com.br/public/v1/webhooks \
  -H "X-API-Key: nbr_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://meuapp.com/webhooks/nobur",
    "events": ["broker.created", "broker.updated", "property.created"]
  }'

Resposta (201):

{
  "id": "whs_abc123",
  "url": "https://meuapp.com/webhooks/nobur",
  "events": ["broker.created", "broker.updated", "property.created"],
  "secret": "whsec_...",
  "is_active": true,
  "created_at": "2026-02-15T12:00:00Z",
  "updated_at": "2026-02-15T12:00:00Z"
}

O campo secret é retornado apenas na criação. Guarde-o em local seguro para verificar assinaturas.

Formato do Payload

Cada entrega contém um payload JSON com as informações do evento:

{
  "id": "whd_abc123",
  "event_type": "broker.created",
  "created_at": "2026-02-15T12:00:00Z",
  "payload": {
    "id": "brk_abc123",
    "name": "João da Silva",
    "creci": "12345-F",
    "email": "joao@imobiliaria.com",
    "tenant_id": "tnt_abc123",
    "organization_id": "org_abc123",
    "created_at": "2026-02-15T12:00:00Z",
    "updated_at": "2026-02-15T12:00:00Z"
  }
}

Verificação de Assinatura

Cada entrega inclui o header X-Webhook-Signature com uma assinatura HMAC-SHA256 do corpo da requisição, usando o secret do webhook como chave.

Verifique sempre a assinatura para garantir que a requisição veio do Nobur.

Exemplo em Node.js

const crypto = require("crypto");

function verifyWebhookSignature(body, signature, secret) {
  const expectedSignature = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(body, "utf8")
    .digest("hex");

  if (signature.length !== expectedSignature.length) {
    return false;
  }

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// No handler do webhook
app.post("/webhooks/nobur", (req, res) => {
  const signature = req.headers["x-webhook-signature"];
  const body = req.rawBody; // corpo da requisição como string

  if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send("Assinatura inválida");
  }

  const event = JSON.parse(body);
  console.log(`Evento recebido: ${event.event_type}`);

  // Processar o evento
  switch (event.event_type) {
    case "broker.created":
      // Criar corretor no seu sistema
      break;
    case "property.updated":
      // Atualizar imóvel no seu sistema
      break;
  }

  res.status(200).send("OK");
});

Exemplo em Python

import hmac
import hashlib

def verify_webhook_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode("utf-8"),
        body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# No handler do webhook (Flask)
@app.route("/webhooks/nobur", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-Webhook-Signature")
    body = request.get_data()

    if not verify_webhook_signature(body, signature, WEBHOOK_SECRET):
        return "Assinatura inválida", 401

    event = request.get_json()
    print(f"Evento recebido: {event['event_type']}")

    # Processar o evento
    if event["event_type"] == "broker.created":
        # Criar corretor no seu sistema
        pass

    return "OK", 200

Retentativas

Se a entrega falhar (timeout ou status HTTP diferente de 2xx), o Nobur tenta novamente com backoff exponencial:

TentativaIntervalo aproximado
1aimediata
2a1 minuto
3a5 minutos
4a30 minutos
5a2 horas

Após 5 tentativas sem sucesso, a entrega é marcada como failed.

Consultando Entregas

Você pode consultar o histórico de entregas de um webhook:

curl -X GET "https://api.nobur.com.br/public/v1/webhooks/whs_abc123/deliveries?limit=10" \
  -H "X-API-Key: nbr_sua_chave_aqui"

Resposta:

{
  "items": [
    {
      "id": "whd_abc123",
      "subscription_id": "whs_abc123",
      "event_type": "broker.created",
      "status": "success",
      "http_status": 200,
      "attempt_count": 1,
      "created_at": "2026-02-15T12:00:00Z",
      "completed_at": "2026-02-15T12:00:01Z"
    }
  ],
  "page_info": {
    "has_next_page": false,
    "has_previous_page": false
  }
}

Status de Entrega

StatusDescrição
pendingEntrega aguardando envio ou retentativa
successEntrega concluída com sucesso (resposta 2xx)
failedTodas as tentativas falharam

Boas Práticas

  • Responda rapidamente -- retorne 200 o mais rápido possível e processe o evento de forma assíncrona
  • Implemente idempotência -- seu endpoint pode receber o mesmo evento mais de uma vez; use o id da entrega para deduplicação
  • Verifique a assinatura -- sempre valide o header X-Webhook-Signature antes de processar
  • Use HTTPS -- a URL do webhook deve usar HTTPS em produção
  • Monitore falhas -- consulte o endpoint de entregas para identificar problemas