Webhook Integration
Send alerts to any HTTP endpoint.
Configuration
| Field | Description |
|---|---|
| Name | Descriptive name for this integration |
| URL | Your webhook endpoint URL |
| Secret Key | Shared secret for signature verification (optional) |
| Headers | Custom headers to include (optional) |
Webhook Payload
Pingward sends a POST request with JSON body:
json
{
"event": "issue.created",
"timestamp": "2024-01-24T15:30:00Z",
"issue": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"testId": "...",
"testName": "Production API Health",
"errorCategory": "Timeout",
"severity": "Critical",
"status": "Open",
"firstSeenAt": "2024-01-24T15:25:00Z",
"lastSeenAt": "2024-01-24T15:30:00Z",
"occurrenceCount": 3
},
"test": {
"id": "...",
"name": "Production API Health",
"url": "https://api.example.com/health",
"method": "GET"
},
"result": {
"statusCode": null,
"responseTimeMs": 30000,
"errorMessage": "Request timed out after 30000ms"
}
}Event Types
| Event | Description |
|---|---|
issue.created | New issue detected |
issue.updated | Issue status changed or new occurrence |
issue.resolved | Issue was resolved |
issue.acknowledged | Issue was acknowledged |
Signature Verification
If you configure a secret key, Pingward includes a signature header:
X-Pingward-Signature: sha256=abc123...Verify by computing HMAC-SHA256 of the raw body with your secret:
javascript
const crypto = require('crypto');
function verifySignature(body, signature, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === expected;
}Custom Headers
Add headers for authentication or routing:
| Header | Value |
|---|---|
| Authorization | Bearer your-token |
| X-Source | pingward |
Use Cases
PagerDuty (Generic Webhook)
URL: https://events.pagerduty.com/v2/enqueue
Headers:
Content-Type: application/jsonCustom payload transformation may be needed.
Zapier
URL: Your Zapier webhook URLZapier can then trigger thousands of other actions.
Custom Incident Management
URL: https://your-system.com/api/incidents
Headers:
Authorization: Bearer <token>Runbook Automation
URL: https://your-automation.com/webhooks/alert
Secret: <shared-secret>Response Requirements
Your endpoint should:
- Return 2xx status code on success
- Respond within 30 seconds
- Be idempotent (same alert may be sent multiple times)
Troubleshooting
Connection Errors
- Verify the URL is accessible from the internet
- Check firewall rules
- Ensure HTTPS certificate is valid
Authentication Failures
- Verify header values are correct
- Check token expiration
- Ensure proper escaping of special characters
Timeouts
- Webhook endpoints must respond within 30 seconds
- Process asynchronously if needed
- Return 202 Accepted for async processing
Best Practices
Idempotency
The same event may be delivered multiple times. Use the issue ID to deduplicate:
javascript
if (alreadyProcessed(payload.issue.id)) {
return res.status(200).send('Already processed');
}Quick Response
Respond quickly, process asynchronously:
javascript
app.post('/webhook', (req, res) => {
queue.add(req.body); // Process later
res.status(202).send('Accepted');
});Signature Verification
Always verify signatures in production to ensure requests are from Pingward.