HookSniff C# SDK

June 3, 2026 · View on GitHub

NuGet License HookSniff

Official C# SDK for HookSniff — reliable webhook delivery for developers.

Installation

dotnet add package HookSniff

Package Reference

<PackageReference Include="HookSniff" Version="1.2.0" />

Quick Start

using HookSniff;

// Initialize client
var client = new HookSniffClient(
    "hs_xxx_your_api_key",
    new HookSniffOptions("https://hooksniff-api-e6ztf3x2ma-ew.a.run.app")
);

// List endpoints
var endpoints = await client.Endpoint.ListAsync("app_xxx");
Console.WriteLine($"Endpoints: {endpoints.Count}");

// Create an endpoint
var newEndpoint = await client.Endpoint.CreateAsync("app_xxx", new EndpointIn
{
    Url = "https://your-app.com/webhook"
});
Console.WriteLine($"Created: {newEndpoint.Id}");

// Send a webhook message
var message = await client.Message.CreateAsync("app_xxx", new MessageIn
{
    EventType = "order.created",
    Payload = new Dictionary<string, object>
    {
        { "order_id", "12345" },
        { "total", 99.99 }
    }
});
Console.WriteLine($"Message sent: {message.Id}");

Authentication

Use your API key (starts with hs_) or a JWT token from the login endpoint.

// With API key
var client = new HookSniffClient("hs_xxx");

// With custom base URL
var client = new HookSniffClient(
    "hs_xxx",
    new HookSniffOptions("https://hooksniff-api-e6ztf3x2ma-ew.a.run.app")
);

// With custom retry schedule (max 5 retries)
var client = new HookSniffClient(
    "hs_xxx",
    new HookSniffOptions(retryScheduleMilliseconds: new List<int> { 50, 100, 200, 500, 1000 })
);

Webhook Verification

Verify incoming webhook signatures using HMAC-SHA256 (Standard Webhooks compliant).

using HookSniff;
using HookSniff.Exceptions;

var webhook = new Webhook("whsec_your_signing_secret");

try
{
    // With a Func<string?, string?> headers provider
    webhook.Verify(payload, headerName => request.Headers[headerName]);
    Console.WriteLine("✅ Signature valid!");
}
catch (WebhookVerificationException ex)
{
    Console.WriteLine($"❌ Invalid signature: {ex.Message}");
}

HookSniff Branded Headers

The SDK supports both branded and unbranded headers:

// HookSniff branded
webhook.Verify(payload, key => headers.TryGetValue(key ?? "", out var val) ? val : null);
// Looks for: hooksniff-id, hooksniff-timestamp, hooksniff-signature

// Standard Webhooks (unbranded)
// Looks for: webhook-id, webhook-timestamp, webhook-signature

Signing Webhooks

var signature = webhook.Sign(
    msgId: "msg_xxx",
    timestamp: DateTimeOffset.UtcNow,
    payload: jsonString
);
// Returns: "v1,<base64-signature>"

Resources

Core

ResourceAsync MethodsSync MethodsDescription
EndpointListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync, PatchAsync, GetSecretAsync, RotateSecretAsync, GetHeadersAsync, UpdateHeadersAsync, PatchHeadersAsync, GetStatsAsyncList, Create, Get, Update, Delete, Patch, GetSecret, RotateSecret, GetHeaders, UpdateHeaders, PatchHeaders, GetStatsManage webhook endpoints
MessageListAsync, CreateAsync, GetAsync, ExpungeContentAsyncList, Create, Get, ExpungeContentSend and manage webhook messages
MessageAttemptListByEndpointAsync, ListByMsgAsync, GetAsync, ExpungeContentAsync, ResendAsyncListByEndpoint, ListByMsg, Get, ExpungeContent, ResendTrack delivery attempts
EventTypeListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync, PatchAsync, ImportOpenapiAsyncList, Create, Get, Update, Delete, Patch, ImportOpenapiManage event types
AuthenticationLogoutAsyncLogoutAuth operations
StatisticsAggregateAppStatsAsyncAggregateAppStatsUsage statistics
HealthGetAsyncGetAPI health check

Faz 8-15 — New Features

ResourceAsync MethodsDescription
EnvironmentListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, ListVariablesAsync, CreateVariableAsync, UpdateVariableAsync, DeleteVariableAsyncManage environments (dev/staging/prod)
BackgroundTaskListAsync, GetAsync, CancelAsyncManage async background tasks
OperationalWebhookListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, ListDeliveriesAsyncOperational webhook endpoints
MessagePollerPollAsync, SeekAsync, CommitAsyncLong-polling consumer API
InboundListConfigsAsync, CreateConfigAsync, HandleInboundAsyncInbound webhook proxy
ConnectorListAsync, GetAsync, ListConfigsAsync, CreateConfigAsync, UpdateConfigAsync, DeleteConfigAsyncThird-party connectors
IntegrationsListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, TestAsync, ListEventsAsync, GetStatsAsyncIntegration management
StreamListChannelsAsync, GetChannelAsync, CreateChannelAsync, UpdateChannelAsync, DeleteChannelAsync, ListMessagesAsync, ListSubscriptionsAsync, DisconnectSubscriptionAsync, PublishEventAsyncReal-time streaming

Additional Resources

ResourceDescription
ApplicationApplication management
ApiKeyAPI key CRUD, rotate
SearchFull-text delivery search
AlertAlert rule CRUD, test
AnalyticsDelivery trends, success rate, latency
BillingSubscription, usage, invoices, portal
PortalProfile, plan, notifications
TeamTeams, invites, members, roles
NotificationList, read, unread count
SsoSSO config management
AuditLogAudit entry listing
CustomDomainDomain management, verification
RateLimitPer-endpoint rate limits
RoutingRouting rules, endpoint health
TemplateTemplate listing, apply
SchemaSchema registry, validation
PlaygroundTest webhooks
ServiceTokenService token management

Error Handling

The SDK throws ApiException for HTTP errors with status code and response body:

using HookSniff;

try
{
    var endpoint = await client.Endpoint.GetAsync("app_xxx", "ep_xxx");
}
catch (ApiException ex)
{
    Console.WriteLine($"Status: {ex.ErrorCode}");     // e.g., 404
    Console.WriteLine($"Body: {ex.ErrorContent}");     // JSON error response
    Console.WriteLine($"Message: {ex.Message}");       // Error description
}

Common Status Codes

CodeMeaning
400Bad Request — check your input
401Unauthorized — invalid or missing token
403Forbidden — insufficient permissions
404Not Found — resource doesn't exist
409Conflict — duplicate resource
422Validation Error — invalid parameters
429Rate Limited — auto-retry with backoff
500Server Error — retry later

Rate Limiting

The SDK automatically handles 429 rate limit responses:

  • Reads the Retry-After header
  • Waits the specified duration
  • Retries the request automatically

For 5xx server errors, the SDK retries with exponential backoff using the configured retry schedule.

Requirements

  • .NET 8.0+
  • Newtonsoft.Json 13.0+

License

MIT — see LICENSE for details.