Webhooks

Receba eventos da frota em tempo real com webhooks da Cobli e valide as entregas com assinatura HMAC.


O que é webhook?

ponto de interesse Webhook é uma tecnologia que permite que a Cobli envie uma requisição HTTP POST para a sua aplicação sempre que um evento relevante ocorrer na frota — sem que você precise ficar consultando nossa API. Use webhooks para:

  • Disparar alertas em tempo real (câmera, velocidade, bateria baixa)
  • Integrar rastreamento de frota com sistemas internos
  • Automatizar fluxos a partir de eventos de ignição ou ponto de interessse

Eventos disponíveis

Tipo de assinaturaeventType no payloadDescrição
geofence_ingeofence_inVeículo entrou em um ponto de interesse
geofence_outgeofence_outVeículo saiu de um ponto de interesse
ignition_onignition_onIgnição ligada
ignition_offignition_offIgnição desligada
positionpositionPosição periódica com ignição ligada
position_sleepposition_sleepPosição periódica com ignição desligada
speedalert_driven_over_speedInício de alerta de excesso de velocidade
speedend_alert_driven_over_speedFim de alerta de excesso de velocidade
battery_external_lowbattery_external_lowTensão da bateria abaixo do threshold
battery_external_disconnectedbattery_external_disconnectedBateria externa desconectada
battery_external_reconnectedbattery_external_reconnectedBateria externa reconectada
hard_breakhard_breakFrenagem brusca detectada pela câmera
fast_accelerationfast_accelerationAceleração brusca detectada pela câmera
speedy_turnspeedy_turnCurva acentuada detectada pela câmera
tailgatingtailgatingSeguimento próximo detectado pela câmera
front_collision_warningfront_collision_warningAviso de colisão frontal detectado pela câmera
distracted_drivingdistracted_drivingDistração ao volante detectada pela câmera
eyes_closedeyes_closedOlhos fechados detectados pela câmera
phone_usagephone_usageUso de celular detectado pela câmera
smokingsmokingUso de cigarro detectado pela câmera
yawnyawnBocejo detectado pela câmera
sossosSinal SOS acionado pelo motorista

speed: ao subscrever o tipo "speed", você recebe automaticamente tanto alert_driven_over_speed quanto end_alert_driven_over_speed — os dois eventos são inseparáveis.

Eventos de câmera: disponíveis apenas para frotas com dispositivos de câmera integrada Cobli. A disponibilidade de cada tipo de evento depende do modelo do dispositivo instalado.


Primeiros passos

  1. Crie um endpoint HTTP que aceite POST com Content-Type: application/json.

    • Responda 2xx em até 5 segundos. Processe de forma assíncrona se necessário.
    • Valide o header X-Cobli-Signature antes de processar — ver Verificação de assinatura.
  2. Cadastre a assinatura no painel Cobli em Configurações → Webhooks.

    • Informe a URL, a chave secreta e os tipos de evento desejados.
  3. Valide a integração — gere um evento de teste (ex: ligue a ignição de um veículo) e confirme que seu endpoint recebe o payload esperado.


Formato dos eventos

Todos os eventos seguem o mesmo envelope:

{
  "eventId"  : "7decdf99-283d-4c70-9b95-a3b3f896e9b9",
  "eventTime": "2024-03-15T10:23:07Z",
  "eventType": "geofence_in",
  "eventData": { }
}
CampoTipoDescrição
eventIdUUIDIdentificador determinístico do evento — derivado de fleetId + deviceId + eventType + eventTime. Dois envios do mesmo evento produzem o mesmo eventId. Use para deduplicação.
eventTimestring ISO 8601 (UTC)Momento em que o evento ocorreu no dispositivo
eventTypestringTipo do evento (ver coluna "eventType no payload" na tabela acima)
eventDataobjetoDados específicos do evento (detalhados abaixo)

Campos comuns em eventData

Os campos abaixo estão disponíveis em todos os eventos. Campos opcionais são omitidos (ou nulos) quando o dado não está disponível — projete seu integrador para tolerar ausência.

