Webhooks

Guia de Integração de Webhooks

Receba notificações em tempo real sobre eventos de controle de acesso — criação, atualização, transferência, cancelamento, reembolso e uso de ingressos.

Visão geral

Webhooks permitem que seu sistema seja notificado automaticamente sempre que um evento relevante ocorre na plataforma de controle de acesso da Ingresse. Em vez de consultar a API repetidamente (polling), você registra uma URL e passa a receber requisições HTTP POST com o payload do evento.

Como funciona

Você cria uma assinatura (subscription) informando sua URL e os gatilhos desejados. A Ingresse envia um POST assinado para essa URL sempre que um dos eventos ocorre.

Ambientes

AmbienteBase URLUso
production
<WEBHOOK_PROD_HOST>Fornecido junto com suas credenciais no onboarding.
staging
https://awa-access-webhook.staging.ingresse.comAmbiente de testes/homologação.

Gatilhos disponíveis

Ao criar uma assinatura, escolha um ou mais gatilhos. Cada gatilho corresponde a um tipo de evento.

Gatilhoevent_typeDescrição
create
code_createdNovo código/ingresso criado.
update
code_updatedCódigo/ingresso atualizado.
transfer
code_transferredIngresso transferido para outra pessoa.
cancel
code_cancelledIngresso cancelado.
refund
code_refundedIngresso reembolsado.
use
code_usedIngresso utilizado (check-in/validação).

Disponibilidade dos gatilhos

A disponibilidade de cada gatilho para sua integração é confirmada durante o onboarding.

Estrutura do payload

Cada notificação é enviada como POST com corpo JSON. Os campos de topo identificam o evento; payload contém os dados do código/ingresso.

JSON
{
  "id": 1042,
  "event_type": "code_created",
  "created_at": "2026-04-29T13:00:00Z",
  "payload": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "code": "25ABC12345678",
    "external_id": "ext-code-123",
    "type": "individual",
    "status": "active",
    "order_id": "650e8400-e29b-41d4-a716-446655440000",
    "user_id": "750e8400-e29b-41d4-a716-446655440000",
    "event_id": "850e8400-e29b-41d4-a716-446655440000",
    "ticket_id": "950e8400-e29b-41d4-a716-446655440000",
    "can_transfer": true,
    "attributes": {
      "rfc": true,
      "rfc_provider": "biometry"
    },
    "owner": {
      "id": "750e8400-e29b-41d4-a716-446655440000",
      "name": "João Silva",
      "email": "[email protected]"
    },
    "user": {
      "id": "750e8400-e29b-41d4-a716-446655440000",
      "name": "João Silva",
      "email": "[email protected]"
    },
    "event": {
      "id": "95a447c4-0000-4000-8000-000000000002",
      "external_id": "850e8400-e29b-41d4-a716-446655440000",
      "name": "Rock in Rio 2026"
    },
    "ticket": {
      "id": "950e8400-e29b-41d4-a716-446655440000",
      "name": "Pista Premium"
    }
  }
}
CampoTipoDescrição
id
intIdentificador da notificação.
event_type
stringTipo do evento (ex: code_created).
created_at
string (ISO 8601)Momento em que a plataforma ingeriu o evento (não necessariamente o instante exato em que ele ocorreu).
payload
objectDados do código/ingresso afetado.

Os objetos aninhados user, owner, event e ticket são opcionais: dependendo do gatilho e do contexto, podem estar ausentes do payload. O evento pode também trazer campos adicionais além dos documentados aqui (por exemplo owner_id, buyer_id, ownership, validation_metadata, updated_at) — ignore campos desconhecidos ao processar o payload.

O campo event_id de topo e o external_id dentro do objeto event são o UUID externo do evento — o mesmo identificador usado nas URLs da Access Control API; event.id é um identificador interno, não use para correlacionar.

Backfill ao criar uma assinatura

Ao criar uma assinatura, a plataforma pode reenviar eventos passados dentro do escopo configurado. Prepare seu receptor para lidar com um volume inicial maior do que o regime normal.

