Emit a webhook event
Declare an event name, publish it from a handler, and the dispatcher fans it out to every matching subscription with signing, delivery, and retries handled for you.
Declare the event
Add a public const string to any *WebhookEvents class in your slice. It's reflection-discovered into the catalog (exactly like permissions), so it appears in the subscription editor automatically:
public static class ProjectWebhookEvents
{
public const string Archived = "project.archived";
}Publish it
From your handler:
await _eventBus.PublishAsync(ProjectWebhookEvents.Archived, new
{
project.Id,
project.Name,
archivedAt = DateTimeOffset.UtcNow,
});The dispatcher matches active subscriptions, queues a signed delivery per match (HMAC-SHA256 over the body), and a Hangfire job POSTs it off the request path with backoff retries. Tenant admins subscribe at /admin/webhooks.
Receivers verify with
X-NetForge-Signature: sha256=<hex> — recompute the HMAC over the raw bytes using the endpoint's secret and compare. See Webhooks for the full header set and the delivery log.