Skip to main content

Webhooks API Reference

See Webhook Alerts → for setup instructions. This page covers the full technical reference.

Event Types

EventTrigger
incident.createdMonitor failure threshold exceeded
incident.acknowledgedTeam member acknowledges an incident
incident.resolvedMonitor recovery threshold exceeded
monitor.pausedMonitor manually paused
monitor.resumedMonitor manually resumed
ssl.expiry_warningSSL cert expiry within warning threshold
ssl.expiry_criticalSSL cert expiry within critical threshold

Full Payload Schema

interface PingSLAWebhookPayload {
event: string;
timestamp: string; // ISO 8601 UTC
webhookId: string; // Delivery ID for idempotency
incident?: {
id: string; // e.g. "inc_abc123"
url: string; // Dashboard link
status: 'open' | 'acknowledged' | 'resolved';
createdAt: string;
acknowledgedAt?: string;
resolvedAt?: string;
durationSeconds?: number;
};
monitor: {
id: string; // e.g. "mon_xyz456"
name: string;
type: 'http' | 'ping' | 'keyword' | 'ssl';
url?: string; // For HTTP/keyword monitors
hostname?: string; // For ping/ssl monitors
};
failure?: {
reason: string; // Human-readable failure description
statusCode?: number; // For HTTP monitors
responseTime?: number; // ms, null if timed out
region: string; // Probe region that triggered
keyword?: string; // For keyword monitors
};
ssl?: {
expiresAt: string;
daysRemaining: number;
issuer: string;
};
workspace: {
id: string;
name: string;
};
}

Signature Verification

POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
X-PingSLA-Signature: sha256=<hmac_hex>
X-PingSLA-Timestamp: <unix_timestamp>
X-PingSLA-Event: incident.created
X-PingSLA-Webhook-ID: whd_xxxxxxxxx

Verification algorithm (Node.js):

import crypto from 'crypto';

export function verifyWebhook(rawBody, headers, secret) {
const timestamp = headers['x-pingsla-timestamp'];
const signature = headers['x-pingsla-signature'];

// Reject requests older than 5 minutes (replay attack prevention)
const age = Math.abs(Date.now() / 1000 - parseInt(timestamp, 10));
if (age > 300) throw new Error('Webhook timestamp too old');

const payload = `${timestamp}.${rawBody}`;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
throw new Error('Invalid webhook signature');
}
}

// Express example
app.post('/webhooks/pingsla', express.raw({ type: 'application/json' }), (req, res) => {
try {
verifyWebhook(req.body, req.headers, process.env.PINGSLA_WEBHOOK_SECRET);
const event = JSON.parse(req.body);
// Handle event
res.sendStatus(200);
} catch (err) {
res.status(400).json({ error: err.message });
}
});

Verification algorithm (Python):

import hmac, hashlib, time

def verify_webhook(raw_body: bytes, headers: dict, secret: str) -> None:
timestamp = headers.get('x-pingsla-timestamp', '')
signature = headers.get('x-pingsla-signature', '')

age = abs(time.time() - float(timestamp))
if age > 300:
raise ValueError('Webhook timestamp too old')

payload = f"{timestamp}.{raw_body.decode('utf-8')}"
expected = 'sha256=' + hmac.new(
secret.encode(), payload.encode(), hashlib.sha256
).hexdigest()

if not hmac.compare_digest(expected, signature):
raise ValueError('Invalid webhook signature')

Idempotency

The webhookId field in every payload is a unique delivery ID. Use it to deduplicate retries on your side:

const seenWebhooks = new Set();

function handleWebhook(payload) {
if (seenWebhooks.has(payload.webhookId)) return; // duplicate
seenWebhooks.add(payload.webhookId);
// process ...
}

Response Requirements

Your endpoint must:

  • Return HTTP 2xx within 10 seconds
  • Return 2xx even if you plan to process the event asynchronously
  • Not return 3xx redirects (PingSLA does not follow redirects for webhooks)

Non-2xx responses trigger the retry schedule.

Testing Webhooks

Use webhook.site or requestbin.com to inspect webhook payloads during development.

From the PingSLA dashboard: Settings → Notification Channels → [your webhook] → Test sends a incident.created test payload.