The Webhooks module provides a production-grade webhook delivery system with subscription CRUD, HMAC-SHA256 request signing, configurable retry policies, dead letter queue, IP allowlisting, and per-subscriber rate limiting.
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/webhooks/subscriptions | POST | Create subscription |
/api/webhooks/subscriptions | GET | List subscriptions |
/api/webhooks/subscriptions/{id} | GET | Get subscription details |
/api/webhooks/subscriptions/{id} | PATCH | Update subscription |
/api/webhooks/subscriptions/{id} | DELETE | Cancel subscription |
/api/webhooks/subscriptions/{id}/rotate-secret | POST | Rotate signing secret |
/api/webhooks/subscriptions/{id}/ping | POST | Test delivery |
Architecture
WebhookSubscriptionService │ ├── IWebhookSubscriptionRepository → SqlSugarWebhookSubscriptionRepository ├── IWebhookEventTypeRegistry → InMemoryWebhookEventTypeRegistry ├── IWebhookHttpClient → DefaultWebhookHttpClient ├── IWebhookDeadLetterQueue → NullWebhookDeadLetterQueue ├── IWebhookIpAllowlistPolicy → AllowAllWebhookIpAllowlistPolicy └── IWebhookRateLimitPolicy → AllowAllWebhookRateLimitPolicy
WebhookDeliveryService │ ├── Signature generation (HMAC-SHA256) ├── Retry policy (exponential backoff) ├── Dead letter queue (failed deliveries) └── Delivery logging (WebhookDeliveryLogEntity)Webhook subscription
public class WebhookSubscriptionEntity : TenantSoftDeleteEntityBase{ public string CallbackUrl { get; set; } public string EventTypes { get; set; } // JSON array of event type patterns public string Secret { get; set; } // HMAC signing secret (hashed) public bool IsActive { get; set; } public int MaxRetries { get; set; }}Request signing
Every webhook delivery includes HMAC-SHA256 signature headers:
POST /webhook/callback HTTP/1.1Content-Type: application/jsonX-Webhook-Signature: sha256=abc123...X-Webhook-Timestamp: 2026-06-22T10:00:00ZX-Webhook-Event: ticket.createdX-Webhook-Delivery-Id: del-789X-Webhook-Subscription-Id: sub-456
{"eventId": "...", "eventType": "ticket.created", "payload": {...}}Verification (subscriber-side):
var signature = WebhookSignature.Compute(secret, payload, timestamp);var isValid = signature == request.Headers["X-Webhook-Signature"];Retry policy
Exponential backoff with configurable limits:
public class WebhookRetryPolicy{ public int MaxRetries { get; set; } = 5; public TimeSpan InitialDelay { get; set; } = TimeSpan.FromSeconds(5); public TimeSpan MaxDelay { get; set; } = TimeSpan.FromHours(1); public double BackoffMultiplier { get; set; } = 2.0;}Event type patterns
Subscriptions support wildcard patterns:
ticket.* → All ticket eventsticket.created → Only ticket creationchat.message_sent → Only new chat messages*.created → All creation eventsAvailable event types
Defined in WebhookEventTypes:
| Pattern | Source Module |
|---|---|
ticket.* | Tickets |
chat.* | Chat |
file.* | Files |
billing.* | PlatformBilling |
notification.* | Notifications |
catalog.* | Catalog |
Delivery logging
public class WebhookDeliveryLogEntity : TenantSoftDeleteEntityBase{ public Guid SubscriptionId { get; set; } public string EventType { get; set; } public int HttpStatusCode { get; set; } public string? ResponseBody { get; set; } public string? ErrorMessage { get; set; } public int AttemptNumber { get; set; } public DateTimeOffset DeliveredAt { get; set; }}See also
- Webhook signing — Security details
- Eventing — CAP event infrastructure