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:

  1. Open your integration

    Dashboard → select integration → Settings (or Integration settings) → Webhooks

  2. Add endpoint

    Click Add Webhook, enter a public HTTPS URL (localhost is not accepted in production)

  3. Select events

    Subscribe only to events you need — fewer payloads, simpler handlers

  4. 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.new

New error detected

error.spike

Error rate increased significantly

error.resolved

Error marked as resolved

performance.degradation

Performance metrics below threshold

security.vulnerability

New vulnerability detected

alert.triggered

Custom alert rule triggered

testingai.completed

TestingAI run finished

autopatch.created

Auto-Patch created a fix

integration.updated

Integration 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.