Custom Webhook Integration - EasyAlert

Custom Webhook
Integrate any tool that can send HTTP webhooks
Overview
The Custom integration allows you to connect any monitoring tool, script, or application that can send HTTP POST requests. Easyalert automatically extracts common fields and captures additional data as tags.
ℹ️ Info: Use Custom integration when your monitoring tool isn't in our supported list, or when you want to send alerts from custom applications.
Setup Instructions
Step 1: Create Integration in Easyalert
- Go to Integrations page from left menu
- Click Add Integration button
- Select Custom as Source Type
- Enter a name (e.g.,
Internal Monitoring) - Click Create to save
- Copy the generated Webhook URL
Example:
https://api.easyalert.io/api/v1/webhooks/ingest/wh_abc123...
Step 2: Configure Your Source
Set up your monitoring tool or script to POST JSON to the webhook URL.
Step 3: Send a Test Event
Send a test payload and verify it appears in Easyalert.
Webhook URL
Your webhook URL:
https://api.easyalert.io/api/v1/webhooks/ingest/{token}
Request Format
| Setting | Value |
|---|---|
| Method | POST |
| Content-Type | application/json |
| Authentication | None (token in URL) |
Payload Format
Standard Fields
| Field | Default | Description |
|---|---|---|
eventId | auto-generated | Unique event identifier |
title | "Custom Alert" | Alert title |
description | "" | Detailed description |
severity | "warning" | critical, error, warning, info, ok |
status | "problem" | problem, ok |
timestamp | now | ISO 8601 or Unix timestamp |
host | - | Hostname |
hostIp | - | Host IP address |
service | - | Service name |
environment | - | Environment |
team | - | Team name |
customerName | - | Customer name (for MSP routing) |
Field Recognition
Easyalert automatically recognizes these common field names:
Title Fields
title, name, subject, summary, alert_name, message_title
Description Fields
description, message, body, text, details
Severity Fields
severity, priority, level, criticality
Status Fields
status, state, alert_status, current_state
Host Fields
host, hostname, server, node, instance, machine
IP Address Fields
hostIp, host_ip, ip, ip_address, source_ip
Service Fields
service, application, app, component
Environment Fields
environment, env
Other Fields
region, datacenter, dc, location, team, owner, customer, client, tenant
Custom Field → Tag Conversion
Any field not in the standard list is automatically captured as a tag:
{
"eventId": "evt-001",
"title": "Alert",
"project_code": "PRJ-001",
"datacenter": "EU-West",
"cost_center": "CC-1234"
}
Result:
tags.project_code = "PRJ-001"tags.datacenter = "EU-West"tags.cost_center = "CC-1234"
Nested Tags
You can also send structured tags:
{
"tags": {
"environment": "production",
"team": "platform",
"service": "api"
}
}
Severity Values
These values are automatically mapped:
| Input Value | Easyalert Severity |
|---|---|
| critical, disaster, fatal, emergency, P1 | Critical |
| error, high, major, P2 | High |
| warning, warn, medium, minor, average, P3 | Warning |
| info, information, low, notice, P4, P5 | Info |
| ok, resolved, recovery, clear, success | OK |
Values are case-insensitive.
Status Values
| Input Value | Easyalert Status |
|---|---|
| problem, alert, alerting, triggered, firing, open, active | Problem |
| ok, resolved, recovery, clear, closed, inactive | OK |
Example Payloads
Minimal Payload
{
"title": "High CPU Usage",
"severity": "critical",
"host": "web-01"
}
Full Payload
{
"eventId": "cpu-high-server01-20241203-001",
"title": "High CPU Usage on server01",
"description": "CPU usage exceeded 90%",
"severity": "critical",
"status": "problem",
"timestamp": "2024-12-03T10:00:00Z",
"host": "server01",
"hostIp": "192.168.1.100",
"service": "web-application",
"environment": "production",
"customerName": "AcmeCorp",
"project_code": "PRJ-001",
"datacenter": "Frankfurt"
}
Recovery Payload
{
"eventId": "cpu-high-server01-20241203-001",
"title": "High CPU Usage on server01",
"status": "resolved",
"timestamp": "2024-12-03T10:45:00Z"
}
Routing for Tags
Use custom fields for escalation routing:
tags.customer equals "AcmeCorp" → Acme Policy
tags.project_code equals "PRJ-001" → Project Policy
tags.environment equals "production" → Prod Policy
Test
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"eventId": "test-001",
"title": "Test Alert",
"severity": "warning",
"status": "problem",
"host": "test-server",
"project_code": "TEST"
}'
Recovery Test
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"eventId": "test-001",
"status": "resolved"
}'
Integration Examples
From a Shell Script
#!/bin/bash
WEBHOOK_URL="YOUR_WEBHOOK_URL"
# Check disk usage
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK_USAGE" -gt 90 ]; then
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"High Disk Usage\",
\"severity\": \"critical\",
\"host\": \"$(hostname)\",
\"description\": \"Disk usage is at ${DISK_USAGE}%\"
}"
fi
From Python
import requests
import json
webhook_url = "YOUR_WEBHOOK_URL"
payload = {
"title": "Application Error",
"severity": "high",
"host": "app-server-01",
"service": "payment-service",
"description": "Payment processing failed",
"tags": {
"error_code": "PAY-001",
"transaction_id": "txn-12345"
}
}
response = requests.post(
webhook_url,
headers={"Content-Type": "application/json"},
data=json.dumps(payload)
)
print(f"Status: {response.status_code}")
From Node.js
const axios = require("axios");
const webhookUrl = "YOUR_WEBHOOK_URL";
const payload = {
title: "Service Degradation",
severity: "warning",
host: "api-gateway",
service: "user-service",
description: "Response times increased by 50%",
tags: {
p99_latency: "2500ms",
error_rate: "2.5%",
},
};
axios
.post(webhookUrl, payload)
.then((response) => console.log("Alert sent:", response.status))
.catch((error) => console.error("Error:", error.message));
Troubleshooting
Webhook returns error
- Verify Content-Type is
application/json - Ensure payload is valid JSON
- Check webhook URL is correct
- Look at response body for error details
Fields not being extracted
- Use recognized field names from the list above
- Check field name spelling and casing
- View webhook samples to see parsed result
Wrong severity assigned
- Check severity value spelling
- Use standard values (critical, warning, info, etc.)
- Set appropriate default severity in integration config
Recovery not resolving incident
- Include same
eventIdin recovery payload - Set
statusto "resolved" or "ok" - Verify both payloads reach Easyalert
Invalid JSON error
- Validate JSON syntax (use jsonlint.com)
- Ensure proper escaping of special characters
- Check for trailing commas
Event grouped into existing incident
- Same host alerts within 5 minutes are grouped
- Use unique eventId to create separate incidents
- Check host field value
Best Practices
Use Consistent Event IDs: Include a unique eventId that stays consistent between alert and recovery. This enables automatic incident resolution.
Include Relevant Context: Add host, service, and environment fields to help responders quickly understand the alert.
Use Tags for Routing: Add tags that can be used in escalation routing rules (team, environment, customer).
Test Thoroughly: Send test alerts and recoveries before relying on the integration in production.
Include URLs: Add links to your monitoring tool or relevant dashboards in the url field.
Use Standard Severity Values: Stick to standard values (critical, warning, info) for consistent mapping.