Webhooks
Send real-time Sublyzer events to your servers: setup, payloads, signature verification, retries, and integrations.
What are webhooks?
Webhooks push events from Sublyzer to your HTTPS endpoint as soon as something happens — new errors, alert rules firing, TestingAI finishing, Auto-Patch creating a fix, and more. Use them for Slack, PagerDuty, Jira, internal dashboards, or custom automation.
Discord (all plans)
Paste a Discord incoming webhook URL in Integration → Discord. No custom server code required.
Custom HTTPS webhooks (PRO)
Your own URL with signed JSON payloads, event filters, delivery logs, and automatic retries.
Setting up custom webhooks (PRO)
Configure outbound webhooks per integration:
Open your integration
Dashboard → select integration → Settings (or Integration settings) → Webhooks
Add endpoint
Click Add Webhook, enter a public HTTPS URL (localhost is not accepted in production)
Select events
Subscribe only to events you need — fewer payloads, simpler handlers
Save secret & test
Copy the signing secret, then Test Webhook to send a sample payload
FREE plans: use built-in Discord notifications. Upgrade to PRO for custom endpoints and delivery history.
Webhook events
Subscribe to one or more event types:
error.newNew error detected
error.spikeError rate increased significantly
error.resolvedError marked as resolved
performance.degradationPerformance metrics below threshold
security.vulnerabilityNew vulnerability detected
alert.triggeredCustom alert rule triggered
testingai.completedTestingAI run finished
autopatch.createdAuto-Patch created a fix
integration.updatedIntegration settings changed
Payload format
Every delivery is POST with Content-Type: application/json:
{
"id": "wh_abc123xyz",
"event": "error.new",
"timestamp": "2024-01-15T10:30:00.000Z",
"integration": {
"id": "int_123abc",
"name": "My Website",
"code": "abc123def456ghi789jkl012"
},
"data": { }
}Example: error.new
{
"id": "wh_err_new_001",
"event": "error.new",
"timestamp": "2024-01-15T10:30:00.000Z",
"integration": {
"id": "int_123abc",
"name": "My Website",
"code": "abc123def456ghi789jkl012"
},
"data": {
"error": {
"id": "err_xyz789",
"message": "TypeError: Cannot read properties of undefined (reading 'map')",
"severity": "high",
"count": 1,
"url": "https://example.com/products",
"browser": "Chrome",
"os": "Windows 10"
}
}
}Verifying signatures
Reject forged requests by validating X-Sublyzer-Signature (HMAC-SHA256 of the raw body):
X-Sublyzer-Signature: sha256=a1b2c3d4e5f6...
Node.js example
const crypto = require('crypto');
function verifyWebhook(rawBody, signature, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
} catch {
return false;
}
}
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-sublyzer-signature'];
const raw = req.body.toString();
if (!verifyWebhook(raw, sig, process.env.SUBLYZER_WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(raw);
// queue for async processing…
res.status(200).send('OK');
});Secret location: Integration → Webhooks → Show Secret. Rotate if leaked.
Retries & delivery logs
- Retries: up to 5 — intervals ~1 min, 5 min, 30 min, 2 h, 24 h
- Success: any 2xx response
- Timeout: 30 seconds per attempt
- Auto-disable: after 5 consecutive failures
Delivery logs show each attempt: status, duration, payload snapshot, and response body — open the webhook in Integration settings → Delivery Logs.
Respond in under 5 seconds; process heavy work in a background job. Use the webhook id field for idempotency — retries may resend the same event.
Example: forward to Slack
Minimal handler that forwards error.new / error.spike to Slack:
app.post('/sublyzer-webhook', express.json(), async (req, res) => {
const { event, data, integration } = req.body;
if (event !== 'error.new' && event !== 'error.spike') {
return res.status(200).send('Ignored');
}
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `[${integration.name}] ${event}: ${data?.error?.message}`,
}),
});
res.status(200).send('OK');
});Best practices
- Always verify signatures in production
- Return 2xx quickly; process asynchronously
- Deduplicate by webhook
id - Log payloads during rollout; use Test Webhook first
- Monitor endpoint uptime — failed deliveries disable the webhook after repeated errors
Need help? Join our Discord.