> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Consumir eventos

> Consuma eventos do Streaming Hub: verifique assinaturas HMAC de webhook, trate a rotação, leia os headers X-Lerian, deduplique entregas e puxe com ack por cursor.

O Streaming Hub entrega eventos de duas formas. Os sinks de **push** (`webhook`, `sqs`, `rabbitmq`, `eventbridge`) enviam cada evento correspondente para um destino seu. Um sink de **pull** mantém os eventos em um cursor do lado do servidor, que seu consumidor lê no ritmo dele. Esta página cobre o que seu consumidor deve fazer em cada caso.

## Verificar uma assinatura de webhook

***

O Streaming Hub assina cada entrega de webhook com um HMAC sobre o timestamp da requisição e o corpo exato dela. A assinatura prova que a requisição veio do Streaming Hub e que ela não foi adulterada nem repetida. Dois headers carregam a assinatura:

| Header | Valor |
| - | - |
| `X-Webhook-Signature` | A assinatura, no formato `v1,sha256=<hex>`. |
| `X-Webhook-Timestamp` | O timestamp em segundos Unix embutido na assinatura. |

A fórmula da assinatura é:

```
signature_input = "v1:" + X-Webhook-Timestamp + "." + <raw request body>
X-Webhook-Signature = "v1,sha256=" + hex( HMAC-SHA256(key = signing_secret, message = signature_input) )
```

Para verificar uma entrega:

1. **Leia o corpo cru e o timestamp**: verifique antes de fazer o parse do corpo, sobre os bytes exatos recebidos. Qualquer nova serialização muda os bytes e quebra a assinatura.
2. **Verifique o frescor**: rejeite a requisição se o `X-Webhook-Timestamp` estiver a mais de 5 minutos de agora. Essa é a janela de proteção contra repetição.
3. **Recalcule a assinatura**: monte o `signature_input` como acima com seu signing secret e codifique o HMAC-SHA256 em hexadecimal.
4. **Compare em tempo constante**: compare seu `v1,sha256=<hex>` com o `X-Webhook-Signature` recebido usando uma comparação de tempo constante (segura contra ataques de tempo). Rejeite quando não bater.
5. **Responda**: devolva `2xx` apenas depois que a assinatura e o frescor passarem.

Você recebe o signing secret quando cria a subscription, ou quando faz a última rotação dele. O Streaming Hub nunca envia o segredo em um header. O header carrega apenas a assinatura derivada. Veja [criar uma subscription de webhook](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md) para saber de onde vem o segredo.

## Tratar duas assinaturas durante a rotação

***

Quando você [faz a rotação de um signing secret](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md), o hub roda uma **sobreposição de assinatura dupla de 24 horas**. Durante a sobreposição, cada entrega carrega dois headers `X-Webhook-Signature`, um assinado com o segredo novo e outro com o segredo anterior. O hub os envia como headers repetidos, então você pode migrar para o segredo novo sem perder nenhuma entrega.

Verifique contra os dois: recalcule a assinatura esperada com cada segredo que você tem no momento e aceite a requisição se qualquer uma das assinaturas recebidas bater. Depois de fazer o deploy do segredo novo e confirmá-lo, aposente o antigo.

> [!WARNING]
>
> Leia o `X-Webhook-Signature` como uma lista de valores de header repetidos usando o acessor multivalor de headers do seu framework (ou a visão de headers crus dele). Não quebre uma única string juntada em vírgulas: o próprio valor da assinatura contém uma vírgula (`v1,sha256=…`), então uma quebra ingênua por vírgula o corrompe. Algumas pilhas HTTP juntam headers repetidos com `", "` por padrão. Use o acessor de lista para obter cada valor inteiro.

## Headers de correlação

***

Cada entrega de webhook também carrega um conjunto de headers de contexto `X-Lerian-*`:

| Header | Carrega |
| - | - |
| `X-Lerian-Event-Id` | O id estável do evento (o `ce-id` do CloudEvents). É a chave de deduplicação e continua constante entre reentregas do mesmo evento. |
| `X-Lerian-Event-Type` | O tipo do evento, como o final `<resource>.<event>` puro (por exemplo, `transaction.created`). |
| `X-Lerian-Tenant-Id` | O id do tenant dono (apenas atribuição). |
| `X-Lerian-Delivery-Id` | O id por tentativa. Ele muda a cada nova tentativa do mesmo evento. |
| `X-Lerian-Schema-Version` | A versão do schema do payload. |

