Skip to main content

Webhook Alerts

Webhooks send HTTP POST requests to your endpoint when an incident is created or resolved. Use webhooks to integrate PingSLA with any custom system, ticketing platform, or on-call tool.

Adding a Webhook Channel

  1. Go to Settings → Notification Channels → New Channel
  2. Select Webhook
  3. Enter the endpoint URL (must be HTTPS)
  4. Optionally add a secret for payload verification
  5. Click Test

Webhook Payload

PingSLA sends a POST request with Content-Type: application/json.

Incident Created (DOWN)

{
"event": "incident.created",
"timestamp": "2026-05-18T14:32:00.000Z",
"incident": {
"id": "inc_abc123",
"url": "https://app.pingsla.com/incidents/inc_abc123",
"status": "open",
"createdAt": "2026-05-18T14:32:00.000Z"
},
"monitor": {
"id": "mon_xyz456",
"name": "Production API Health",
"type": "http",
"url": "https://api.yourapp.com/health"
},
"failure": {
"reason": "HTTP 503 Service Unavailable",
"statusCode": 503,
"responseTime": null,
"region": "us-east-1"
},
"workspace": {
"id": "ws_xxxxxxxxx",
"name": "Acme Corp"
}
}

Incident Resolved (RECOVERED)

{
"event": "incident.resolved",
"timestamp": "2026-05-18T14:36:22.000Z",
"incident": {
"id": "inc_abc123",
"url": "https://app.pingsla.com/incidents/inc_abc123",
"status": "resolved",
"createdAt": "2026-05-18T14:32:00.000Z",
"resolvedAt": "2026-05-18T14:36:22.000Z",
"durationSeconds": 262
},
"monitor": {
"id": "mon_xyz456",
"name": "Production API Health",
"type": "http",
"url": "https://api.yourapp.com/health"
},
"workspace": {
"id": "ws_xxxxxxxxx",
"name": "Acme Corp"
}
}

Payload Verification (HMAC-SHA256)

If you configure a webhook secret, PingSLA signs every request with HMAC-SHA256.

X-PingSLA-Signature: sha256=3d7e2c1a...
X-PingSLA-Timestamp: 1716042720

Verify in your receiver:

import crypto from 'crypto';

function verifyPingSLAWebhook(body, signature, timestamp, secret) {
const payload = `${timestamp}.${JSON.stringify(body)}`;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
warning

Always verify webhook signatures in production. Unverified webhooks can be spoofed to trigger false incident reports in your systems.

Integration Recipes

PagerDuty

PagerDuty exposes native webhook ingestion. Use the PagerDuty Events API v2 endpoint:

https://events.pagerduty.com/v2/enqueue

Map PingSLA payload fields to PagerDuty:

// Your bridge function (Lambda or Express endpoint)
app.post('/pingsla-to-pagerduty', async (req, res) => {
const { event, monitor, failure } = req.body;
const pdPayload = {
routing_key: process.env.PAGERDUTY_INTEGRATION_KEY,
event_action: event === 'incident.created' ? 'trigger' : 'resolve',
dedup_key: req.body.incident.id,
payload: {
summary: `${monitor.name} is DOWN — ${failure?.reason ?? 'recovered'}`,
source: monitor.url,
severity: 'critical',
},
};
await fetch('https://events.pagerduty.com/v2/enqueue', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(pdPayload),
});
res.sendStatus(200);
});

Slack (Custom Format)

Use a webhook to build a custom Slack message if the native Slack channel doesn't meet your formatting needs.

Custom Ticketing / JIRA

POST the webhook payload to a Lambda or Express micro-service that translates it to a JIRA issue creation call.

Retry Behavior

AttemptDelay
InitialImmediate
Retry 130 seconds
Retry 22 minutes
Retry 38 minutes

After 3 failed retries, the delivery is marked as failed. The incident timeline records all delivery attempts.

Troubleshooting

IssueResolution
Webhook receives no requestsVerify URL is HTTPS and publicly reachable
401 / 403 from receiverAdd PingSLA to IP allowlist or fix auth config
Signature mismatchEnsure you hash the raw body before JSON.parse
Test succeeds, real events don'tVerify alert policy is attached to the monitor