Whisperr 1.0.0
dotnet add package Whisperr --version 1.0.0
NuGet\Install-Package Whisperr -Version 1.0.0
<PackageReference Include="Whisperr" Version="1.0.0" />
<PackageVersion Include="Whisperr" Version="1.0.0" />
<PackageReference Include="Whisperr" />
paket add Whisperr --version 1.0.0
#r "nuget: Whisperr, 1.0.0"
#:package Whisperr@1.0.0
#addin nuget:?package=Whisperr&version=1.0.0
#tool nuget:?package=Whisperr&version=1.0.0
Whisperr .NET SDK
Server-side SDK for .NET - reliable churn-signal event tracking for ASP.NET Core, workers, serverless handlers, and any backend that knows the end-user id.
dotnet add package Whisperr
Quick Start
using Whisperr;
var whisperr = new WhisperrClient(Environment.GetEnvironmentVariable("WHISPERR_API_KEY")!);
whisperr.Track(
"user_8842",
"payment_failed",
new Dictionary<string, object?>
{
["amount_cents"] = 4900,
["reason"] = "card_declined"
});
whisperr.Identify("user_8842", new IdentifyOptions
{
Email = "ada@example.com",
Traits = new Dictionary<string, object?>
{
["plan"] = "pro"
}
});
await whisperr.ShutdownAsync();
The user id is always explicit. Pass the same external_user_id that your app
uses everywhere else, and backend events land on the same Whisperr timeline as
frontend events.
ASP.NET Core
Install the companion package for dependency-injection wiring:
dotnet add package Whisperr.AspNetCore
AddWhisperr binds the Whisperr configuration section and falls back to the
WHISPERR_API_KEY environment variable, then registers WhisperrClient as a
singleton. The host disposes the singleton on shutdown, which runs a final
flush, so you do not need to manage the lifetime yourself.
using Whisperr.AspNetCore;
builder.Services.AddWhisperr(builder.Configuration, options =>
{
options.OnError = error => Console.Error.WriteLine($"whisperr:{error.Code} {error.Message}");
});
// appsettings.json
{
"Whisperr": {
"ApiKey": "wrk_...",
"FlushInterval": "00:00:10"
}
}
Inject WhisperrClient wherever you have the user id. Track/Identify
enqueue and return immediately; let the background flush and host-shutdown flush
deliver them, rather than awaiting FlushAsync on the request path (a flush can
wait through retry backoff):
app.MapPost("/billing/webhook", (
BillingWebhook webhook,
WhisperrClient whisperr) =>
{
whisperr.Track(webhook.UserId, "payment_failed", new Dictionary<string, object?>
{
["amount_cents"] = webhook.AmountCents,
["provider"] = "stripe"
});
return Results.Ok();
});
Request-scoped tracking
For request handlers that already authenticate a user, add the middleware after
authentication and use HttpContext.Whisperr(), which binds to the user id from
the NameIdentifier/sub claim (override via UseWhisperr(resolveUser)):
using Whisperr.AspNetCore;
app.UseAuthentication();
app.UseWhisperr();
app.MapPost("/plan/upgrade", (HttpContext http) =>
{
http.Whisperr().Track("plan_upgraded", new Dictionary<string, object?> { ["plan"] = "pro" });
return Results.Ok();
});
Behavior
TrackandIdentifyenqueue in memory and return immediately.- Events flush in batches to
/v1/events/batch; identity updates flush to/v1/identify. - Requests use
X-API-Key. event_typemust be lowercasesnake_case; invalid events are dropped before they can poison a batch.- Each event gets a stable
$message_ididempotency key incontext; retries reuse the same id. 401/403retain the batch and surfaceauth.429,5xx, timeouts, and network failures retry with bounded backoff; after retries are exhausted, the batch is retained andretry_exhaustedis surfaced.- Other
4xxresponses drop the offending batch and surfacedropped.
The queue is in-process, not crash-durable. Call FlushAsync or
ShutdownAsync before short-lived processes exit.
Runtime support
- Targets:
net8.0andnetstandard2.0(the latter covers .NET Framework 4.7.2+ and other netstandard2.0 hosts). The conformance suite runs on bothnet8.0andnet472in CI. - Long-lived hosts: hold one client for the process lifetime. In ASP.NET Core the DI singleton is disposed (and flushed) on shutdown.
- Short-lived / serverless: the background timer cannot guarantee delivery
before the runtime freezes —
await client.ShutdownAsync()(orFlushAsync()) before returning so buffered events aren't lost. - Trimming / AOT: standard server apps (including trimmed deployments) are
supported. The SDK uses reflection-based
System.Text.Json, so Native AOT is not a v1 guarantee; prefer the JIT/ReadyToRun runtimes for now.
Options
| Option | Default | Notes |
|---|---|---|
ApiKey |
- | App ingestion key (wrk_...). Required unless disabled. |
BaseUrl |
https://api.whisperr.net |
Whisperr ingestion API. |
FlushAt |
20 |
Flush when this many operations are queued. |
FlushInterval |
10s |
Background flush cadence. Use TimeSpan.Zero to disable. |
MaxQueueSize |
10000 |
Oldest operations drop on overflow. |
MaxBatchSize |
500 |
Events per batch; backend cap is 500. |
MaxRetries |
6 |
Transient retries before retaining for a later flush. |
RequestTimeout |
10s |
Per-request timeout. |
Disabled |
false |
No-op client for tests and local modes. |
Debug |
false |
Emits diagnostic warnings to Logger or stderr. |
OnError |
- | Observability hook for auth, dropped, retry_exhausted. |
HttpClient |
private client | Pass your own for custom handlers or test capture. |
Development
The tests consume whisperr-spec fixtures. In this workspace the sibling
../whisperr-spec repo is picked up automatically. In CI or another checkout:
export WHISPERR_SPEC_PATH=/path/to/whisperr-spec/conformance/wire.json
dotnet test
Build and pack:
dotnet test -c Release
dotnet pack src/Whisperr/Whisperr.csproj -c Release -o artifacts
Publish to NuGet. Releases are cut by pushing a v*.*.* tag (the workflow
derives the package version from the tag), but you can also push locally:
dotnet nuget push artifacts/Whisperr.*.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key "$NUGET_API_KEY" \
--skip-duplicate
Whisperr - predict churn, automate interventions, recover revenue. whisperr.net
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Whisperr:
| Package | Downloads |
|---|---|
|
Whisperr.AspNetCore
ASP.NET Core integration for the Whisperr .NET SDK: dependency-injection registration and request-scoped event tracking. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 133 | 7/3/2026 |