IntegrationsAlerting
Webhook
Send alerts to any HTTP endpoint using webhooks. Follow the setup steps and practical guidance for using Webhook in your Parseable observability workflow.
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?