Custom Webhooks
Overview
Custom Webhooks in ToBeAlert allow external systems to send alerts using their own data format. Instead of adapting your monitoring tools to ToBeAlert's format, you can create a custom webhook that maps incoming data to ToBeAlert's alert structure.
How It Works
- Create a webhook configuration that defines field mappings
- Get a unique webhook URL for your configuration
- Send data in your format to the webhook URL
- ToBeAlert maps your data into standardized alerts
Webhook URL Format
Each custom webhook configuration gets a unique URL:
https://your-tobealert.com:9000/api/webhooks/custom/{webhook-id}
This endpoint accepts POST requests with a JSON body. It has no inbound authentication in this version: anyone who knows the URL can post to it.
Creating a Custom Webhook
1. Define Your Input Format
First, understand what data your monitoring system sends. For example:
{
"hostname": "web-server-01",
"check": "cpu_usage",
"status": "CRITICAL",
"message": "CPU usage is 95%",
"timestamp": "2025-04-15T10:30:00Z",
"metrics": {
"cpu": 95.2,
"memory": 67.8
},
"tags": [
"production",
"linux"
],
"source": "nagios"
}
2. Create the Webhook Configuration
fieldMappings is required, and resource, event, environment, type, text, and severity must each be mapped or have a default; otherwise the request returns 400.
The webhook ID may contain only letters, digits, - and _. Creating needs scope write:webhook_configs.
curl -X POST http://your-tobealert.com:9000/api/webhook_config \
-H "Content-Type: application/json" \
-H "Authorization: Key YOUR_API_KEY" \
-d '{
"id": "nagios-monitoring",
"name": "Nagios Monitoring Integration",
"fieldMappings": {
"resource": "hostname",
"event": "check",
"text": "message",
"value": "metrics.cpu",
"origin": "source",
"tags": "tags",
"attributes": {
"source_status": "status",
"memory_usage": "metrics.memory",
"original_timestamp": "timestamp"
}
},
"defaultValues": {
"environment": "Production",
"type": "nagiosAlert",
"severity": "warning",
"group": "infrastructure",
"service": [
"monitoring"
]
}
}'
Each value in fieldMappings is a path into the payload; fixed values go in defaultValues. The sender's status (CRITICAL) is not a ToBeAlert severity, so it is kept in attributes.source_status and severity defaults to warning until a policy translates it — see Transforming values.
3. Use Your Webhook URL
The response (201) includes the stored configuration and your webhook URL:
{
"status": "ok",
"id": "nagios-monitoring",
"webhook_config": { "id": "nagios-monitoring", "name": "Nagios Monitoring Integration", "...": "..." },
"webhook_url": "https://your-tobealert.com:9000/api/webhooks/custom/nagios-monitoring"
}
Now send your data to this URL:
curl -X POST https://your-tobealert.com:9000/api/webhooks/custom/nagios-monitoring \
-H "Content-Type: application/json" \
-d '{
"hostname": "web-server-01",
"check": "cpu_usage",
"status": "CRITICAL",
"message": "CPU usage is 95%",
"timestamp": "2025-04-15T10:30:00Z",
"metrics": {
"cpu": 95.2,
"memory": 67.8
},
"tags": ["production", "linux"],
"source": "nagios"
}'
The mapping produces this alert:
[
{
"resource": "web-server-01",
"event": "cpu_usage",
"text": "CPU usage is 95%",
"value": 95.2,
"origin": "nagios",
"tags": [
"production",
"linux"
],
"attributes": {
"source_status": "CRITICAL",
"memory_usage": 67.8,
"original_timestamp": "2025-04-15T10:30:00Z"
},
"environment": "Production",
"type": "nagiosAlert",
"severity": "warning",
"group": "infrastructure",
"service": [
"monitoring"
]
}
]
The inbound response lists the alerts created:
{
"status": "ok",
"webhook_id": "nagios-monitoring",
"webhook_name": "Nagios Monitoring Integration",
"alerts_created": 1,
"alerts": [
{ "id": "6f1c…", "resource": "web-server-01", "event": "cpu_usage", "severity": "warning" }
]
}
Field Mappings
Field mappings say where each alert field is read in the payload. They copy values as they are: there are no ${…} templates, expressions, or functions. The full syntax is in the Field Mapping Reference.
| Mapping value | Meaning |
|---|---|
"hostname", "server.name", "checks[0]", "events[1].type" | Path into the payload (dot notation, array index) |
"tags" / "tags[]" | Whole array, copied as a list |
{"path": "errors", "join": ", "} | Array joined into one string |
{"path": "hosts[]", "expand": true} | One alert per array element ([N] in other mappings reads the same index) |
{"path": "is_critical", "if_true": "critical", "if_false": "warning"} | One of two fixed values depending on a boolean |
{"cpu": "metrics.cpu", …} under attributes | Custom attributes, same syntax |
3600, true | Numbers and booleans are copied literally |
A string is always a path: "environment": "production" reads a key called production and, when it is missing, leaves the field out. Put fixed text in defaultValues:
{
"defaultValues": {
"environment": "Production",
"group": "general",
"origin": "webhook",
"severity": "warning"
}
}
A default is used when the field is not mapped or its path is missing in the payload.
Set arrayPath (for example alerts) when the payload carries several events in one array: each element becomes one alert, and every mapping is read inside that element.
Transforming values
To translate a source status into a severity, replace part of a text, or add a fixed tag, keep the mapping as a plain copy and add a policy with modifiers (condition on the copied value → set, replace, add). Case changes, trimming, numeric thresholds, and values built from several fields need a custom tool attached to the policy. Details: Transforming values.
Complete Examples
Ready-to-adapt configurations for Prometheus Alertmanager, Datadog, Grafana, PagerDuty, AWS CloudWatch, Kubernetes, and a custom application are in Integration Examples, each with its sample payload.
Managing Webhooks
List All Webhooks
curl -H "Authorization: Key YOUR_API_KEY" \
http://your-tobealert.com:9000/api/webhook_configs
Get Webhook Details
curl -H "Authorization: Key YOUR_API_KEY" \
http://your-tobealert.com:9000/api/webhook_config/nagios-monitoring
Update Webhook
curl -X PUT http://your-tobealert.com:9000/api/webhook_config/nagios-monitoring \
-H "Content-Type: application/json" \
-H "Authorization: Key YOUR_API_KEY" \
-d '{
"name": "Updated Nagios Integration",
"fieldMappings": {
"resource": "hostname",
"event": "check",
"text": "message",
"attributes": { "source_status": "status" }
}
}'
PUT updates the fields you send; fields you omit keep their value.
Delete Webhook
curl -X DELETE http://your-tobealert.com:9000/api/webhook_config/nagios-monitoring \
-H "Authorization: Key YOUR_API_KEY"
Testing Webhooks
Send a sample POST to the inbound URL and read the response: it lists the alerts created and, for each failed alert, the mapped data and the reason. There is no GET on the inbound URL; read the configuration with GET /api/webhook_config/{id}.
curl -X POST https://your-tobealert.com:9000/api/webhooks/custom/nagios-monitoring \
-H "Content-Type: application/json" \
-d '{
"hostname": "test-server",
"check": "cpu_test",
"status": "WARNING",
"message": "Test alert"
}'
Error Handling
Common Errors
- Missing required fields — saving mappings that do not cover
resource,event,environment,type,text,severityreturns 400Invalid field mappings: Missing required alert columns: … - Field silently missing — a mapping whose path is not in the payload (or a fixed string or
${…}template written infieldMappings) leaves the field out; usedefaultValues - Alert rejected — the mapped data is not a valid alert:
An environment must be provided,service must be a list,tags must be a list,Severity (…) is not one of … - No alerts from Array Path — 400
No alerts generated from payloadwhen the path is missing or the array is empty
Error Response Format
Rejected requests (403 disabled, 404 unknown id, invalid or empty JSON, mapping errors) return a status and a message:
{
"status": "error",
"message": "No alerts generated from payload"
}
When the payload was mapped but some alerts could not be created, the response keeps the alert summary and adds errors with the mapped data and the reason. status is partial (HTTP 200) when at least one alert was created, error (HTTP 400) when none was:
{
"status": "error",
"webhook_id": "nagios-monitoring",
"webhook_name": "Nagios Monitoring Integration",
"alerts_created": 0,
"alerts": [],
"errors": [
{
"alert_data": { "resource": "web-01", "event": "cpu", "severity": "UNKNOWN", "...": "..." },
"error": "Severity (UNKNOWN) is not one of security, critical, major, minor, warning, …"
}
]
}
Best Practices
- Use descriptive webhook IDs — make them easy to identify and manage
- Provide default values — every required field should have a default or a path that is always present
- Validate input format — test with real data from your monitoring system
- Keep source values in attributes — policies can then translate statuses and priorities
- Monitor webhook health — check the responses your monitoring system receives for rejected or failed alerts
- Version your configurations — use IDs like
nagios-v1,nagios-v2
Security Considerations
- The inbound URL has no authentication in this version: treat the webhook ID as a secret and keep it out of public places
- Use HTTPS for all webhook traffic
- Consider network controls (IP allowlists) in front of ToBeAlert when possible
- Delete webhook configurations you no longer use