# PagerDuty

{% hint style="info" %}
This capability is only available to BYOC deployments. Check out our [pricing page](https://www.groundcover.com/pricing) for more information about subscription plans and the available deployment modes.
{% endhint %}

### Generate PagerDuty Routing (Integration) Key

1. In PagerDuty, Go to the your desired service, then click on integrations tab
2. Click on "Add an integration" or "+ Add another integration"
3. Select "Events API V2" Integration, and click on Add.

   <figure><img src="/files/XOc5hTD6CKZGeEfnvtAl" alt=""><figcaption><p>Events API V2</p></figcaption></figure>
4. Copy the Integration Key.

   <figure><img src="/files/okuHefalrHqmoDVcjrBo" alt=""><figcaption></figcaption></figure>

### Create an PagerDuty Connected App in groundcover

1. In groundcover, go to **Settings → Connected-Apps**.
2. Click on PagerDuty.

<figure><img src="/files/V2qipS1XnR9CL7lKxdsp" alt=""><figcaption></figcaption></figure>

3. Select a name and paste your routing key.

<figure><img src="/files/wgEzSaEp1kTF0QWe62oW" alt="" width="375"><figcaption></figcaption></figure>

4. **Test the connection** (Optional) - sends a test alert to verify the integration.
5. **Save**

### PagerDuty Event Payload

groundcover sends events to PagerDuty using the Events API V2 format:

```json
{
  "routing_key": "<your-routing-key>",
  "event_action": "trigger|resolve",
  "dedup_key": "{{ fingerprint }}",
  "payload": {
    "summary": "{{ summary }}",
    "severity": "critical|error|warning|info",
    "source": "groundcover",
    "timestamp": "{{ timestamp }}",
    "custom_details": {
      "monitor_name": "{{ monitor_name }}",
      "monitor_id": "{{ monitor_id }}",
      "description": "{{ description }}",
      "value": "{{ value }}",
      "threshold": "{{ threshold }}",
      "status": "alerting|resolved",
      "renotification_count": 0,
      "labels": {
        "cluster": "{{ labels.cluster }}",
        "namespace": "{{ labels.namespace }}",
        "workload": "{{ labels.workload }}"
      }
    }
  },
  "links": [
    { "href": "{{ urls.issue }}", "text": "View Issue" },
    { "href": "{{ urls.monitor }}", "text": "View Monitor" }
  ]
}
```

{% hint style="info" %}
This payload structure is fixed and cannot be customized. Values shown with `{{ }}` are dynamically populated from your monitor configuration. If you need a custom payload structure, use a [Generic Webhook](/integrations/connected-apps/generic-webhook.md) instead.

**Test mode:** When using "Test the connection", the `status` field will be "test" and other fields like `value`, `threshold`, and URLs may contain placeholder values.
{% endhint %}

#### Payload Field Reference

| Field                  | Location            | Description                                                                                                                                       |
| ---------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `summary`              | `payload.summary`   | Issue title from the alert                                                                                                                        |
| `severity`             | `payload.severity`  | Mapped from groundcover severity (see table below)                                                                                                |
| `source`               | `payload.source`    | Always "groundcover"                                                                                                                              |
| `timestamp`            | `payload.timestamp` | Alert firing time in UTC                                                                                                                          |
| `monitor_name`         | `custom_details`    | Name of the monitor                                                                                                                               |
| `monitor_id`           | `custom_details`    | Internal unique ID of the monitor                                                                                                                 |
| `description`          | `custom_details`    | Monitor description with variable expansion                                                                                                       |
| `value`                | `custom_details`    | The value that triggered the alert                                                                                                                |
| `threshold`            | `custom_details`    | Configured threshold for the monitor                                                                                                              |
| `status`               | `custom_details`    | Alert state: "alerting", "resolved", or "test" (during connection testing)                                                                        |
| `renotification_count` | `custom_details`    | Counter for re-notifications (starts at 0)                                                                                                        |
| `labels`               | `custom_details`    | Monitor labels as key-value pairs. Only labels defined in the monitor's group-by or custom labels are included; keys may be absent if not defined |
| `dedup_key`            | root                | Alert fingerprint for deduplication                                                                                                               |
| `links`                | root                | URLs to issue and monitor in groundcover                                                                                                          |

### Key Fields for Automation

**`renotification_count`**: Starts at 0 for the first notification and increments with each re-notification while the alert is firing. This field is included in every event payload and can be used in PagerDuty Event Orchestration for automation:

* `renotification_count == 0` - First notification
* `renotification_count > 0` - Re-notification (alert still firing)

The counter resets to 0 when the alert resolves and fires again.

**`dedup_key`**: Uses the alert fingerprint to group related events. PagerDuty will deduplicate events with the same `dedup_key`.

### Severity Mapping

groundcover severities are mapped to PagerDuty severities:

| groundcover | PagerDuty |
| ----------- | --------- |
| S1          | critical  |
| S2          | error     |
| S3          | warning   |
| S4          | info      |

### Troubleshooting

#### Why isn't there a separate description field in PagerDuty alerts?

PagerDuty Events API v2 uses `summary` as the main alert title. The `description` field is included in `custom_details` and contains the monitor description with any configured variable expansion.

#### Can I customize which labels appear in PagerDuty?

With the Connected App, monitor labels (group-by and custom) are included in `custom_details.labels`. Only labels that are defined on the monitor are included - keys will be absent if the label is not defined. If you need to select specific labels or map them to custom field names, use a [Generic Webhook](/integrations/connected-apps/generic-webhook.md) with a custom payload.

#### My alerts show "groundcover" as the source - can I change this?

The `source` field is fixed to "groundcover" in the Connected App. To customize the source or any other field, use a [Generic Webhook](/integrations/connected-apps/generic-webhook.md) instead.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.groundcover.com/integrations/connected-apps/pagerduty.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
