Skip to main content

Custom Webhook

CompanyEstimated TimeVendor DocsOpen Source
PagerTree LLC15 minutesv3.rb

What Is the Custom Webhook Integration?​

The Custom Webhook integration allows you to process arbitrary inbound webhook payloads using a user-defined YAML configuration. This is useful when you need conditional logic to automatically create, acknowledge, or resolve alerts based on the webhook contents.

Key features include:

  • MongoDB-style rule matching (same operators & syntax as Routers).
  • Nested JSON support via log.data.<field>.
  • Handlebars templates for dynamic fields (see handlebars and handlebars-helpers).
  • Actions: create, update, acknowledge, resolve.
  • Preprocessors such as parse_json and parse_sns.

It integrates with tools like UptimeRobot, AWS SNS, Pingdom, and many more by parsing payloads and applying your rules.

info

This documentation is for incoming custom webhooks (that need custom logic) into PagerTree. If you are looking for the PagerTree standard format webhooks, refer to the webhook documentation. For outgoing webhooks, refer to the outgoing webhook documentation.

How It Works​

  1. Your external system sends a POST request to PagerTree’s integration endpoint.
  2. PagerTree loads your YAML rules.
  3. Preprocessors (if any) run first (e.g., parse_json, parse_sns).
  4. Each rule’s match block is evaluated against the payload.
  5. On the first match, PagerTree performs the specified actions.
  6. If no rule matches, the optional default rule applies.