CampoTipoObrigatórioDescrição
deviceIdstringsimIdentificador do dispositivo
vehicleIdUUIDsimIdentificador do veículo
fleetIdUUIDsimIdentificador da frota
licensePlatestringsimPlaca do veículo
cobliIdstringnãoIdentificador alfanumérico de 4 caracteres do dispositivo (ex: "R875"); presente quando disponível
driverIdUUIDnãoIdentificador do motorista, quando identificado no momento do evento
latitudenumbernãoLatitude no momento do evento
longitudenumbernãoLongitude no momento do evento
headingintnãoDireção em graus (0–360)
ignitionstringnãoEstado da ignição: "ON" ou "OFF"
odometernumbernãoOdômetro em km. Requer odômetro inicial cadastrado no veículo; para dispositivos com rede CAN, o valor é obtido diretamente pelo barramento
batteryVoltagelongnãoTensão da bateria em milivolts
fuelLevellongnãoNível de combustível em mililitros (mL) — disponível apenas em dispositivos com rede CAN
rpmlongnãoRotação do motor (RPM) — disponível apenas em dispositivos com rede CAN
speedInKmhnumbernãoVelocidade do veículo em km/h no momento do evento
connectionTypestringnãoTipo de rede: GSM, THREE_G, FOUR_G_LTE, LTE, WIFI
numberOfSatellitesintnãoNúmero de satélites GPS
hdopnumbernãoPrecisão horizontal do GPS (valores menores = maior precisão)

Verificação de assinatura

Cada requisição inclui o header X-Cobli-Signature com a assinatura HMAC-SHA256 do corpo (eventData serializado), codificada em hexadecimal. Use a secretKey configurada na assinatura para verificar a autenticidade:

import hmac, hashlib

def verificar(secret: str, body: bytes, assinatura: str) -> bool:
    esperado = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, assinatura)

Rejeite requisições sem X-Cobli-Signature válido com status 400. Nunca processe um payload cuja assinatura não pôde ser verificada.


Payload por tipo de evento

GEOFENCE_IN e GEOFENCE_OUT

Disparado quando um veículo entra ou sai de um ponto de interesse cadastrado.

{
  "eventId"  : "7decdf99-283d-4c70-9b95-a3b3f896e9b9",
  "eventTime": "2024-03-15T10:23:07Z",
  "eventType": "geofence_in",
  "eventData": {
    "deviceId"    : "879797465464874",
    "vehicleId"   : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"     : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate": "ABC1D23",
    "cobliId"     : "R875",
    "driverId"    : "d1234567-0000-0000-0000-000000000001",
    "latitude"    : -23.764235,
    "longitude"   : -46.595110,
    "geofenceId"  : "59e88bca-d3b9-4980-95a9-421fe2ffb275",
    "name"        : "MEU LOCAL DE INTERESSE",
    "address"     : "Rua Lourenço Marques, 297, São Paulo - SP, 04547-100",
    "speedInKmh"  : 12.5,
    "odometer"    : 45230.5
  }
}

Campos adicionais:

CampoTipoObrigatórioDescrição
geofenceIdUUIDnãoIdentificador do ponto de interesse
namestringnãoNome do ponto de interesse
addressstringnãoEndereço do ponto de interesse

IGNITION_ON e IGNITION_OFF

Disparado quando há mudança no estado da ignição do veículo.

{
  "eventId"  : "a1b2c3d4-0000-0000-0000-111122223333",
  "eventTime": "2024-03-15T08:00:00Z",
  "eventType": "ignition_on",
  "eventData": {
    "deviceId"        : "879797465464874",
    "vehicleId"       : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"         : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"    : "ABC1D23",
    "cobliId"         : "R875",
    "driverId"        : "d1234567-0000-0000-0000-000000000001",
    "latitude"        : -23.550520,
    "longitude"       : -46.633308,
    "heading"         : 90,
    "speedInKmh"      : 15.3,
    "ignition"        : "ON",
    "odometer"        : 45230.5,
    "batteryVoltage"  : 12450,
    "connectionType"  : "FOUR_G_LTE"
  }
}

driverId é incluído quando um motorista está associado ao veículo no momento do evento.


POSITION e POSITION_SLEEP

Disparado periodicamente com a posição do veículo. POSITION ocorre com ignição ligada; POSITION_SLEEP com ignição desligada. A frequência depende da configuração do dispositivo.

