---
title: 'PagerDuty'
description: 'Trigger PagerDuty incidents via Events API v2 with dedup_key = Yorker incident ID, observations and scoped hypothesis in custom_details.'
section: 'Integrations'
canonical_url: 'https://yorkermonitoring.com/docs/integrations/pagerduty'
---

# PagerDuty

Yorker drives PagerDuty through the [Events API v2](https://developer.pagerduty.com/docs/events-api-v2-overview). One Yorker incident maps to one PagerDuty alert; the `dedup_key` is the Yorker `incident_id`. Subsequent lifecycle events update the same PagerDuty alert rather than creating new ones.

For the underlying model (lifecycle states, event types, scoped hypothesis), see [Incidents](/docs/concepts/incidents).

## Set up

1. In PagerDuty, add an **Events API v2** integration to the service that should receive Yorker alerts. Copy the **Integration Key** (also called the routing key).
2. Note your PagerDuty region: `us` for `events.pagerduty.com`, `eu` for `events.eu.pagerduty.com`.
3. In Yorker, create a notification channel of type `pagerduty` with the routing key and region:

```bash
curl -X POST https://yorkermonitoring.com/api/notification-channels \
  -H "Authorization: Bearer $YORKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "pd-oncall",
    "channel": {
      "type": "pagerduty",
      "routingKey": "R0UTINGKEY1234567890ABCDEF",
      "serviceRegion": "us"
    }
  }'
```

| Field            | Required | Default | Description                               |
| ---------------- | -------- | ------- | ----------------------------------------- |
| `routingKey`     | yes      | —       | Events API v2 integration key             |
| `serviceRegion`  | no       | `us`    | `us` or `eu`                              |

## Event mapping

| Yorker event      | PD `event_action` | Notes                                              |
| ----------------- | ----------------- | -------------------------------------------------- |
| `opened`          | `trigger`         | First alert created                                |
| `acknowledged`    | `acknowledge`     | Forwards the Yorker ack to PD                      |
| `auto_resolved`   | `resolve`         | After cool-down elapses                            |
| `closed`          | `resolve`         | User-initiated close                               |
| `reopened`        | `trigger`         | Recurrence re-triggers the alert                   |
| `note_added`      | `trigger`         | PD treats duplicate dedup_key triggers as updates  |
| `severity_changed`| *(skipped)*       | Events API v2 has no matching action               |
| `alert_attached`  | *(skipped)*       | Internal-only                                      |

`dedup_key` is always the Yorker `incident_id`. `severity` maps `critical → critical`, `warning → warning`, `info → info`.

Example `opened` payload:

```json
{
  "routing_key": "R0UTINGKEY…",
  "event_action": "trigger",
  "dedup_key": "inc_abc",
  "payload": {
    "summary": "[Yorker] Checkout API outage",
    "source": "yorker",
    "severity": "critical",
    "class": "synthetic-monitoring",
    "custom_details": {
      "incident_id": "inc_abc",
      "event_type": "opened",
      "event_id": "ievt_001",
      "sources": ["synthetic_http"],
      "affected_checks": ["Checkout API"],
      "locations_affected": ["loc_us_east_1", "loc_eu_west_1"],
      "shared_failing_domains": ["api.stripe.com"],
      "hypothesis": {
        "summary": "Stripe API is returning 503/504; checkout is blocked.",
        "confidence": 0.75,
        "ruled_in": ["shared_failing_domain=api.stripe.com"],
        "ruled_out": ["DNS resolution: NXDOMAIN not observed", "TLS: handshake completes"],
        "scope": "external_symptoms_only",
        "correlation_dimensions_matched": ["shared_failing_domain", "error_pattern"]
      },
      "actor": { "type": "system", "id": null }
    }
  },
  "links": [
    { "href": "https://yorkermonitoring.com/dashboard/incidents/inc_abc", "text": "View in Yorker" }
  ]
}
```

When the incident is a recurrence of prior closed incidents, Yorker adds up to 5 prior incident links to the `links` array so the on-call engineer can pivot to history without leaving PD.

## Template overrides

Only the `custom_details` block is user-editable. The envelope (routing key, event action, dedup key, severity, source, summary) is fixed so dedupe and severity semantics stay consistent across your tenants.

> **UI editor note:** the in-app per-channel template editor (at **Settings > Notification Channels > Templates**) currently supports Slack, email, and webhook channels only. PagerDuty `customDetails` overrides are authored through the API below; a UI editor for PagerDuty is planned for a future release.

```bash
curl -X PUT https://yorkermonitoring.com/api/notification-channels/nch_abc \
  -H "Authorization: Bearer $YORKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "incidentTemplate": {
      "channelType": "pagerduty",
      "overrides": {
        "opened": {
          "customDetails": "{\"runbook\":\"https://wiki.acme.com/runbooks/checkout\",\"yorker_link\":\"{{incident.triageUrl}}\",\"severity\":\"{{incident.severity}}\",\"hypothesis\":\"{{payload.hypothesis.summary}}\"}"
        }
      }
    }
  }'
```

The rendered string must parse as a JSON object. On render failure or invalid JSON the default custom_details block is used instead; dispatch does not fail.

Helper and render context are the same as the [Slack integration](/docs/integrations/slack).

## Ack propagation

Acknowledging in Yorker sends `event_action: "acknowledge"` to PagerDuty. Acknowledging in PagerDuty does **not** propagate back to Yorker in this release — bidirectional sync is tracked as a future enhancement.

## Disabling

The PagerDuty channel type is **incident-pipeline-only** — it has no legacy per-alert dispatch path. `incidentSubscribed` is locked to `true` for PagerDuty channels; the API rejects create/update requests that set it to `false`. To stop routing incidents to a PagerDuty channel, delete it or remove it from the alert rule's channel list.
