Webhooks

Gateway-independent webhook dispatcher featuring secure HMAC signatures and automatic exponential retry queues.

Asynchronous outbound webhook execution subsystem verifying payload integrity via HMAC-SHA256 headers with configurable backoff policies.

Webhook Dispatch Engine

The webhook dispatch engine processes domain events asynchronously. It acts as an outbox consumer that listens for events, matches them against tenant webhook subscriptions, and queues them for delivery. The process is fully decoupled from the main HTTP request thread, ensuring that slow third-party servers do not affect platform performance.

Webhook Dispatch Flow
Domain Event Raised
WebhookDispatcher (INotificationHandler)
Lookup Active Tenant Webhooks (filtered by EventType)
HTTP POST to Endpoint URL
2xx
Success (2xx)
Failure (non-2xx or timeout)
Queue to WebhookDeliveryAttempts

Payload Structure & Format

All webhook notifications sent by SCRIPE are HTTP POST requests containing a standard JSON payload envelope. The envelope contains metadata about the event, and the payload body inside 'data' contains the serialized state of the modified resource.

Webhook Payload EnvelopeJSON
{
  "id": "evt_01HXZ8FQ2N4JMKRV9C3T6S7YBW",
  "type": "admin.created",
  "timestamp": "2026-06-28T14:30:00.000Z",
  "tenantId": "enc_a1b2c3d4e5",
  "data": {
    "id": "enc_f6g7h8i9j0",
    "email": "admin@company.com",
    "name": "Alice Johnson",
    "createdAt": "2026-06-28T14:30:00.000Z"
  }
}
Signature Verification (C# Receiving Server)C#
// Verify the X-Scripe-Signature header on your webhook receiver
public static bool VerifySignature(
    string rawBody,
    string receivedSignature,
    string secretKey)
{
    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey));
    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody));
    var computed = Convert.ToHexString(hash).ToLower();

    // Constant-time comparison — prevents timing attacks
    return CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(computed),
        Encoding.UTF8.GetBytes(receivedSignature));
}

Automatic Retry & Backoff

When an external webhook endpoint returns a non-2xx status code or times out, the dispatch engine queues it for retry. It uses an exponential backoff strategy to wait longer between subsequent attempts, preventing overwhelming the target server.

Attempt #Delay After PreviousCumulative Wait
1 (initial)0 minImmediate
25 min5 min
330 min35 min
42 h~2 h 35 min
58 h~11 h
6 (final)24 h~35 h — marks Abandoned

HMAC-SHA256 Signature Security

To prevent spoofing attacks, all webhook requests include an X-Scripe-Signature header. This header contains the HMAC-SHA256 signature of the raw JSON request body, computed using the webhook's secret key. Receivers must compute the signature of the received body and compare it using a constant-time comparison helper.

Webhook Management APIs

MethodEndpointDescription
GET/api/webhooksList all registered webhooks for the tenant
POST/api/webhooksRegister a new webhook endpoint
PUT/api/webhooks/{id}Update endpoint URL or event filter
DELETE/api/webhooks/{id}Remove a webhook registration
POST/api/webhooks/{id}/testSend a test ping to the endpoint