Webhook
Send alerts to any HTTP endpoint using webhooks
Send Parseable alerts to any HTTP endpoint using generic webhooks for custom integrations.
Overview
Webhooks provide a flexible way to integrate Parseable with any system that accepts HTTP requests:
- Custom Applications - Send alerts to your internal tools
- Third-Party Services - Integrate with any service that has an API
- Automation Workflows - Trigger automated responses to alerts
- Data Pipelines - Forward alerts to data processing systems
Prerequisites
- HTTP endpoint that accepts POST requests
- Parseable alerts configured
- Network connectivity between Parseable and the webhook endpoint
Basic Webhook Configuration
Parseable Alert with Webhook
Configure an alert in Parseable with a webhook target:
{
"name": "High Error Rate Alert",
"dataset": "application-logs",
"alertType": "threshold",
"condition": {
"field": "level",
"operator": "equals",
"value": "error"
},
"threshold": 100,
"duration": "5m",
"webhook": {
"url": "https://your-endpoint.com/webhook",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer your-api-token"
}
}
}Webhook Payload
When an alert triggers, Parseable sends a JSON payload to your webhook endpoint:
{
"alert_name": "High Error Rate Alert",
"dataset": "application-logs",
"alert_type": "threshold",
"severity": "high",
"triggered_at": "2024-01-15T10:30:00Z",
"condition": {
"field": "level",
"operator": "equals",
"value": "error"
},
"threshold": 100,
"current_value": 150,
"duration": "5m",
"message": "Error count exceeded threshold: 150 > 100"
}Building a Webhook Receiver
Node.js Example
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
const alert = req.body;
console.log('Received alert:', alert);
// Process the alert
handleAlert(alert);
res.status(200).json({ status: 'received' });
});
function handleAlert(alert) {
// Your custom logic here
// Examples:
// - Send to a messaging queue
// - Update a database
// - Trigger an automation
// - Forward to another service
console.log(`Alert: ${alert.alert_name}`);
console.log(`Stream: ${alert.dataset}`);
console.log(`Value: ${alert.current_value} (threshold: ${alert.threshold})`);
}
app.listen(3000, () => {
console.log('Webhook receiver listening on port 3000');
});Python Example
from flask import Flask, request, jsonify
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/webhook', methods=['POST'])
def webhook():
alert = request.json
logging.info(f"Received alert: {alert}")
# Process the alert
handle_alert(alert)
return jsonify({'status': 'received'}), 200
def handle_alert(alert):
# Your custom logic here
logging.info(f"Alert: {alert.get('alert_name')}")
logging.info(f"Stream: {alert.get('dataset')}")
logging.info(f"Value: {alert.get('current_value')} (threshold: {alert.get('threshold')})")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)Go Example
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Alert struct {
AlertName string `json:"alert_name"`
Stream string `json:"dataset"`
AlertType string `json:"alert_type"`
Severity string `json:"severity"`
TriggeredAt string `json:"triggered_at"`
Threshold int `json:"threshold"`
CurrentValue int `json:"current_value"`
Message string `json:"message"`
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
var alert Alert
if err := json.NewDecoder(r.Body).Decode(&alert); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Printf("Received alert: %s", alert.AlertName)
log.Printf("Stream: %s, Value: %d (threshold: %d)",
alert.Stream, alert.CurrentValue, alert.Threshold)
// Process the alert
handleAlert(alert)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "received"})
}
func handleAlert(alert Alert) {
// Your custom logic here
fmt.Printf("Processing alert: %s\n", alert.AlertName)
}
func main() {
http.HandleFunc("/webhook", webhookHandler)
log.Println("Webhook receiver listening on port 3000")
log.Fatal(http.ListenAndServe(":3000", nil))
}Authentication
Bearer Token
{
"webhook": {
"url": "https://your-endpoint.com/webhook",
"headers": {
"Authorization": "Bearer your-api-token"
}
}
}Basic Auth
{
"webhook": {
"url": "https://your-endpoint.com/webhook",
"headers": {
"Authorization": "Basic base64-encoded-credentials"
}
}
}API Key
{
"webhook": {
"url": "https://your-endpoint.com/webhook",
"headers": {
"X-API-Key": "your-api-key"
}
}
}Common Integrations
Forward to Microsoft Teams
app.post('/webhook', async (req, res) => {
const alert = req.body;
const teamsMessage = {
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": alert.severity === 'critical' ? "FF0000" : "FFA500",
"summary": alert.alert_name,
"sections": [{
"activityTitle": `🚨 ${alert.alert_name}`,
"facts": [
{ "name": "Stream", "value": alert.dataset },
{ "name": "Severity", "value": alert.severity },
{ "name": "Value", "value": `${alert.current_value} (threshold: ${alert.threshold})` }
],
"markdown": true
}]
};
await axios.post(process.env.TEAMS_WEBHOOK_URL, teamsMessage);
res.status(200).json({ status: 'sent' });
});Forward to Discord
app.post('/webhook', async (req, res) => {
const alert = req.body;
const discordMessage = {
embeds: [{
title: `🚨 ${alert.alert_name}`,
color: alert.severity === 'critical' ? 0xFF0000 : 0xFFA500,
fields: [
{ name: "Stream", value: alert.dataset, inline: true },
{ name: "Severity", value: alert.severity, inline: true },
{ name: "Value", value: `${alert.current_value}`, inline: true }
],
timestamp: alert.triggered_at
}]
};
await axios.post(process.env.DISCORD_WEBHOOK_URL, discordMessage);
res.status(200).json({ status: 'sent' });
});Trigger AWS Lambda
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
app.post('/webhook', async (req, res) => {
const alert = req.body;
await lambda.invoke({
FunctionName: 'alert-handler',
InvocationType: 'Event',
Payload: JSON.stringify(alert)
}).promise();
res.status(200).json({ status: 'triggered' });
});Best Practices
- Respond Quickly - Return 200 status immediately, process async if needed
- Implement Retries - Handle transient failures gracefully
- Validate Payloads - Verify the webhook payload structure
- Use HTTPS - Always use encrypted connections
- Authenticate Requests - Verify requests are from Parseable
- Log Everything - Keep audit logs of received webhooks
- Handle Duplicates - Implement idempotency for duplicate alerts
Troubleshooting
Webhook Not Receiving
- Verify the webhook URL is accessible from Parseable
- Check firewall rules allow incoming connections
- Verify the endpoint returns 2xx status codes
- Check Parseable logs for webhook errors
Authentication Failures
- Verify credentials are correct
- Check header names are properly formatted
- Ensure tokens haven't expired
Timeout Issues
- Increase timeout settings if processing takes time
- Process alerts asynchronously
- Return 202 Accepted for long-running operations
Next Steps
- Set up Parseable alerts for automated notifications
- Configure Slack for team notifications
- Configure PagerDuty for incident management
Was this page helpful?