Configure Event Notification Webhooks (Beta)
Event Notifications is in Beta. Features and functionality are subject to change as we continue to iterate this functionality towards General Availability.
This topic describes how to configure and use webhooks for Event Notifications, including webhook payload structure, HMAC signature verification, and integration with services like Slack.
Overview
Webhooks allow you to receive Event Notifications as HTTP POST requests to an endpoint you control. This enables integration with services like Slack, PagerDuty, custom monitoring systems, and other tools that support webhook integrations.
Event Notifications webhooks include:
- JSON payload with event data
- HMAC-SHA256 signature for verification
- Automatic retries with exponential backoff
- Delivery attempt tracking
Configuring Webhook URLs
To configure a webhook for Event Notifications:
-
Prepare your webhook endpoint:
- Ensure your endpoint can receive HTTP POST requests
- Endpoint must be publicly accessible (or use a secure tunnel for testing)
- Endpoint should respond with a 2xx status code (200-299) for successful delivery
- Response time should be under 5 seconds
-
Create a notification subscription with webhook delivery:
- Navigate to Notifications > Create Notification
- Select your event type and configure filters
- Choose Webhook as the delivery method
- Enter your webhook URL
- (Optional but recommended) Enter a signing secret for HMAC verification
-
Test your webhook:
- Trigger a test event to verify webhook delivery
- Check your endpoint logs for incoming requests
- Verify the payload structure matches your expectations
See Create Event Notification Subscriptions (Beta) for detailed instructions on creating subscriptions.
Webhook Payload Structure
Event Notifications webhooks deliver a JSON payload with the following structure:
{
"event": "customer.created",
"timestamp": "2026-01-25T22:48:32Z",
"text": "A new customer has been created.\n\nCustomer: Testy McTestface\nCustomer ID: 38ljzNKNZZSIp3bUQYSPzJUUBpd\nApplication: Demo\nChannel: Stable\nLicense Type: trial\nExpiration: 2026-02-24\nCreated at: 2026-01-25 22:48:32 UTC\n\nView customer: https://vendor.replicated.com/apps/demo-jaybird/customer/38ljzNKNZZSIp3bUQYSPzJUUBpd",
"data": {
"app_id": "34LgWqPkIlmhPDhvQVrbWcRwvLW",
"team_id": "CKUTNRX16FghU69v_RjZ1Q1EFXBcQBMZ",
"app_name": "Demo",
"app_slug": "demo-jaybird",
"eventType": "customer.created",
"channel_id": "34LgWuB1oCNbdLV6BbeepUSAEA6",
"created_at": "2026-01-25T22:48:32.391894468Z",
"event_type": "customer.created",
"expires_at": "2026-02-24T22:47:37Z",
"customer_id": "38ljzNKNZZSIp3bUQYSPzJUUBpd",
"channel_name": "Stable",
"license_type": "trial",
"customer_name": "Testy McTestface",
"subscription_name": "Trial Customer Alerts"
}
}
The subscription_name field is included in the data object only when a custom name is set on the subscription. For email notifications, the custom name is prepended to the email subject line.
Payload Fields
| Field | Type | Description |
|---|---|---|
event | string | Event type identifier (e.g., "customer.created", "instance.upgraded") |
timestamp | string | ISO 8601 timestamp when the event occurred |
text | string | Human-readable text description of the event, formatted for easy reading |
data | object | Event-specific data containing detailed information about the event |
The data object contains fields specific to each event type. Common fields include:
app_id- Application identifierteam_id- Team identifierapp_name- Application nameapp_slug- Application slug (URL-safe identifier)event_type- Event type identifiersubscription_name- Custom subscription name, if set- Additional fields specific to the event type (customer_id, instance_id, channel_id, etc.)
Webhook Signing (HMAC-SHA256)
Event Notifications webhooks include an HMAC-SHA256 signature for verification. This allows you to verify that webhook requests are genuinely from Replicated and have not been tampered with.
How Signing Works
When you configure a webhook with a signing secret:
- Replicated generates an HMAC-SHA256 signature of the webhook payload using your secret
- The signature is sent in the
X-Replicated-SignatureHTTP header - Your endpoint can verify the signature to ensure authenticity
Signature Header Format
The X-Replicated-Signature header contains the signature in the following format:
X-Replicated-Signature: sha256=<hex-encoded-signature>
Example:
X-Replicated-Signature: sha256=5d7f8e9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e
Verifying Webhook Signatures
To verify webhook signatures in your endpoint, follow these steps:
Step 1: Extract the Signature
Extract the signature from the X-Replicated-Signature header:
const signatureHeader = req.headers['x-replicated-signature'];
const signature = signatureHeader.replace('sha256=', '');
Step 2: Compute the Expected Signature
Compute the HMAC-SHA256 signature of the raw request body using your signing secret:
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', signingSecret);
hmac.update(requestBody); // Use the raw request body string
const expectedSignature = hmac.digest('hex');
Step 3: Compare Signatures
Use a constant-time comparison to prevent timing attacks:
const crypto = require('crypto');
function verifySignature(signature, expectedSignature) {
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
if (!verifySignature(signature, expectedSignature)) {
// Signature verification failed - reject the request
return res.status(401).send('Invalid signature');
}
// Signature verified - process the webhook
Integrating with Slack
To send Event Notifications to a Slack channel using webhooks:
-
Create a Slack incoming webhook:
- Go to your Slack workspace settings
- Navigate to Apps > Incoming Webhooks
- Click Add to Slack
- Select the channel where you want to receive notifications
- Copy the webhook URL
For detailed instructions, see the Slack documentation on incoming webhooks.
-
Create an Event Notification subscription:
- Navigate to Notifications > Create Notification in the Vendor Portal
- Select your event type and configure filters
- Choose Webhook as the delivery method
- Paste your Slack webhook URL
- (Optional) Add a signing secret if you want to verify signatures
-
Test the integration:
- Trigger a test event to verify Slack notifications
- Check your Slack channel for the notification message
The text field in the webhook payload is automatically formatted for readability in Slack and other chat tools.
Delivery Retries and Timeouts
Event Notifications automatically retries failed webhook deliveries to ensure reliability.
Retry Behavior
- Initial delivery attempt: Made immediately when the event occurs
- Retry policy: Exponential backoff with up to 8 retry attempts
- Timeout: Each delivery attempt times out after 5 seconds
- Retry schedule: Approximately 1m, 2m, 4m, 8m, 16m, 32m, 64m, 128m after initial failure
Successful Delivery
A webhook delivery is considered successful when your endpoint:
- Responds with an HTTP status code in the 2xx range (200-299)
- Responds within 5 seconds
Failed Delivery
A webhook delivery is considered failed when:
- Your endpoint responds with a non-2xx status code
- The request times out (exceeds 5 seconds)
- A network error occurs (endpoint unreachable, DNS failure, etc.)
After all retry attempts are exhausted, the notification is marked as permanently failed and can be viewed in the notification history.
Debugging Webhooks
Viewing Webhook Delivery History
To debug webhook delivery issues:
- Navigate to Notifications > History
- Find the event you're investigating
- Expand the event row to see:
- Delivery status (Sent, Failed, Pending)
- Delivery attempts and timestamps
- Error messages for failed attempts
- Response status codes from your endpoint
Common Webhook Issues
Issue: Webhooks not being received
- Verify webhook URL is correct and publicly accessible
- Check firewall rules and network configuration
- Test endpoint manually with
curlor Postman - Review webhook delivery history for error messages
Issue: Signature verification failing
- Ensure you're using the raw request body (not parsed JSON)
- Verify signing secret matches what you configured in the notification
- Check that you're extracting the signature from the correct header
- Use the verification code examples above as a reference
Issue: Endpoint timing out
- Optimize endpoint response time (should be under 5 seconds)
- Process webhooks asynchronously (return 200 immediately, process in background)
- Add logging to identify slow operations
Issue: Duplicate webhooks received
- Implement idempotency using the event timestamp and event type
- Store processed event IDs to prevent duplicate processing
- Handle retries gracefully in your application logic
Testing Webhooks Locally
To test webhooks during development:
-
Use a tunnel service like ngrok to expose your local endpoint:
ngrok http 3000 -
Use the ngrok URL as your webhook URL in the notification configuration:
https://abc123.ngrok.io/webhook -
Trigger test events and watch the ngrok dashboard or your application logs
Next Steps
- Create Event Notification Subscriptions (Beta) - Create webhook subscriptions
- Manage Event Notification Subscriptions (Beta) - View webhook delivery history
- Event Notifications (Beta) - Overview and available event types