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.