{
  "eventId"  : "b2c3d4e5-0000-0000-0000-222233334444",
  "eventTime": "2024-03-15T10:00:00Z",
  "eventType": "position",
  "eventData": {
    "deviceId"           : "879797465464874",
    "vehicleId"          : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"            : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"       : "ABC1D23",
    "cobliId"            : "R875",
    "latitude"           : -23.550520,
    "longitude"          : -46.633308,
    "heading"            : 180,
    "speedInKmh"         : 45.2,
    "ignition"           : "ON",
    "odometer"           : 45245.0,
    "numberOfSatellites" : 12,
    "hdop"               : 0.9,
    "rpm"                : 1800,
    "fuelLevel"          : 35000,
    "batteryVoltage"     : 12480,
    "connectionType"     : "FOUR_G_LTE"
  }
}

POSITION_SLEEP possui os mesmos campos; a ignição estará como "OFF" e velocidade/RPM geralmente ausentes.


ALERT_DRIVEN_OVER_SPEED

Gerado pela assinatura do tipo speed. Disparado no início de um alerta de excesso de velocidade.

{
  "eventId"  : "c3d4e5f6-0000-0000-0000-333344445555",
  "eventTime": "2024-03-15T14:30:00Z",
  "eventType": "alert_driven_over_speed",
  "eventData": {
    "deviceId"        : "879797465464874",
    "vehicleId"       : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"         : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"    : "ABC1D23",
    "cobliId"         : "R875",
    "driverId"        : "d1234567-0000-0000-0000-000000000001",
    "latitude"        : -23.550520,
    "longitude"       : -46.633308,
    "speedInKmh"      : 95.0,
    "speedLimitInKmh" : 80.0,
    "severity"        : "HIGH",
    "hdop"            : 1.2,
    "batteryVoltage"  : 12450
  }
}

Campos adicionais:

CampoTipoObrigatórioDescrição
speedLimitInKmhnumbersimLimite de velocidade configurado
severitystringsimSeveridade do alerta

END_ALERT_DRIVEN_OVER_SPEED

Gerado pela assinatura do tipo speed. Disparado quando o veículo volta ao limite de velocidade, complementando o alert_driven_over_speed com a duração total do alerta.

{
  "eventId"  : "d4e5f6a7-0000-0000-0000-444455556666",
  "eventTime": "2024-03-15T14:31:30Z",
  "eventType": "end_alert_driven_over_speed",
  "eventData": {
    "deviceId"              : "879797465464874",
    "vehicleId"             : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"               : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"          : "ABC1D23",
    "cobliId"               : "R875",
    "driverId"              : "d1234567-0000-0000-0000-000000000001",
    "latitude"              : -23.552100,
    "longitude"             : -46.634500,
    "speedInKmh"            : 78.0,
    "speedLimitInKmh"       : 80.0,
    "severity"              : "HIGH",
    "startTime"             : "2024-03-15T14:30:00Z",
    "durationAboveInMillis" : 90000,
    "hdop"                  : 1.2,
    "batteryVoltage"        : 12450
  }
}

Campos adicionais:

CampoTipoObrigatórioDescrição
startTimestring ISO 8601 (UTC)simMomento em que o alerta iniciou — equivale ao eventTime do alert_driven_over_speed correspondente
durationAboveInMillislongsimDuração total acima do limite, em milissegundos

Use deviceId + startTime para correlacionar o início e o fim do alerta.


BATTERY_EXTERNAL_LOW

Disparado quando a tensão média da bateria externa cai abaixo do threshold configurado para a frota.

{
  "eventId"  : "e5f6a7b8-0000-0000-0000-555566667777",
  "eventTime": "2024-03-15T22:10:00Z",
  "eventType": "battery_external_low",
  "eventData": {
    "deviceId"                  : "879797465464874",
    "vehicleId"                 : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"                   : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"              : "ABC1D23",
    "cobliId"                   : "R875",
    "latitude"                  : -23.550520,
    "longitude"                 : -46.633308,
    "heading"                   : 0,
    "speedInKmh"                : 8.2,
    "ignition"                  : "OFF",
    "odometer"                  : 45230.5,
    "batteryVoltage"            : 11200,
    "batteryVoltageThresholdMv" : 11500,
    "voltageRegime"             : "LIGHT",
    "connectionType"            : "FOUR_G_LTE"
  }
}

