Skip to main content
Toda mudança de estado relevante na Repass (criar um Afiliado, registrar uma Conversão, aprovar uma Comissão, pagar um Payout) grava o novo estado e um evento de domínio. O conjunto desses eventos forma um log único, imutável e ordenado: o event store. Diferente da maioria das plataformas, esse log é exposto como recurso de API (GET /events). Ele é a sua trilha de auditoria completa: você consegue responder “o que aconteceu, quando, e quem causou” para qualquer recurso, e reconstruir a sequência de decisões que levou a uma Comissão ou Payout específico. O mesmo log é o que alimenta os Webhooks.

O que é um evento

Um evento de domínio é o registro imutável de um fato de negócio. Nasce e nunca muda. Cada evento tem um envelope padronizado, idêntico no GET /events/{id} e no body entregue aos Webhooks:
string
Identificador evt_<ULID>. O ULID dá ordenação cronológica natural: é o cursor de paginação e a ordem em que os eventos são entregues nos Webhooks.
string
Tipo namespaced recurso.ação (ex.: commission.paid, conversion.created). Veja o catálogo de eventos.
integer
Versão do schema do payload daquele tipo. Hoje todos os tipos estão em version: 1.
string
Tipo do agregado a que o evento se refere (ex.: commission, payout, conversion, invoice).
string
ID do agregado (ex.: comm_..., pay_...). Combinado com aggregateType, é o eixo natural de auditoria de um recurso.
object
Snapshot do fato: um diff (before/after), a entidade completa ou campos específicos, conforme o tipo. Dinheiro sempre em centavos (inteiro); percentuais em basis points.
object
{ actor: { type, id }, source? }. actor.type é um de user, api_key ou system: quem causou o fato.
string
Instante em que o fato ocorreu, em ISO-8601 (definível pelo emissor).
string
Instante em que o evento foi gravado no store, em ISO-8601.

As regras do event store

O log só recebe novos eventos: um evento, uma vez gravado, nunca é alterado nem apagado. Não existe caminho na API que reescreva o log. Isso é o que torna a trilha de auditoria confiável: nada é editado retroativamente.
Todo evento carrega type namespaced, version de schema do payload, aggregateType + aggregateId, payload, metadata e occurredAt/recordedAt. O catálogo de tipos é estável e é a fonte do GET /events/types e da validação de assinaturas de Webhook. Quando o shape de um payload precisar mudar de forma incompatível, o version daquele tipo é incrementado: consumidores leem version para saber como interpretar o payload.
Toda mudança de estado e o(s) evento(s) correspondente(s) são gravados de forma atômica: ou os dois entram, ou nenhum entra. Não existe estado sem evento, nem evento sem o estado que ele descreve, exceto a reconciliação, que grava eventos que são o próprio fato (uma divergência ou um resumo).
O log é exposto via GET /events, escopado pela sua organização, com filtros por tipo, agregado, ator e período, e paginação por cursor em ordem decrescente (mais recente primeiro). É a porta de acesso programático ao histórico, combinada com Webhooks para entrega push.
Gravar estado e evento de forma atômica garante que o log nunca diverge do estado por uma falha durante a escrita. A reconciliação (mais abaixo) cobre o caso residual: divergências em que estado e evento ficam inconsistentes entre si.

Consultando o log

O event store é exposto por três endpoints, todos autenticados e escopados pela sua organização (veja Autenticação). Para a referência completa de cada um, veja a aba Referência da API.

Listar eventos

GET /events pagina por cursor em ordem decrescente (mais recente primeiro). Use os filtros de querystring para recortar a auditoria:
string
Um único tipo (ex.: commission.paid).
string[]
Múltiplos tipos (repetível: ?types=commission.paid&types=commission.voided).
string
Tipo do agregado (ex.: commission).
string
ID do agregado: o eixo para auditar um recurso específico (ex.: comm_...).
string
Quem causou o fato: user, api_key ou system.
string
Início do período (inclusivo).
string
Fim do período (exclusivo).
A paginação segue a convenção da plataforma (limit 1 a 100, default 25; starting_after/ending_before). Veja Paginação.

Buscar um evento

O envelope retornado pelo GET /events/{id} é exatamente o mesmo body entregue nos Webhooks. Como a entrega de Webhook é at-least-once, o consumidor deve deduplicar pelo id do evento, o mesmo id que você vê aqui.

Descobrir a taxonomia

GET /events/types retorna o catálogo estático de tipos com a version vigente de cada um. Use-o para descobrir o que pode ser auditado e para validar quais tipos você quer assinar num endpoint de Webhook.
O catálogo cobre toda a taxonomia da plataforma, não só eventos de Webhook. Os tipos espelham o ciclo de vida de cada módulo: Programas e regras, Afiliados, Links e cupons, Tracking, Conversões e fraude, Comissões, Payouts, Fiscal e Reprocessamento. A lista completa, com payloads, está no catálogo de eventos.
webhook.test é um tipo sintético: ele é entregue por uma entrega de teste de Webhook, mas nunca é gravado no event store nem aparece em GET /events/types. Por isso não pode ser assinado.

Reconstruindo decisões

Como o log preserva, em ordem, cada fato com seu ator e seu snapshot de payload, você consegue reconstruir a sequência completa de decisões sobre um recurso. Filtre por aggregate_type + aggregate_id e leia os eventos em ordem cronológica. Por exemplo, o ciclo de vida típico de uma Comissão emerge dos seus eventos: Cada transição é um evento com o actor que a causou (um processo automático system, um operador user ou uma api_key) e o snapshot do estado naquele instante. Para entender por que um valor mudou (por exemplo, após uma alteração de regra), combine o log com o Reprocessamento: o evento reprocess.commission_recalculated carrega o before/after do recálculo.

Reconciliação entre estado e eventos

Gravar estado e evento de forma atômica garante consistência contra falhas durante a escrita. Para cobrir o risco residual (uma divergência em que estado e evento ficam inconsistentes entre si), uma reconciliação periódica recalcula o estado esperado dos agregados de dinheiro a partir do log e o compara com o estado armazenado. A reconciliação cobre os agregados de dinheiro (commission, payout, conversion e invoice):
  • Comissão: compara status e amountCents.
  • Payout: compara status e amountCents (imutável após a criação).
  • Conversão: compara só status. Um refund parcial muda valores com payload próprio, então comparar valor daria falso positivo.
  • Invoice: compara só status.
Quando o estado derivado do log diverge do armazenado, é emitido um evento reconciliation.divergence_found (ator system/reconciliation) com o campo divergente (status, amountCents ou orphan), o expected e o actual, abrindo um incidente auditável. Um estado sem nenhum evento gera uma divergência orphan. Ao final, é emitido um reconciliation.completed por organização, com checked e divergenceCount.
Os eventos de reconciliação são, eles próprios, gravados no log. reconciliation.divergence_found é o incidente: monitore esse tipo (via GET /events?type=reconciliation.divergence_found ou um Webhook assinado) para ser alertado de qualquer inconsistência entre o log e o estado.

Próximos passos

Catálogo de eventos

A taxonomia completa, com cada tipo de evento e o shape do seu payload.

Webhooks: visão geral

Receba os eventos do store por push, com assinatura HMAC e retries.

Reprocessamento

Como mudanças de regra recalculam Comissões, e o que isso registra no log.

Refund e clawback

Acompanhe o ciclo de estorno e clawback pela trilha de eventos.