Configure and Use Webhooks (Alpha)
Event Notifications is in Alpha. Features and functionality are subject to change.
This topic describes how to configure and use webhooks for Event Notifications.
Webhooks allow you to receive 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.
About Adding Custom HTTP Headers
You can add custom HTTP headers to webhook subscriptions to authenticate with your receiving endpoint. This is useful when your endpoint requires an API key, bearer token, or other credentials in the request headers.
Header values are encrypted at rest and masked in the UI after you save the subscription. To update a saved header value, you must re-enter it. Custom headers are included in both real webhook deliveries and test webhook requests.
Custom headers have the following limitations:
- Maximum of five headers per subscription
- Header values can be up to 2048 characters
- Duplicate header names are not allowed
- Certain reserved headers (such as
Content-TypeandHost) cannot be overridden
About the Webhook Payload Format
When you create or edit a webhook notification and select event types, you can click the View example button to open the payload preview modal and see the exact JSON structure your endpoint receives. This is useful when building your endpoint's request parser.
The preview shows:
- The top-level payload envelope (
event,timestamp,data,text) - All event-specific fields in the
dataobject, with type annotations (string, number, boolean, ISO-8601-timestamp, array, or object)
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
The following describes the fields in the webhook payload:
| 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 readability in Slack and other chat tools |
data | object | Event-specific data containing detailed information about the event. The
|
Verify Webhook Signatures
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.
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-Signature HTTP header. The X-Replicated-Signature header contains the signature in the following format: X-Replicated-Signature: sha256=<hex-encoded-signature>. For example:
X-Replicated-Signature: sha256=5d7f8e9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e.
To verify webhook signatures in your endpoint:
-
Extract the signature from the
X-Replicated-Signatureheader:const signatureHeader = req.headers['x-replicated-signature'];
const signature = signatureHeader.replace('sha256=', ''); -
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'); -
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
Integrate with Slack Using Webhooks
For more information about configuring incoming webhooks with Slack, see the Sending messages using incoming webhooks in the Slack documentation.
To send notifications to a Slack channel using webhooks:
- Go to your Slack workspace settings.
- Go to Apps > Incoming Webhooks and click Add to Slack.
- Select the channel where you want to receive notifications.
- Copy the webhook URL.
- Create an Event Notification subscription in the Vendor Portal using your Slack webhook URL. See Create an Event Notification.
- Trigger a test event to verify that the webhook is configured properly.
Test Webhooks Locally
You can test a webhook locally using a development endpoint that is either publicly accessible, or reachable through a secure tunnel.
Note the following:
- If you configured a signing secret, the test payload is signed with HMAC-SHA256 using the same
X-Replicated-Signatureheader as real deliveries - If you configured custom HTTP headers, they are included in the test request so you can verify your endpoint's authentication logic
- Private and internal IP addresses (localhost, RFC 1918 ranges, link-local, cloud metadata endpoints) are blocked for security
You can also test webhooks from the Vendor Portal when you create a webhook notification subscription. For more information, see Create an Event Notification.
To test webhooks against a local development endpoint:
-
Use a tunnel service like ngrok to expose your local endpoint:
ngrok http 3000 -
Enter the ngrok URL as your webhook URL in the notification form:
https://abc123.ngrok.io/webhook -
Click Send test webhook to send a sample payload to your local endpoint through the tunnel.
-
Check the ngrok dashboard or your application logs to verify the request was received and processed correctly.
About Delivery Retries and Timeouts for Webhooks
The Vendor Portal automatically retries failed webhook deliveries to ensure reliability. When a webhook delivery attempt fails, the Vendor Portal makes up to eight retry attempts. Each delivery attempt times out after five seconds. The retry schedule is approximately 1m, 2m, 4m, 8m, 16m, 32m, 64m, 128m after the first failed attempt.
A webhook delivery is considered failed when:
- The 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 eight retry attempts, the Vendor Portal marks the notification as permanently failed. The Vendor Portal also sends an email to both the subscription creator and team Admins with details about the failure, including the event type, the last error message, and a link to the delivery history in the Vendor Portal.
If a webhook subscription has 10 consecutive permanent failures, the Vendor Portal automatically disables it. To resume deliveries, verify that your endpoint is reachable and then re-enable the subscription from the Notifications page.