Segurança e validação de assinatura

Toda requisição inclui o header X-Signature no formato sha256=<hash>. O hash é um HMAC-SHA256 do corpo bruto da requisição usando o secret da assinatura. Sempre valide a assinatura antes de processar o evento.

O secret é gerado no momento da criação da assinatura e entregue pela Ingresse durante o onboarding.

Use o corpo bruto

Calcule o HMAC sobre os bytes exatos do corpo recebido, antes de qualquer parsing JSON. Reserializar o JSON pode alterar o conteúdo e invalidar a assinatura.
JavaScript
const crypto = require('crypto')

function verificarAssinatura(segredo, corpo, cabecalho) {
  const esperado = Buffer.from('sha256=' + crypto.createHmac('sha256', segredo).update(corpo).digest('hex'))
  const recebido = Buffer.from(cabecalho ?? '')
  // timingSafeEqual lança se os buffers tiverem tamanhos diferentes — comparar antes.
  if (esperado.length !== recebido.length) return false
  return crypto.timingSafeEqual(esperado, recebido)
}

// Com Express: use express.raw para receber o corpo bruto
app.post('/webhook', express.raw({ type: '*/*' }), (req, res) => {
  if (!verificarAssinatura(process.env.SEGREDO, req.body, req.headers['x-signature'] ?? ''))
    return res.status(401).send()
  // processar evento de forma assíncrona...
  res.status(200).send()
})

Idempotência

A mesma notificação pode ser entregue mais de uma vez (por exemplo, após uma reentrega). Use o campo id como chave de idempotência para evitar processamento duplicado. O id do envelope é estável entre reentregas: a mesma notificação sempre chega com o mesmo id.

Python
# Exemplo com Redis (Python)
def processar(evento):
    chave = f"webhook:{evento['id']}"
    if redis.set(chave, 1, ex=86400, nx=True) is None:
        return  # já processado
    # processar...

Reentregas e timeouts

Responda com status 2xx o mais rápido possível (idealmente em poucos segundos) e processe o evento de forma assíncrona. O tempo de resposta considerado é de aproximadamente 25 segundos; acima disso a entrega é tratada como timeout. Respostas 3xx contam como sucesso — prefira responder 2xx diretamente.

Respostas 5xx ou timeout são reentregues automaticamente: a entrega é tentada até 3 vezes no total (a tentativa original mais 2 reentregas), com intervalo fixo de aproximadamente 2 minutos. Respostas 4xx (incluindo 429) são consideradas definitivas e não são reentregues. Após esgotadas as tentativas, a entrega é encaminhada para reprocessamento manual pela Ingresse.

Boas práticas

Confirme o recebimento rapidamente, enfileire o trabalho pesado e seja tolerante a entregas fora de ordem e a reentregas duplicadas.

Filtros

É possível restringir quais eventos sua URL recebe usando o objeto filters na criação da assinatura. Apenas eventos cujo payload corresponda aos filtros são entregues.

FiltroTipoDescrição
type
stringTipo do código (ex: individual).
status
stringStatus do ingresso (ex: cancelled).
event_id
string (UUID)Restringe a um evento.
ticket_id
string (UUID)Restringe a um tipo de ingresso.
can_transfer
booleanSomente transferíveis/não transferíveis.
attributes.rfc
booleanBiometria facial ativa.

Somente ingressos individuais com biometria ativa

JSON
{
  "filters": {
    "type": "individual",
    "attributes": {
      "rfc": true
    }
  }
}

Somente ingressos com status cancelado

JSON
{
  "filters": {
    "status": "cancelled"
  }
}

Tipo de ingresso específico, apenas transferíveis

JSON
{
  "filters": {
    "ticket_id": "950e8400-e29b-41d4-a716-446655440000",
    "can_transfer": true
  }
}

Todos os ingressos de um evento com biometria obrigatória

JSON
{
  "filters": {
    "event_id": "850e8400-e29b-41d4-a716-446655440000",
    "attributes": {
      "rfc": true
    }
  }
}