Campos adicionais:

CampoTipoObrigatórioDescrição
batteryVoltageThresholdMvintsimThreshold configurado no momento do disparo (mV)
voltageRegimestringnãoSistema elétrico: "LIGHT" (12 V) ou "HEAVY" (24 V)

BATTERY_EXTERNAL_DISCONNECTED

Disparado quando a bateria externa é desconectada do dispositivo.

{
  "eventId"  : "f6a7b8c9-0000-0000-0000-666677778888",
  "eventTime": "2024-03-15T22:15:00Z",
  "eventType": "battery_external_disconnected",
  "eventData": {
    "deviceId"      : "879797465464874",
    "vehicleId"     : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"       : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"  : "ABC1D23",
    "cobliId"       : "R875",
    "latitude"      : -23.550520,
    "longitude"     : -46.633308,
    "heading"       : 0,
    "speedInKmh"    : 8.2,
    "ignition"      : "OFF",
    "odometer"      : 45230.5,
    "batteryVoltage": 11800,
    "connectionType": "FOUR_G_LTE"
  }
}

BATTERY_EXTERNAL_RECONNECTED

Disparado quando a bateria externa é reconectada ao dispositivo.

{
  "eventId"  : "a7b8c9d0-0000-0000-0000-777788889999",
  "eventTime": "2024-03-15T22:20:00Z",
  "eventType": "battery_external_reconnected",
  "eventData": {
    "deviceId"      : "879797465464874",
    "vehicleId"     : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"       : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"  : "ABC1D23",
    "cobliId"       : "R875",
    "latitude"      : -23.550520,
    "longitude"     : -46.633308,
    "heading"       : 0,
    "speedInKmh"    : 8.2,
    "ignition"      : "OFF",
    "odometer"      : 45230.5,
    "batteryVoltage": 12350,
    "connectionType": "FOUR_G_LTE"
  }
}

Eventos de câmera

Disparado quando um evento de comportamento do motorista ou segurança veicular é detectado pela câmera integrada Cobli. Os 11 tipos de eventos de câmera compartilham a mesma estrutura de payload — o eventType identifica o comportamento detectado.

eventTypeDescrição
hard_breakFrenagem brusca
fast_accelerationAceleração brusca
speedy_turnCurva acentuada
tailgatingSeguimento próximo
front_collision_warningAviso de colisão frontal
distracted_drivingDistração ao volante
eyes_closedOlhos fechados
phone_usageUso de celular
smokingUso de cigarro
yawnBocejo
sosSinal SOS acionado pelo motorista
{
  "eventId"  : "7decdf99-283d-4c70-9b95-a3b3f896e9b9",
  "eventTime": "2024-03-15T10:23:07Z",
  "eventType": "distracted_driving",
  "eventData": {
    "deviceId"           : "879797465464874",
    "vehicleId"          : "05009b4a-bed3-4431-955a-4c3e80dc6697",
    "fleetId"            : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "licensePlate"       : "ABC1D23",
    "cobliId"            : "R875",
    "driverId"           : "d1234567-0000-0000-0000-000000000001",
    "latitude"           : -23.550520,
    "longitude"          : -46.633308,
    "speedInKmh"         : 72.5,
    "heading"            : 180,
    "ignition"           : "ON",
    "batteryVoltage"     : 12800,
    "numberOfSatellites" : 12,
    "hdop"               : 0.8,
    "connectionType"     : "FOUR_G_LTE"
  }
}

Nota: os campos rpm e fuelLevel nunca estão presentes em eventos de câmera — câmeras não têm acesso ao barramento CAN. O campo odometer aparece quando há odômetro inicial cadastrado no veículo; nesse caso, o valor é calculado a partir desse registro. Campos opcionais ausentes são omitidos do JSON (não aparecem como null).


Retentativas e idempotência

Comportamento por código de resposta