Important matching notes:

  • All JSON body payload fields are referenced under log.data.
  • Supports operators such as:
    $eq, $regex, $gt, $in, $and, $or, $not, $exists, and more. (see routers#operators)
  • Handlebars templates allow injecting values directly from payload structure. (see handlebars and handlebars-helpers)

Video Explanation​

Check out the following video, for an in-depth explanation of how to use the custom YAML definition in the PagerTree Custom Webhook integration.

Integration Walkthrough​

In this tutorial, we'll set up the Custom Webhook integration in PagerTree and configure the YAML rules. We assume you have a PagerTree account and a custom tool that can send POST webhooks.

In PagerTree​

  1. Create the integration by clicking the Webhook (Custom) logo.
  2. Enter your YAML configuration in the Custom Definition field (see examples below).
  3. Copy the PagerTree Endpoint URL to configure in your source tool.

Configure YAML Rules​

Define rules in YAML for matching and actions (see examples below). Prefix fields with log.data for payload data.

In Your Source Tool​

Configure your tool (e.g., UptimeRobot, AWS SNS, etc.) to send POST requests to PagerTree's endpoint URL. The payload will be processed using your YAML rules.

YAML Syntax Reference​

Rule Structure​

preprocess:
# preprocessors
# - type: parse_sns
rules:
- match:
# conditions (see your specific tool's payload)
# log.data.state: "alarm"
actions:
- type: create|update|acknowledge|resolve
thirdparty_id: "{{log.data.id}}"
default:
actions:
- type: ignore

Preprocessors​

PreprocessorDescription
parse_jsonConverts a raw string into JSON.
parse_snsProcesses AWS SNS payloads and parses the Notification Message.

Match Data​

The shape of the data passed in for you to match on is as follows:

{
"always": true,
"log": {
"data": {
/* Your tool's payload (a combition of any query parameters and JSON payload) (hash) */
"key1": "value1",
"key2": {
"key3": 123
}
// ...
},
"headers": {
/* Headers of the HTTP Request sent by your tool (hash) */
"Content-Type": "application/json"
// ...
},
"body": "", // Raw body of the payload (string).
"params": {}, // Raw query parameters (hash).
"method": "", // The HTTP verb (string).
"url": "", // The URL that was called (string).
"remote_ip": , // The IP that made the call (string).
}
}

Action Fields​

FieldRequired?TypePurpose
type✅stringcreate, update, acknowledge, resolve
thirdparty_id✅stringIdentifier used for alert correlation. (see integrations@alert-aggregation)
titleon createstringAlert title.
description-stringAlert description.
urgency-enumcritical, high, medium, low, silent
tags-list/stringAlert tags. List (array). String (comma delimited)
meta-objectAdditional metadata (hash)
additional_data-listSupplemental visual fields (object) {format: "text|link|img|email|phone|datetime", label: "string", value: "string"}
dedup_keys-list/stringGlobal deduplication keys. List (array). String (command delimiated)
incident-booleanBoolean value true|false if this alert should be flagged as an incident
incident_severityif incident truestringSEV-1, SEV-2, SEV-3, SEV-4, SEV-5
incident_messageif incident truestringA custom message to be displayed at the top of the alert page
info

For update, thirdparty_id is only used to find the existing alert to update - it cannot be used to change the alert's thirdparty_id. Every field besides type and thirdparty_id is optional; only the fields your rule returns are changed on the alert, so leave a field out entirely if you don't want it touched.

Examples​

Example: New Relic​

---
rules:
- match:
log.data.currentState: "open"
log.data.severity: "CRITICAL"
actions:
- type: create
title: "{{log.data.accumulations.policyName.[0]}} - {{log.data.accumulations.conditionName.[0]}}"
description: "{{log.data.annotations.description}} - Details: {{log.data.details}}"
thirdparty_id: "{{log.data.incidentId}}"
urgency: "high"
additional_data:
- format: link
label: Incident URL
value: "{{log.data.incidentUrl}}"
- format: link
label: Policy URL
value: "{{log.data.policyUrl}}"
- format: text
label: Targets
value: "{{log.data.targets.[0].name}} ({{log.data.targets.[0].type}})"

- match:
log.data.currentState: "closed"
actions:
- type: resolve
thirdparty_id: "{{log.data.incidentId}}"

default:
actions:
- type: ignore
reason: "Unhandled New Relic alert"

Example: Update Urgency Without Resolving​

Some tools send a "downgraded" or "warning" event when an incident's severity changes without it actually closing. Rather than resolving and recreating the alert, use update to change just the urgency:

---
rules:
- match:
log.data.currentState: "open"
log.data.severity: "CRITICAL"
actions:
- type: create
title: "{{log.data.accumulations.policyName.[0]}}"
thirdparty_id: "{{log.data.incidentId}}"
urgency: "critical"

- match:
log.data.currentState: "open"
log.data.severity: "WARNING"
actions:
- type: update
thirdparty_id: "{{log.data.incidentId}}"
urgency: "medium"

- match:
log.data.currentState: "closed"
actions:
- type: resolve
thirdparty_id: "{{log.data.incidentId}}"

default:
actions:
- type: ignore
reason: "Unhandled event"

Since title isn't included in the update action, the alert keeps its original title - only urgency changes.

Example: AWS SNS + Cloudwatch​

---
preprocess:
- type: parse_sns
rules:
- match:
log.data.Type: "Notification"
log.data.Message.NewStateValue: "ALARM"
actions:
- type: create
title: "{{sanitize log.data.Subject}}"
description: "{{log.data.Message.NewStateReason}}"
thirdparty_id: "{{log.data.Message.AlarmArn}}"
additional_data:
- format: text
label: Event Category
value: "scheduledChange"
- format: text
label: Affected Resources
value: "example-service|example-backend"
- format: link
label: Fargate Platform Docs
value: "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform-fargate.html"
- format: link
label: Task Maintenance Docs
value: "https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-maintenance.html"
- format: link
label: Service Definition Params
value: "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html#sd-deploymentconfiguration"
- format: link
label: Fargate Notifications Blog
value: "https://aws.amazon.com/blogs/containers/improving-operational-visibility-with-aws-fargate-task-retirement-notifications/"
- format: link
label: Create Deployment CLI
value: "https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html"
- format: link
label: AWS Support
value: "https://aws.amazon.com/support"

- match:
log.data.Type: "Notification"
log.data.Message.NewStateValue: "OK"
actions:
- type: resolve
thirdparty_id: "{{log.data.Message.AlarmArn}}"
default:
actions:
- type: ignore
reason: "Unhandled CloudWatch Event"
Example: AWS SNS Cloudwatch (cURL)​

You have successfully completed the Custom Webhook Integration.