Verbara.Sdk.Push.Webhooks 2.7.0

dotnet add package Verbara.Sdk.Push.Webhooks --version 2.7.0
                    
NuGet\Install-Package Verbara.Sdk.Push.Webhooks -Version 2.7.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Verbara.Sdk.Push.Webhooks" Version="2.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Verbara.Sdk.Push.Webhooks" Version="2.7.0" />
                    
Directory.Packages.props
<PackageReference Include="Verbara.Sdk.Push.Webhooks" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Verbara.Sdk.Push.Webhooks --version 2.7.0
                    
#r "nuget: Verbara.Sdk.Push.Webhooks, 2.7.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Verbara.Sdk.Push.Webhooks@2.7.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Verbara.Sdk.Push.Webhooks&version=2.7.0
                    
Install as a Cake Addin
#tool nuget:?package=Verbara.Sdk.Push.Webhooks&version=2.7.0
                    
Install as a Cake Tool

Verbara.Sdk.Push.Webhooks

Outbound HTTP webhook delivery for Verbara.Sdk.Push. Consumes events from the in-process Push bus, matches them against WebhookSubscription topic patterns, and POSTs to configured URLs with HMAC-SHA256 signing and exponential retry/backoff.

Usage

using Verbara.Sdk.Push.Topics;
using Verbara.Sdk.Push.Webhooks;

builder.Services.AddVerbaraPush()
                .AddVerbaraPushWebhooks(opts =>
                {
                    opts.MaxRetries = 5;
                    opts.InitialDelay = TimeSpan.FromSeconds(1);
                    opts.MaxDelay = TimeSpan.FromSeconds(60);
                    opts.TimeoutPerAttempt = TimeSpan.FromSeconds(10);
                });

// Runtime registration:
var store = app.Services.GetRequiredService<IWebhookSubscriptionStore>();
await store.AddAsync(new WebhookSubscription
{
    Id = "crm-prod",
    TopicPattern = TopicPattern.Parse("calls.**"),
    TargetUrl = new("https://crm.example.com/hooks/calls"),
    Secret = "<shared secret>"
});

Accepted option values

WebhookDeliveryOptions is checked when the options are first resolved (at the latest when the host builds the WebhookDeliveryService hosted service at start) and again by both WebhookDeliveryService constructors. A value delivery could never use stops the host from starting instead of losing deliveries later:

Option Accepted Default
MaxRetries 0 or more 5
InitialDelay TimeSpan.Zero to int.MaxValue ms (about 24.8 days) 1 s
MaxDelay InitialDelay to int.MaxValue ms 60 s
TimeoutPerAttempt greater than zero and at most int.MaxValue ms, or Timeout.InfiniteTimeSpan 10 s

Through AddVerbaraPushWebhooks a rejected value fails with an OptionsValidationException that lists every offending option, for example MaxDelay: MaxDelay = 00:00:00.5000000 cannot be used by webhook delivery: it must be at least InitialDelay. A service constructed directly throws ArgumentOutOfRangeException whose ParamName is the first offending option (in the order MaxRetries, InitialDelay, MaxDelay, TimeoutPerAttempt).

The service reads the options object it was built with, so a value changed on that object after start is not re-validated. If such a change makes a retry delay unusable, the delivery that needed it is dead-lettered (deliveries.dead_letter) with one Error entry (EventId 8) naming the subscription, the event type and the exception; other deliveries and later events are unaffected.

Delivery headers

Header Value
Content-Type application/json
X-Signature sha256=<hex> (absent if subscription has no secret)
X-Event-Type PushEvent.EventType
User-Agent WebhookDeliveryOptions.UserAgent (default Verbara.Sdk.Push.Webhooks/1.0)
traceparent PushEventMetadata.TraceContext (absent if null)

Extra per-subscription headers are appended from WebhookSubscription.Headers.

Extension points

  • Custom payload shape: implement IWebhookPayloadSerializer and register as singleton before AddVerbaraPushWebhooks.
  • Custom signature: implement IWebhookSigner (e.g., JWT, asymmetric signatures) and register as singleton.
  • Durable subscriptions: implement IWebhookSubscriptionStore (SQL/Redis/Postgres) and register as singleton. The default InMemoryWebhookSubscriptionStore is process-local.

Observability

Counters on Verbara.Sdk.Push.Webhooks meter:

  • asterisk.push.webhooks.deliveries.succeeded
  • asterisk.push.webhooks.deliveries.failed
  • asterisk.push.webhooks.deliveries.retried
  • asterisk.push.webhooks.deliveries.dead_letter
  • asterisk.push.webhooks.circuit.opened
  • asterisk.push.webhooks.circuit.skipped

deliveries.dead_letter counts deliveries that failed all MaxRetries + 1 attempts and were dropped, and deliveries that ended early because their retry delay could not be computed or waited, or because they failed outside their attempts (for example in the payload serializer). It is an operational signal, not a queue: nothing is stored and nothing can be replayed. A delivery skipped because its URL's circuit is open is dropped without an attempt and counted in circuit.skipped, not dead_letter. Retries still in flight when the host stops are lost without being counted, and every counter starts again from zero in the new process.

Failures logged at Error (category Verbara.Sdk.Push.Webhooks.WebhookDeliveryService):

EventId When
1 the bus observer received an error
2 the subscription store could not be enumerated
5 a delivery exhausted its retries (dead-lettered)
8 a delivery's retry delay could not be computed or waited (dead-lettered)
9 an event could not be dispatched, for example because its TopicPath does not parse; later events are unaffected
10 a delivery failed outside its attempts, for example in the payload serializer (dead-lettered)

Neither the dispatch nor a delivery can leave a faulted task behind: every failure ends in one of these entries.

Enroll via Verbara.Sdk.OpenTelemetry — WithAllSources() includes this meter automatically; it is already registered in VerbaraTelemetry.MeterNames.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.7.0 0 10/3/2026
2.6.1 415 9/30/2026
2.6.0 696 9/24/2026
2.5.3 590 9/13/2026
2.5.2 246 9/13/2026
2.5.1 238 9/12/2026
2.5.0 117 8/25/2026
2.4.0 666 7/27/2026
2.3.2 213 7/20/2026
2.3.1 193 7/14/2026
2.3.0 177 7/6/2026
2.2.1 236 5/23/2026
2.2.0 132 5/20/2026
2.1.2 115 5/8/2026
2.1.1 119 5/7/2026
2.1.0 109 5/7/2026
2.0.0 117 5/6/2026