Resposta do seu endpointComportamento
2xxEntrega confirmada — sem retentativa
4xx (exceto 429)Falha permanente — não retentado
429 Too Many RequestsRetentado após o intervalo indicado no header Retry-After; se ausente, aplica backoff exponencial
5xxRetentado com backoff exponencial
Timeout (sem resposta em 5 s)Retentado com backoff exponencial

Política de backoff exponencial

ParâmetroValor
Tentativas máximas5
Delay inicial2 s
Multiplicador
Delay máximo15 s
Variação aleatória±20%

Progressão típica (sem jitter): 2 s → 4 s → 8 s → 15 s → 15 s.

Pausa automática por falha em sequência

Após 5 falhas consecutivas para a mesma URL de destino, as entregas para aquela URL são pausadas automaticamente por 60 segundos. Após o intervalo, as entregas são retomadas sem intervenção necessária.

Essa pausa afeta apenas a URL com falhas — outras assinaturas com URLs diferentes não são impactadas.

Use eventId como chave de idempotência. Em caso de retentativa, o mesmo evento pode ser entregue mais de uma vez. Armazene os IDs já processados para evitar efeitos duplicados.


Desativação automática por falha persistente

Se as entregas para uma assinatura falharem continuamente por 7 dias, a assinatura é desativada automaticamente. Nesse estado:

  • O campo active da assinatura passa a false
  • failure_started_at registra o início da janela de falha
  • failure_reason descreve o motivo (ex: "HTTP 503", "TIMEOUT")
  • deactivated_at registra o momento da desativação
  • Nenhum novo evento é entregue até que a assinatura seja reativada manualmente

Para reativar, corrija o endpoint e reabilite a assinatura no painel Cobli. Eventos gerados durante o período de inatividade não são retransmitidos.


Boas práticas

  • Responda rápido, processe depois. Seu endpoint deve responder 2xx em até 5 s. Enfileire o evento e processe em background para evitar timeout.

  • Use eventId como chave de idempotência. O mesmo evento pode ser entregue mais de uma vez em caso de retentativa. Armazene os IDs já processados para evitar duplicidade.

  • Valide sempre a assinatura antes de processar o payload — rejeite requests sem X-Cobli-Signature válido com 400.

  • Não retente erros 4xx no seu lado. A Cobli interpreta 4xx como falha permanente e não fará novas tentativas. Corrija sua integração e aguarde novos eventos.

  • Filtre por eventType no início do handler para ignorar tipos não esperados sem retornar erro — isso evita 4xx desnecessários.

  • Monitore failure_started_at. Esse campo indica que a Cobli está enfrentando falhas de entrega para a sua assinatura. Atue antes dos 7 dias para evitar desativação automática.

  • Tolere campos ausentes. Campos opcionais podem estar ausentes ou nulos dependendo do modelo do dispositivo e da disponibilidade do dado no momento do evento. Não assuma presença.


Formato legado (retrocompatível)

Assinaturas criadas antes da migração para o formato padrão continuam recebendo o payload no formato legado. Esse formato não sofrerá mudanças — a compatibilidade é garantida indefinidamente para assinaturas existentes.

O formato legado é aplicado apenas aos eventos geofence_in e geofence_out.

{
  "event_id"  : "7decdf99-283d-4c70-9b95-a3b3f896e9b9",
  "event_type": "geofence_in",
  "event_time": "2022-09-08 15:47:46",
  "event_data": {
    "fleetId"   : "cf3f1990-2ce3-4ed9-85c5-9a528295ecfe",
    "deviceId"  : "879797465464874",
    "latitude"  : -23.764235,
    "longitude" : -46.595110,
    "geofenceId": "59e88bca-d3b9-4980-95a9-421fe2ffb275",
    "name"      : "MEU LOCAL DE INTERESSE",
    "address"   : "Rua Lourenço Marques, 297, São Paulo - SP, 04547-100"
  }
}

Diferenças em relação ao formato padrão:

AspectoFormato padrãoFormato legado
Chaves do envelopecamelCasesnake_case
eventTime / event_timeISO 8601 (2024-03-15T10:23:07Z)"yyyy-MM-dd HH:mm:ss" (UTC)
vehicleIdpresenteausente
Eventos disponíveistodosapenas ponto de interesse