Skip to content

Webhooks Endpoints — Admin API

Granit.Webhooks.Endpoints exposes a Minimal API for managing webhook subscriptions: create and update subscriptions, transition through lifecycle states (active, suspended, deactivated), rotate signing secrets, send test pings, and monitor delivery statistics. Read endpoints require the Webhooks.Subscriptions.Read permission; mutating operations (write, lifecycle, operations) additionally require Webhooks.Subscriptions.Manage.

  • DirectoryGranit.Webhooks.Endpoints/ Minimal API route groups + DTOs + validators
    • Granit.Webhooks Core abstractions (IWebhookSubscriptionReader/Writer)
    • Granit.Webhooks.EntityFrameworkCore EF Core persistence + IWebhookQueryableProvider
// In your application startup
app.MapGranitWebhooks();
// With custom options:
app.MapGranitWebhooks(opts =>
{
opts.RoutePrefix = "admin/webhooks";
opts.TagName = "Webhook Administration";
});
OptionDefaultDescription
RoutePrefix"webhooks"Route prefix for all webhook endpoints
TagName"Webhooks"OpenAPI tag name for endpoint grouping
MethodRouteDescription
GET/event-typesList all registered webhook event types

Returns the full list of event types declared by application modules via IWebhookEventTypeDefinitionProvider. Each entry includes the event type name, localized display name, description, and category for UI grouping. Labels are resolved based on the Accept-Language header. Requires Webhooks.Subscriptions.Read permission.

MethodRouteDescription
GET/subscriptions/{id}Get a webhook subscription by ID
MethodRouteDescription
POST/subscriptionsCreate a new subscription (returns signing secret once)
PUT/subscriptions/{id}Update a subscription’s target URL
DELETE/subscriptions/{id}Hard-delete a subscription

Lifecycle — Webhooks.Subscriptions.Manage

Section titled “Lifecycle — Webhooks.Subscriptions.Manage”
MethodRouteDescription
POST/subscriptions/{id}/activateReactivate a suspended subscription
POST/subscriptions/{id}/suspendSuspend an active subscription
POST/subscriptions/{id}/deactivatePermanently deactivate a subscription
stateDiagram-v2
    [*] --> Active: Create
    Active --> Suspended: Suspend
    Suspended --> Active: Activate
    Active --> Deactivated: Deactivate
    Suspended --> Deactivated: Deactivate

Operations — Webhooks.Subscriptions.Manage

Section titled “Operations — Webhooks.Subscriptions.Manage”
MethodRouteDescription
POST/subscriptions/{id}/rotate-secretRotate the HMAC signing secret (legacy single-secret model)
POST/subscriptions/{id}/test-pingSend a Stripe-style test ping to the target URL
GET/statsGet aggregate delivery statistics (last 24h)
GET/subscriptions/{id}/keysList signing keys (Active / Retired / Revoked). Read-permission. See Signing keys
POST/subscriptions/{id}/keysRotate via the dual-key model — overlap, grace period, audit history
DELETE/subscriptions/{id}/keys/{keyId}Revoke a specific signing key

Mapped separately via MapGranitWebhooksRedelivery():

MethodRouteDescription
POST/deliveries/{deliveryId}/retryRetry a previously failed delivery attempt

Returns 202 Accepted on success, 404 if not found, 409 if not retryable.

When Granit.Webhooks.EntityFrameworkCore is registered, query endpoints are available:

MethodRouteDescription
POST/subscriptions/queryFilter, sort, and paginate subscriptions
POST/deliveries/queryFilter, sort, and paginate delivery attempts
DTODirectionUsed by
WebhookEventTypeResponseOutputGET event-types
WebhookSubscriptionCreateRequestInputPOST subscriptions
WebhookSubscriptionCreatedResponseOutputPOST subscriptions (includes signing secret)
WebhookSubscriptionUpdateRequestInputPUT subscriptions
WebhookSubscriptionDeactivateRequestInputPOST deactivate
WebhookSubscriptionResponseOutputGET, PUT, lifecycle endpoints
WebhookSubscriptionRotateSecretResponseOutputPOST rotate-secret
WebhookSubscriptionTestPingResponseOutputPOST test-ping
WebhookSubscriptionStatsResponseOutputGET stats

The route group applies Webhooks.Subscriptions.Read at the group level. Mutating sub-groups (Write, Lifecycle, Operations) additionally require Webhooks.Subscriptions.Manage. Both permissions are declared by WebhooksPermissionDefinitionProvider and auto-discovered by GranitAuthorizationModule.

PermissionApplies toDescription
Webhooks.Subscriptions.ReadDiscovery, Read, Query, StatsView subscriptions, list event types, query delivery history
Webhooks.Subscriptions.ManageWrite, Lifecycle, OperationsCreate, update, delete, activate, suspend, deactivate, rotate secrets, test ping

All request DTOs are automatically validated via FluentValidation through MapGranitGroup(). Key rules:

  • Target URL: HTTPS only, absolute URI, max 2048 chars
  • SSRF protection (registration): blocks private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 100.64.0.0/10), localhost, link-local IPv6, and blocked TLDs (.local, .internal, .onion)
  • SSRF protection (delivery): SocketsHttpHandler.ConnectCallback validates resolved IPs at connection time, preventing DNS rebinding attacks
  • Event type: non-empty, max 200 chars, must exist in the event type registry
  • Deactivation reason: non-empty, max 1000 chars
  • Webhooks — core module documentation (publisher, delivery engine, retry)
  • Signing keys (dual-key rotation)GET / POST / DELETE /webhooks/subscriptions/{id}/keys, status flow, grace period, verification fallback