Custom Webhooks Troubleshooting
Common Issues
400 Bad Request
Problem: Field mapping failed, invalid data, empty body, invalid JSON, or no alerts from the configured Array Path.
Common causes:
- Invalid JSON in request
- Empty request body (including
null,{}, or[]treated as empty) - Array Path set, but the POST yields no alerts: the path is missing from the JSON, or the array at that path is empty
- Every mapped alert was rejected: a required field ended up missing (
An environment must be provided),service/tagsis not a list, orseverityis not a ToBeAlert severity (Severity (CRITICAL) is not one of …)
When Array Path is set and no alerts are generated, the response message is No alerts generated from payload.
Example error responses:
{
"status": "error",
"message": "No alerts generated from payload"
}
When the mapping ran but no alert could be created, each rejected alert is listed with the data the mapping produced:
{
"status": "error",
"webhook_id": "your-webhook-id",
"webhook_name": "My Monitoring Integration",
"alerts_created": 0,
"alerts": [],
"errors": [
{
"alert_data": { "resource": "web-01", "event": "cpu", "severity": "CRITICAL", "...": "..." },
"error": "Severity (CRITICAL) is not one of security, critical, major, minor, warning, …"
}
]
}
Invalid JSON returns Invalid JSON payload: …; an empty body returns Empty payload.
Solution:
- Read
errors[].alert_datain the response to see what the mapping produced - Give every required field a default value, so a missing path does not drop it
- Keep values that are not ToBeAlert severities in an attribute and translate them with a policy (see Transforming values)
- Validate incoming JSON format (non-empty object or array)
- Make Array Path match a key in the payload (for example
events), or leave it empty to treat the whole body as one alert
403 Forbidden (disabled)
Problem: The webhook configuration is disabled (enabled: false). The request is rejected with Webhook "…" is disabled and no alert is created. Enable the config when you are ready to create alerts.
Missing Data After Mapping
Problem: Some fields are empty or missing in the created alert.
Causes:
- The path does not exist in this payload (typo, different nesting, or the value is inside an array — use an index such as
items[0].nameor Array Path) - The mapping value is fixed text (
"origin": "nagios") or a template ("${hostname}"): both are read as paths that do not exist, so the field is left out - With Array Path set, the path points outside the array element (for example
commonLabelswhenarrayPathisalerts)
Solution:
- Compare the paths with a real payload from your tool
- Move fixed text to
defaultValues, and add defaults for fields that are not always present:
"defaultValues": {
"environment": "Production",
"group": "default",
"origin": "nagios"
}
Templates or Expressions Have No Effect
Problem: A mapping such as "${hostname}-${check}", "${status == 'CRITICAL' ? 'critical' : 'warning'}" or "${message.trim()}" produces nothing.
Cause: Field mappings do not support templates, expressions, or functions. Each string is a path, and these strings are paths that do not exist.
Solution:
- Map the plain value:
"text": "message" - For a boolean source, use
{"path": "is_critical", "if_true": "critical", "if_false": "warning"} - For case changes, trimming, value translation, or numeric thresholds, add a policy on receive — see Transforming values
Array Mapping Issues
Problem: Arrays not mapping correctly.
Solution:
serviceandtagsneed a list — map the array directly:
"fieldMappings": {
"tags": "tags",
"service": "services"
}
- A text field needs a string — join the array:
"fieldMappings": {
"text": { "path": "errors", "join": ", " }
}
- One element by index, with a default when the array is empty:
"fieldMappings": { "resource": "servers[0]" },
"defaultValues": { "resource": "unknown" }
- One alert per element:
{"path": "servers[]", "expand": true}, or set Array Path when each element is a whole event.
Debugging Techniques
1. Test with Simple Data
Start with a simple test payload:
{
"hostname": "test-server",
"check": "cpu",
"status": "WARNING",
"message": "Test message"
}
2. Check the Configuration
curl -H "Authorization: Key YOUR_API_KEY" \
http://your-tobealert.com:9000/api/webhook_config/your-webhook-id
Compare arrayPath, fieldMappings, and defaultValues with the payload you send. The inbound URL only accepts POST.
Validation Tips
1. Validate Input Structure
Know what data your monitoring system sends:
// Example: Prometheus Alertmanager
{
"alerts": [
{
"labels": {
"alertname": "HighCPU",
"instance": "server-01"
},
"annotations": {
"description": "CPU is high"
}
}
]
}
2. Test Edge Cases
Test with:
- Missing fields
- Null values
- Empty arrays
- Special characters
3. Check the JSON Syntax
fieldMappings and defaultValues must be valid JSON objects (no comments, no trailing commas). The API rejects invalid mappings on save with Invalid field mappings: ….
Common Mapping Patterns
Handling Different Severity Formats
Keep the source value in an attribute, give severity a default, and translate with policies (condition on the attribute → severity set):
"fieldMappings": {
"attributes": { "source_severity": "severity" }
},
"defaultValues": {
"severity": "warning"
}
When the source already sends ToBeAlert severities in lower case (critical, warning, …), map it directly: "severity": "severity".
Environment From a Tag
Mappings cannot search inside a list such as ["env:production", "team:backend"]. Map the list to tags, set environment in defaultValues, or send the environment as its own field from the source.
Alert Identity
There is no alert id template. Alerts are identified by environment, resource, and event: map resource and event to the fields that identify the problem on your side.
Getting Help
- Check the error response - Look for detailed error messages
- Check the configuration -
GET /api/webhook_config/{id} - Test with curl - Verify your payload format
- Contact support - Include webhook configuration (without secrets) and a sample payload
Test Script
#!/bin/bash
# Test custom webhook
WEBHOOK_URL="https://your-tobealert.com:9000/api/webhooks/custom/your-webhook-id"
# Test payload
TEST_DATA='{
"hostname": "test-server-01",
"check": "cpu_usage",
"severity": "warning",
"message": "CPU usage is 85%",
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)'"
}'
echo "Testing webhook: $WEBHOOK_URL"
echo "Payload: $TEST_DATA"
echo ""
response=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d "$TEST_DATA" \
$WEBHOOK_URL)
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | head -n -1)
echo "HTTP Code: $http_code"
echo "Response: $body"
if [ "$http_code" = "200" ]; then
echo "✓ Webhook test successful!"
alert_id=$(echo "$body" | jq -r '.alerts[0].id')
echo "Alert ID: $alert_id"
else
echo "✗ Webhook test failed"
fi