Webhooks
Webhooks são requisições HTTP POST enviadas automaticamente quando eventos acontecem na plataforma. Configure uma URL no seu ambiente para receber notificações em tempo real.
Configurando webhooks
Para configurar um novo webhook, acesse o console e crie um novo destino informando a URL do seu endpoint, escolhendo os tópicos (tipos de evento) que deseja receber. Após configurado, toda vez que um evento ocorrer, uma requisição HTTP POST será enviada para a URL cadastrada.
Consumindo webhooks
Cada requisição de webhook é uma requisição HTTP POST que inclui cabeçalhos com metadados do evento e um corpo JSON com os dados do evento.
Cabeçalhos
Todas as requisições de webhook incluem os seguintes cabeçalhos com o prefixo x-hme-:
- Name
content-type- Type
- string
- Description
Tipo do conteúdo. Sempre
application/json.
- Name
x-hme-event-id- Type
- string
- Description
ID único do evento. Use para deduplicação de mensagens.
- Name
x-hme-timestamp- Type
- string
- Description
Timestamp Unix (em segundos) do momento em que o evento foi gerado.
- Name
x-hme-topic- Type
- string
- Description
Tópico do evento (ex:
traffic-violation.created).
- Name
x-hme-signature- Type
- string
- Description
Assinatura HMAC-SHA256 no formato
v0={signature}. Utilizada para verificação de autenticidade.
Exemplo de requisição
Exemplo de requisição HTTP
POST /webhooks HTTP/1.1
Content-Type: application/json
x-hme-event-id: evt_a056V7R7NmNRjl70
x-hme-timestamp: 1704067200
x-hme-topic: traffic-violation.created
x-hme-signature: v0=5f2c5e3b8a...
{
"type": "traffic-violation.created",
"data": {
"id": 1,
"ait": "AIT123456789",
"code": "1234567890",
"license_plate": "ABC1234",
"description": "Excesso de velocidade",
"status": "pending",
"amount": 100.9,
"date": "2024-01-01 12:00:00",
"due_date": "2024-02-01",
"company": {
"id": 1,
"tax_id": "12345678000190",
"external_uid": "EXT_COMPANY_123",
"name": "Empresa Exemplo Ltda"
}
}
}
Corpo da requisição
O corpo da requisição contém os dados do evento em formato JSON. Verifique o atributo type para identificar o tipo de evento.
- Name
type- Type
- string
- Description
Tipo do evento (ex:
traffic-violation.created).
- Name
data- Type
- object
- Description
Dados do recurso associado ao evento.
Exemplo de payload
{
"type": "traffic-violation.created",
"data": {
"id": 1,
"ait": "AIT123456789",
"code": "1234567890",
"license_plate": "ABC1234",
"description": "Excesso de velocidade",
"status": "pending",
"amount": 100.9,
"date": "2024-01-01 12:00:00",
"due_date": "2024-02-01",
"company": {
"id": 1,
"tax_id": "12345678000190",
"external_uid": "EXT_COMPANY_123",
"name": "Empresa Exemplo Ltda"
}
}
}
Verificando assinaturas
Para garantir que uma requisição foi enviada pela API da habilitar.me, verifique a assinatura presente no cabeçalho x-hme-signature.
A assinatura é calculada usando HMAC-SHA256 sobre o corpo da requisição, utilizando a chave secreta do seu webhook.
O valor do cabeçalho x-hme-signature segue o formato:
v0=${signature}
Passos para verificação
- Extraia a assinatura (
v0) do cabeçalhox-hme-signature. - Calcule o HMAC-SHA256 do corpo da requisição usando sua chave secreta.
- Compare a assinatura calculada com a recebida usando comparação em tempo constante.
- Opcionalmente, use o cabeçalho
x-hme-timestamppara rejeitar requisições com timestamps muito antigos e prevenir ataques de replay.
Verificando uma requisição
const crypto = require('crypto')
function verifyWebhook(req, secret) {
const signatureHeader = req.headers['x-hme-signature']
const body = JSON.stringify(req.body)
// 1. Extrair assinatura
const receivedSignature = signatureHeader.replace('v0=', '')
// 2. Calcular assinatura esperada
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex')
// 3. Comparar em tempo constante
const isValid = crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(receivedSignature)
)
if (!isValid) {
throw new Error('Assinatura inválida')
}
// 4. (Opcional) Rejeitar timestamps antigos (ex: 5 minutos)
const timestamp = parseInt(req.headers['x-hme-timestamp'])
const currentTime = Math.floor(Date.now() / 1000)
if (currentTime - timestamp > 300) {
throw new Error('Timestamp expirado')
}
return true
}
Entrega e retentativas
A API opera com garantia de entrega at-least-once (pelo menos uma vez). Isso significa que, em casos raros, um mesmo evento pode ser entregue mais de uma vez. Use o cabeçalho x-hme-event-id para deduplicar mensagens no seu sistema.
Retentativas automáticas
Se o seu endpoint retornar um código de resposta HTTP diferente de 2xx, ou estiver indisponível, a entrega será retentada automaticamente com backoff exponencial. O número máximo de tentativas e o intervalo entre elas são configurados pela plataforma.
Retentativas manuais
Retentativas manuais podem ser acionadas através do portal de gerenciamento de webhooks.
Caso seu endpoint apresente falhas consecutivas, o destino pode ser desativado automaticamente. Endpoints desativados não recebem novos eventos até serem reativados.
Tipos de eventos
Abaixo estão listados todos os tipos de eventos disponíveis, agrupados por recurso. Clique no nome do recurso para acessar a documentação completa.
Empresas
- Name
company.created- Description
Uma nova empresa foi criada.
- Name
company.updated- Description
Uma empresa foi atualizada.
- Name
company.certificate.updated- Description
O certificado digital da empresa foi atualizado.
- Name
company.login.updated- Description
O login da empresa foi atualizado.
- Name
company.sne.updated- Description
O SNE da empresa foi atualizado.
Infrações
- Name
traffic-violation.created- Description
Uma nova infração foi criada.
- Name
traffic-violation.updated- Description
Uma infração foi atualizada.
Indicações
- Name
traffic-violation.indication.created- Description
Uma nova indicação foi criada.
- Name
traffic-violation.indication.updated- Description
Uma indicação foi atualizada.
Guias de Pagamento de Infrações
- Name
traffic-violation.ticket.created- Description
Uma nova guia de pagamento de infração foi criada.
- Name
traffic-violation.ticket.updated- Description
Uma guia de pagamento de infração foi atualizada.
Logins
- Name
login.created- Description
Um novo login foi criado.
- Name
login.updated- Description
Um login foi atualizado.
Usuários do Console
- Name
console-user.created- Description
Um novo usuário do console foi criado.
- Name
console-user.updated- Description
Um usuário do console foi atualizado.
Veículos
- Name
vehicle.created- Description
Um novo veículo foi criado.
- Name
vehicle.updated- Description
Um veículo foi atualizado.
Cobranças
- Name
charge.created- Description
Uma nova cobrança foi criada.
- Name
charge.updated- Description
Uma cobrança foi atualizada.
Guias de Pagamento de Cobranças
- Name
charge.payment-slip.created- Description
Uma nova guia de pagamento de cobrança foi criada.
- Name
charge.payment-slip.updated- Description
Uma guia de pagamento de cobrança foi atualizada.