> [!WARNING]
>
> A entrega de webhook não carrega header de origem do produtor. O `X-Lerian-Event-Type` é deliberadamente livre de origem, então um consumidor não consegue distinguir dois produtores que emitem a mesma chave, a menos que a subscription fixe `origin`. Crie uma subscription com origin fixo por produtor quando a identidade da origem importa.

## Deduplicar entregas

***

A entrega é **pelo menos uma vez**: o hub pode entregar o mesmo evento mais de uma vez, por novas tentativas ou por uma reentrega depois do reinício de um worker. Deduplique pelo `X-Lerian-Event-Id`. Ele é estável em toda reentrega do mesmo evento, enquanto o `X-Lerian-Delivery-Id` difere por tentativa. Trate um `X-Lerian-Event-Id` que você já processou como duplicata: confirme com um `2xx` e não processe de novo. Mantenha seu handler idempotente.

## Responder rápido

***

Devolva um `2xx` assim que tiver verificado e aceito o evento de forma durável. Depois faça o trabalho de verdade de forma assíncrona. O hub trata uma resposta com falha, ou mais lenta que o timeout de tentativa da subscription (10 segundos por padrão), como uma entrega falha. Uma entrega falha dispara a [curva de novas tentativas](https://docs.lerian.studio/pt/platform/streaming-hub/how-streaming-hub-works.md). Se o destino continuar quebrado por tempo suficiente, o hub em algum momento [desabilita automaticamente](https://docs.lerian.studio/pt/platform/streaming-hub/how-streaming-hub-works.md) a subscription.

## Puxar eventos

***

Uma subscription `pull` não recebe push. Em vez disso, seu consumidor lê uma página dos eventos dela com:

```
GET /v1/events?subscription_id=<uuid>
```

Os eventos voltam em ordem crescente de chegada, cada um com seu `seq`, seu `ceId` (para dedup), seu tipo e seu payload. A resposta inclui um `next_cursor`.

**A leitura é a confirmação (cursor como ack).** Buscar uma página avança o cursor durável da subscription até o maior `seq` devolvido. Não existe chamada de ack separada. Ler uma página a confirma. Isso é monotônico, então nunca anda para trás.

Para paginar normalmente, retome a partir do `next_cursor` do servidor e pare quando uma página curta (com menos itens que seu `limit`) devolver `null`. Dois comportamentos a ter em mente:

* **Um salto para frente com `?after=` pode abrir mão do intervalo.** Quando você passa `?after=N` maior que seu cursor atual e a leitura retorna eventos, o cursor avança além de tudo até `N`. Uma leitura posterior sem `?after=` não retorna os eventos pulados. Isso apenas pode acontecer com um salto para frente feito à mão, nunca pela paginação normal com `next_cursor`.
* **Um salto para trás com `?after=` nunca rebobina.** Um `?after=` antigo ou menor que lê uma página mais velha não move o cursor para trás, porque o cursor apenas avança.

A leitura de pull tem rate limit por tenant. Uma leitura negada devolve `429` com o código `rate_limited`: espere os segundos de `Retry-After` e tente de novo. Um `503` significa que o hub não pode atender a leitura agora, e o `code` dele nomeia a causa (veja a [lista de erros](https://docs.lerian.studio/pt/reference/platform/streaming-hub/streaming-hub-error-list.md)). Espere os segundos de `Retry-After` e tente de novo. Deduplique os eventos puxados pelo `ceId`, assim como um consumidor de webhook deduplica pelo `X-Lerian-Event-Id`.

## Próximos passos

***

> [card] [Gerenciar subscriptions](https://docs.lerian.studio/pt/platform/streaming-hub/managing-subscriptions.md)
>
> Crie subscriptions, faça a rotação de segredos e recupere destinos desabilitados.

> [card] [Operar o Streaming Hub](https://docs.lerian.studio/pt/platform/streaming-hub/operating-streaming-hub.md)
>
> Leia os endpoints de saúde do hub.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.