AWS CloudWatch integration
Forward AWS CloudWatch alarms to Unit Oncall through Amazon SNS. A CloudWatch alarm publishes to an SNS topic, and an HTTPS subscription on that topic POSTs the notification to your Unit Oncall Webhook URL. Unit Oncall normalizes it, routes it to a Schedule, and pages the on-call responder.
Setup
- In Unit Oncall, create a Webhook (Integrations → Webhooks → New). Choose a Team and default Schedule. Use Standard auth mode so the secret is embedded in the URL — SNS HTTPS deliveries cannot add custom headers. Copy the generated Webhook URL.
- In AWS, create (or reuse) an SNS topic and set your CloudWatch alarm's action to publish to it.
- Add an HTTPS subscription to the topic with the Endpoint set to the Unit Oncall Webhook URL from step 1.
- Enable raw message delivery on the subscription (SNS console → the subscription → Edit → check Raw message delivery, or
aws sns set-subscription-attributes --subscription-arn <arn> --attribute-name RawMessageDelivery --attribute-value true). This is required — see the note below. - SNS first sends a
SubscriptionConfirmationrequest. Confirm the subscription (open theSubscribeURLfrom that request) so SNS begins delivering notifications.
Enable raw message delivery. Without it, SNS wraps the alarm in an envelope and delivers the CloudWatch alarm JSON as an escaped string inside the top-level
Messagefield. Unit Oncall evaluates JSONPath against the parsed request body and does not re-parse a string-encoded JSON object, so paths like$.Message.AlarmNamewould not resolve. With raw message delivery on, the CloudWatch alarm JSON becomes the request body directly and the rule below reads its fields from the top level ($.AlarmName, …). Standard auth mode still works — the secret travels in the URL token, which raw delivery does not affect.
Webhook URL
Unit Oncall exposes a single unified receive endpoint. The token in the path identifies the webhook (and, in Standard mode, carries the secret):
POST https://<your-api-host>/api/v1/wh/{token}
{token}is an opaque, encrypted value generated when you create the Webhook. Treat it as a credential.- Standard auth mode (required for SNS): the secret is embedded in the token, so the URL is self-contained. SNS HTTPS deliveries cannot attach a custom header, so Secure mode is not usable here.
Recommended transformation rule
This rule assumes raw message delivery is enabled, so the request body is the CloudWatch alarm JSON itself. It uses the alarm name as the fingerprint, builds a title from the new state and alarm name, maps the alarm state to a severity, and maps StateChangeTime as the detection time so state transitions are ordered correctly.
{
"name": "AWS CloudWatch (via SNS, raw delivery)",
"description": "Maps CloudWatch alarm notifications (SNS raw message delivery) to Unit Oncall alerts.",
"is_active": true,
"mappings": {
"fingerprint": {
"type": "jsonpath",
"path": "$.AlarmName"
},
"title": {
"type": "format",
"format": "[{$.NewStateValue}] {$.AlarmName}"
},
"severity": {
"type": "jsonpath",
"path": "$.NewStateValue",
"mapping": {
"ALARM": "critical",
"INSUFFICIENT_DATA": "warning",
"OK": "info"
},
"default": "warning"
},
"message": {
"type": "jsonpath",
"path": "$.NewStateReason",
"default": "CloudWatch alarm state changed (no reason provided)"
},
"timestamp": {
"type": "jsonpath",
"path": "$.StateChangeTime"
},
"tags": {
"type": "jsonpath",
"path": "$.Region"
}
}
}
See the Transformation Rule reference for the full field and mapping syntax.
Troubleshooting
- No alert arrives. Confirm the SNS subscription status is Confirmed, not PendingConfirmation. Re-confirm via the
SubscribeURLif needed. 403 webhook disabled. The Webhook'sis_enabledisfalse. Enable it.- Fingerprint/title are empty. Raw message delivery is probably off, so the alarm JSON is still an escaped string inside
Messageand$.AlarmNameresolves to nothing. Turn on raw message delivery (Setup step 4). If you cannot enable it (for example a topic shared with consumers that need the envelope), put a Lambda subscriber in front that unwrapsMessageand re-POSTs the alarm JSON to the Webhook URL. - Severity is always the default.
NewStateValuewas missing or had an unexpected value. CloudWatch states areALARM,OK, andINSUFFICIENT_DATA; keep all three in themappingtable. - Alarms flap out of order. Map
$.StateChangeTime(the alarm's state-change time) so transitions are ordered. See the note in the Transformation Rule reference.
