Dashboard

Recursos

Webhooks

Registre endpoints para receber eventos em tempo real.

Scopes: webhooks:read (listar) · webhooks:write (criar, atualizar, excluir)

Listar webhooks

GET /api/webhooks
curl "https://api.placaflow.com.br/api/webhooks" \
  -H "Authorization: Bearer pk_a1b2c3d4..."

Resposta 200:

{
  "webhooks": [
    {
      "id": "w1b2c3d4-...",
      "name": "Sistema ERP",
      "url": "https://api.example.com/webhook",
      "secret": "a1b2c3d4e5f6...",
      "enabled": true,
      "events": ["recognition.created", "alert.triggered"],
      "headers": { "X-Source": "placaflow" },
      "failureCount": 0,
      "lastDeliveryAt": "2026-03-22T14:30:00.000Z",
      "lastDeliveryStatus": 200,
      "createdAt": "2026-03-01T10:00:00.000Z"
    }
  ]
}

Criar webhook

POST /api/webhooks
Content-Type: application/json

Campos:

CampoTipoObrigatórioPadrãoDescrição
namestringsimNome do webhook
urlstringsimURL do endpoint
secretstringnãoauto-geradoSecret para HMAC-SHA256
enabledbooleannãotrueWebhook ativo
eventsstring[]simEventos a receber
headersobjectnão{}Headers HTTP customizados

Eventos disponíveis

EventoDescrição
recognition.createdNova placa reconhecida
alert.triggeredAlerta acionado
camera.onlineCâmera conectou
camera.offlineCâmera desconectou

Exemplo:

curl -X POST "https://api.placaflow.com.br/api/webhooks" \
  -H "Authorization: Bearer pk_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Meu sistema",
    "url": "https://api.example.com/placaflow",
    "events": ["recognition.created", "alert.triggered"],
    "headers": {"Authorization": "Bearer meu-token"}
  }'

Resposta 201: retorna { "webhook": {...} } com secret gerado automaticamente se não fornecido.

Atualizar webhook

PUT /api/webhooks/:id
Content-Type: application/json

Excluir webhook

DELETE /api/webhooks/:id

Verificação de assinatura

Cada requisição inclui o header X-Signature-256 com a assinatura HMAC-SHA256 do body.

Verificação em Node.js:

const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return expected === signature;
}

app.post('/webhook', (req, res) => {
  const sig = req.headers['x-signature-256'];
  if (!verifySignature(req.rawBody, sig, WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  // processar...
});

Verificação em Python:

import hmac, hashlib

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

Erros

CódigoDescrição
400URL ou eventos ausentes
401Não autenticado
404Webhook não encontrado
Esta página foi útil?