Fontes
Uma fonte é uma URL que você passa a um provedor — o Stripe, o GitHub ou qualquer outro que assine os seus webhooks — para que ele possa enviar para nós. Verificamos a assinatura de cada requisição, transformamos a requisição em um evento e o entregamos aos seus endpoints exatamente como um evento que você publicou por conta própria: as mesmas inscrições, as mesmas retentativas, a mesma dead-letter queue.
Use uma fonte quando você quiser um só lugar para o tráfego de webhooks nas duas direções, ou quando quiser que vários dos seus serviços recebam os eventos de um provedor sem que cada um verifique a assinatura do Stripe por conta própria.
Como uma requisição vira entregas
- O provedor faz um POST para a URL de ingestão da fonte,
https://webhooks.nimbusnexus.net/v1/ingest/{source_id}. - Verificamos a assinatura sobre os bytes exatos recebidos, com o segredo de assinatura da fonte.
- O corpo precisa ser um objeto JSON. Lemos o tipo do evento nele (veja Tipos de evento de uma fonte).
- O evento é publicado no projeto da fonte e comparado com as inscrições dos seus endpoints, o que cria uma entrega por endpoint correspondente.
- O provedor recebe
202. Os seus endpoints recebem o evento assinado com o segredo deles, não com o do provedor.
A URL de ingestão é a única parte do Webhooks que aceita requisições sem chave de API: a assinatura do provedor é a credencial.
Provedores e as suas assinaturas
| Provedor | Header que verificamos | Bytes assinados | Janela de replay |
|---|---|---|---|
stripe | Stripe-Signature: t=…,v1=… | {t}.{body} | 5 minutos |
github | X-Hub-Signature-256: sha256=… | {body} | nenhuma (o GitHub não envia timestamp) |
generic | X-Webhook-Signature: sha256=… com X-Webhook-Timestamp | {timestamp}.{body} | 5 minutos |
Os três usam HMAC-SHA256. generic é o mesmo esquema com que assinamos as nossas próprias entregas, então o endpoint de um workspace do Webhooks pode alimentar a fonte de outro, e qualquer remetente que você controle pode assinar assim com poucas linhas.
Criar uma fonte
No console: Sources → New source (também na página Overview). Ou pela API:
curl -sX POST https://webhooks.nimbusnexus.net/v1/sources \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "stripe",
"name": "Stripe live",
"secret": "whsec_…",
"event_type_prefix": "stripe."
}'- Stripe e GitHub: cole o segredo de assinatura que o provedor mostra. Uma fonte criada sem segredo começa desativada; adicione o segredo depois com
rotate-secrete ative-a. - Generic: deixe
secretde fora e nós geramos um, retornado uma vez nesta resposta.
A resposta traz ingest_url. Cole-a nas configurações de webhook do provedor e adicione um endpoint inscrito nos tipos que você espera (prefix stripe. no exemplo acima).
Tipos de evento de uma fonte
Cada requisição precisa de um tipo de evento para que os endpoints possam se inscrever nele. Uma fonte o encontra nesta ordem:
- Onde você mandou procurar: um header da requisição ou um caminho JSON com pontos no corpo (
data.object.type). - Caso contrário, no lugar próprio do provedor: o
typedo corpo nas fontes Stripe e generic, e o headerX-GitHub-Eventnas fontes GitHub. - Se nenhum dos dois der um valor: o tipo padrão da fonte e, na falta dele,
webhook.received.
O prefixo da fonte vai na frente (stripe. + invoice.paid → stripe.invoice.paid), o que mantém separados os tipos de dois provedores em um mesmo projeto. Se a sua lista de tipos de evento mostra webhook.received, uma fonte recebeu requisições sem nenhum tipo que ela conseguisse ler: defina um tipo padrão ou um caminho JSON nessa fonte.
O próprio id de evento do provedor (o evt_… do Stripe, o id de entrega do GitHub) é a chave de idempotência, então, quando um provedor repete um evento que já aceitamos, ele recebe 202 de novo e nada é entregue duas vezes.
O que o provedor vê
| Status | Quando |
|---|---|
202 | Aceita e publicada. |
400 | O corpo não é JSON, ou não é um objeto JSON. |
401 | A assinatura não foi verificada — ausente, malformada, com o segredo errado ou fora da janela de replay. Uma única resposta para todos esses casos, de propósito. |
402 | O workspace já usou a sua franquia mensal de entregas. |
404 | A fonte não existe ou está desativada. |
409 | O id de evento do provedor já foi aceito com um corpo diferente. |
413 | A requisição passa de 512 KiB, ou o payload passa de 256 KiB. |
422 | O tipo não está registrado e a política de tipos de evento é Strict, ou o payload não passa no JSON Schema do tipo. |
429 | Requisições demais: 600 por minuto por fonte antes da verificação da assinatura e, depois, a taxa de publicação do seu plano. |
Os provedores repetem a requisição em qualquer resposta que não seja 2xx, então uma recusa não se perde do lado deles — mas, para ver por que recusamos, ative a captura na fonte e leia as Requisições capturadas.
Rotacionar um segredo
Quando o provedor trocar o segredo, envie o novo:
curl -sX POST https://webhooks.nimbusnexus.net/v1/sources/src_…/rotate-secret \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"secret": "whsec_new…"}'O segredo anterior continua valendo na verificação por 24 horas, então as requisições assinadas com qualquer um dos dois são aceitas enquanto o provedor faz a troca. Para uma fonte generic, envie um corpo vazio e nós geramos o novo segredo.
Próximos passos
- Requisições capturadas — veja as requisições brutas que uma fonte recebeu, incluindo as recusas.
- Fontes na referência da API — todas as operações de fonte, com as chamadas do SDK e da CLI.
- Tipos de evento — o catálogo de tipos e o que acontece com um tipo desconhecido.
- Entregas e retentativas — o que acontece depois que um evento é publicado.
- Visão geral de Webhooks — os objetos e como eles se encaixam.