# Webhooks

Configure and manage V3 webhook subscriptions, including migrating existing V1 and V2 webhook extensions to the current version.

Webhooks allow you to receive HTTP callbacks when significant events happen in your PagerDuty account — for example, when an incident triggers, escalates, or resolves. Details about the event are sent to your specified URL, such as [Slack](/integrations/slack-integration-guide) or your own [custom PagerDuty webhook processor](https://developer.pagerduty.com/docs/ZG9jOjQ1MTg4ODQ0-overview).

> **Migrate to V3 Webhook Subscriptions:** - If you are currently using [V1/V2 webhook extensions](https://support.pagerduty.com/main/docs/v1v2-webhook-extensions)) and need to migrate to V3 webhook subscriptions, follow the [Migration Guide](#migrate-from-v1v2-generic-extensions-to-v3-webhook-subscriptions) or use the [migration script](https://github.com/PagerDuty/public-support-scripts/tree/master/migrate_webhooks_to_v3) (provided as is).
>   - An end-of-life date for V2 webhooks has not been set. End-of-support for V2 webhooks began on October 31, 2022. Existing integrations based on V2 webhooks will continue to work; however, PagerDuty cannot accept new feature requests or implement bug fixes.
>   - V1 webhook extensions became unsupported on November 13, 2021 and lost functionality on October 31, 2022. See [Webhook V1 Alternatives](/integrations/webhooks)) for a list of affected integrations and alternative solutions.

## Webhook IPs

> **Safelist Updates:** As of May 5, 2022, the `/webhook_ips` endpoint will no longer be updated. Use the page linked below for all safelist updates.

For a list of IP addresses that PagerDuty uses to send webhooks in each service region, visit the [Developer Documentation](/developer/webhook-ips).
These IP addresses apply to incident and event webhooks. They do not apply to [External Status Page](/incident-management/communicate/external-status-page) webhook subscriptions, which are sent from a separate system with unpublished source addresses.

## Manage V3 Webhook Subscriptions

You can manage V3 webhook subscriptions in two places:

- [On the Generic Webhooks Page](#add-a-v3-webhook-subscription-on-the-generic-webhooks-page)
- [On the Service Details Page](#add-a-v3-webhook-subscription-on-the-service-details-page)

> **Required User Permissions:** The following roles can manage V3 webhook subscriptions:
>
>   - Manager base role (for service-level and Team-level webhooks)
>   - Users with a Manager Team role (for service-level and Team-level webhooks associated with their Teams)
>   - Admin/Global Admin
>   - Account Owner
>
>   If you do not see **Integrations** in the top navigation bar due to your user role (for example, a Restricted Access user with a Manager Team role), manage V3 webhook subscriptions on the [Service Details Page](#add-a-v3-webhook-subscription-on-the-service-details-page).

> **Product Limit:** You can create up to 10 webhook subscriptions per unique service and [Team](/account-admin/teams) ID (for example, `PXXXXXX`), as well as for the account-level scope. Attempts to create additional webhook subscriptions generate an error: `Failed to create webhook. Webhook subscription limit exceeded for the selected scope.`
>
>   Read more about the **Product Limit Reached** error code (2019) in the developer documentation: [PagerDuty Error Codes](/developer/errors#pagerduty-error-codes).

### Add a V3 Webhook Subscription on the Generic Webhooks Page

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.

2. Click **New Webhook** and complete the following fields:

   | Field                        | Value                                                     |
   | :--------------------------- | :-------------------------------------------------------- |
   | **Webhook URL**              | Enter the webhook URL.                                    |
   | **Description** (optional)   | Enter an optional description.                            |
   | **Event Subscription**       | Select the event types you would like to subscribe to.    |
   | **Custom Header** (optional) | Enter a **Name** and **Value** to create a custom header. |

3. Click **Add Webhook**. A confirmation modal appears notifying you that the webhook has been created and supplies a secret if you would like to [verify webhook payloads](/developer/verifying-webhook-signatures).

### Edit a V3 Webhook Subscription on the Generic Webhooks Page

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.
2. Select the webhook's URL or select   →  **Manage**.
3. Click **Edit** and make the required changes.
4. Click **Save Changes**.

### Delete a V3 Webhook Subscription on the Generic Webhooks Page

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.
2. To the right of the webhook you would like to delete, select   →  **Delete**.
3. In the confirmation modal, click **Delete**.

### Add a V3 Webhook Subscription on the Service Details Page

1. Navigate to **Services**  →  **Service Directory** and select the service where you would like to add the webhook subscription.
2. Select the **Integrations** tab, scroll to the **Webhooks** section, and click **Add or manage webhooks for this service**.

> **No V3 Webhooks Found on this Service:** If this is the first webhook subscription on the service, you see **No V3 webhooks found on this service**. Click **Webhook** to manage webhook subscriptions on the service, then continue to step 3.

![Add a V3 webhook subscription on the service details page](/images/kb/6184f64fc720addf526d155d7ebd6c5abd5722b9f572ea7271d18a74bfe1c180-Webhook_subscriptions_on_the_service_details_page.webp)
*No V3 Webhooks Found on this Service*

3. Click **New Webhook** and complete the following fields:

   | Field                        | Value                                                     |
   | :--------------------------- | :-------------------------------------------------------- |
   | **Webhook URL**              | Enter the webhook URL.                                    |
   | **Description** (optional)   | Enter an optional description.                            |
   | **Event Subscription**       | Select the event types you would like to subscribe to.    |
   | **Custom Header** (optional) | Enter a **Name** and **Value** to create a custom header. |

4. Click **Add Webhook**. A confirmation modal appears notifying you that the webhook has been created and supplies a secret if you would like to [verify webhook payloads](/developer/verifying-webhook-signatures).

### Edit a V3 Webhook Subscription on the Service Details Page

1. Navigate to **Services**  →  **Service Directory** and select the service where you would like to edit the webhook subscription.
2. Select the **Integrations** tab, scroll to the **Webhooks** section, and click **Add or manage webhooks for this service**.
3. Select the webhook's URL or select   →  **Manage**.
4. Click **Edit** and make the required changes.
5. Click **Save Changes**.

### Delete a V3 Webhook Subscription on the Service Details Page

1. Navigate to **Services**  →  **Service Directory** and select the service where you would like to delete the webhook subscription.
2. Select the **Integrations** tab, scroll to the **Webhooks** section, and click **Add or manage webhooks for this service**.
3. To the right of the webhook you would like to delete, select   →  **Delete**.
4. In the confirmation modal, click **Delete**.

### Send a Test Event

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.
2. Select the webhook's URL or   →  **Manage**.
3. Under **Test**, click **Send Test Event**.
4. In the confirmation modal, click **Yes, Send Event**.

The following is an example of the test event payload:

```json
{
  "event": {
    "id": "01CH754SM17TWPE2V2H4VPBRO7",
    "event_type": "pagey.ping",
    "resource_type": "pagey",
    "occurred_at": "2021-12-08T22:58:53.510Z",
    "agent": null,
    "client": null,
    "data": {
      "message": "Hello from your friend Pagey!",
      "type": "ping"
    }
  }
}
```

## Supported Resources and Event Types

The following resources and event types are available with V3 webhooks. Additional event types may be added over time. Refer to the [Developer documentation](/developer/webhooks-overview#event-types) for more information.

### Incidents

| Event Type                    | Description                                                                           |
| :---------------------------- | :------------------------------------------------------------------------------------ |
| `acknowledged`                | Sent when an incident is acknowledged                                                 |
| `annotated`                   | Sent when a note is added to an incident                                              |
| `conference_bridge.updated`   | Sent when a conference bridge is updated                                              |
| `custom_field_values.updated` | Sent when custom field values are updated                                             |
| `delegated`                   | Sent when an incident has been reassigned to another escalation policy                |
| `escalated`                   | Sent when an incident has been escalated to another user in the same escalation level |
| `incident_type.changed`       | Sent when an incident has changed its incident type                                   |
| `priority_updated`            | Sent when the priority of an incident has changed                                     |
| `reassigned`                  | Sent when an incident has been reassigned to another user                             |
| `reopened`                    | Sent when an incident is reopened                                                     |
| `resolved`                    | Sent when an incident has been resolved                                               |
| `responder.added`             | Sent when a responder has been added to an incident                                   |
| `responder.replied`           | Sent when a responder replies to a request                                            |
| `service_updated`             | Sent when the service of an incident has changed                                      |
| `status_update_published`     | Sent when a status update is added to an incident                                     |
| `triggered`                   | Sent when an incident is newly created/triggered                                      |
| `unacknowledged`              | Sent when an incident is unacknowledged                                               |
| `workflow.completed`          | Sent when an Incident Workflow finishes                                               |
| `workflow.started`            | Sent when an Incident Workflow begins                                                 |

### Services

| Event Type                    | Description                                           |
| :---------------------------- | :---------------------------------------------------- |
| `created`                     | Sent when a service is created                        |
| `deleted`                     | Sent when a service is deleted                        |
| `updated`                     | Sent when a service is updated                        |
| `custom_field_values.updated` | Sent when a service's custom field values are updated |

## V3 Webhook Subscriptions versus V1/V2 Webhook Extensions

Conceptually, V3 webhook subscriptions and [V1/V2 generic webhook extensions](https://support.pagerduty.com/main/docs/v1v2-webhook-extensions)) are similar; however, there are some key differences:

- **V3 Webhook Subscription**: A subscription configured to send a webhook to an endpoint every time an event happens on an incident within a specific scope (team or service).
- **V1/V2 Generic Webhook Extension**: An endpoint configured to receive webhooks every time an incident is created, updated, or deleted.

### Key Differences

#### Payload

The final payload differs between V1/V2 and V3. The destination service of the webhook needs to be updated to handle the new payload.

- [V3 payload explanation](/developer/webhooks-overview#webhook-payload)
- [V2 payload explanation](/developer/webhooks-overview#webhook-payload)

##### Incident ID

In V3 webhooks, the incident ID is found in a different payload location than in earlier versions. Use the following code snippet to extract the incident ID:

```javascript
if event.data.type == "incident" {
  incident_id = event.data.id
} else {
  incident_id = event.data.incident.id
}
```

#### Custom Headers

You can add custom headers to V3 webhook subscriptions in the web app:

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.
2. Click **New Webhook** to create a new webhook subscription, or select an existing webhook and click **Edit**.
3. Under **Custom Headers**, click **Add custom header**.
4. Enter a **Name** and **Value** for your header.

> **Unique Header Names:** Each custom header must have a unique **Name** if you add more than one.

5. Click **Save Changes**. Custom header values are redacted after saving for security.

![Redacted custom header](/images/kb/8db535c55c73df67b875be4c184dcf865719e61f8e47e5c5dbfb70bf6c66c125-redacted_header.webp)
*Redacted Custom Header*

##### Delete a Custom Header

1. Navigate to **Integrations**  →  **Generic Webhooks (v3)**.
2. Select a webhook and click **Edit**.
3. Under **Custom Headers**, click  to the right of the custom header you want to delete.
4. Click **Save Changes**.

#### Request Headers

The `user-agent` header in the request displays which webhooks version was used: `PagerDuty-Webhook/V2.0` for V2 and `PagerDuty-Webhook/V3.0` for V3.

V3 webhook subscriptions also introduce two new headers: `x-webhook-subscription` and `x-pagerduty-signature`.

#### Version Comparison

V3 webhook subscriptions offer more event types than previous versions. Note that some event types have a slight name difference between versions — for example, `trigger` (V1 and V2) and `triggered` (V3).

| Resource | Event                            | V1 | V2 | V3 |
| :------- | :------------------------------- | :- | :- | :- |
| Incident | `trigger`/`triggered`            | ✓  | ✓  | ✓  |
|          | `acknowledge`/`acknowledged`     | ✓  | ✓  | ✓  |
|          | `unacknowledge`/`unacknowledged` | ✓  | ✓  | ✓  |
|          | `resolve`/`resolved`             | ✓  | ✓  | ✓  |
|          | `assign`                         | ✓  | ✓  | ✓  |
|          | `escalate`/`escalated`           | ✓  | ✓  | ✓  |
|          | `delegate`/`delegated`           | ✓  | ✓  | ✓  |
|          | `annotate`/`annotated`           |    | ✓  | ✓  |
|          | `priority_updated`               |    |    | ✓  |
|          | `reassigned`                     |    |    | ✓  |
|          | `reopened`                       |    |    | ✓  |
|          | `responder.added`                |    |    | ✓  |
|          | `responder.replied`              |    |    | ✓  |
|          | `status_update_published`        |    |    | ✓  |
|          | `conference_bridge.updated`      |    |    | ✓  |
|          | `custom_field_values.updated`    |    |    | ✓  |
|          | `workflow.completed`             |    |    | ✓  |
|          | `workflow.started`               |    |    | ✓  |
|          | `incident_type.changed`          |    |    | ✓  |
|          | `service_updated`                |    |    | ✓  |
| Service  | `created`                        |    |    | ✓  |
|          | `deleted`                        |    |    | ✓  |
|          | `updated`                        |    |    | ✓  |
|          | `custom_field_values.updated`    |    |    | ✓  |

## Migrate from V1/V2 Generic Extensions to V3 Webhook Subscriptions

There are two options to migrate to V3 webhook subscriptions:

- Follow the [Migration Guide](#migration-guide) below.
- Use the [migration script](https://github.com/PagerDuty/public-support-scripts/tree/master/migrate_webhooks_to_v3) (provided as is).

### Migration Guide

The following guide explains how to migrate existing V1/V2 generic webhook extensions to V3 webhook subscriptions. End-of-support for V2 webhooks began on October 31, 2022, and an end-of-life date is TBD. V1 webhook extensions became unsupported on November 13, 2021 and lost functionality in October 2022.

> **Required User Permissions:** - Admins and Account Owners can migrate an account's V1/V2 webhook extensions to V3 webhook subscriptions.
>   - Team Managers can migrate a subset of an account's V1/V2 webhook extensions to V3 webhook subscriptions based on their Team access.

#### Step 1: Generate an API Key

**Admins and Account Owners:**

1. Navigate to **Integrations**  →  **API Access Keys** and click **Create New API Key**.
2. Enter a **Description** to help you identify the key later. Check **Read-only** if you want to restrict the key to read-only access. Click **Create Key**.
3. Copy the generated API key to a secure location — this is the only time it is displayed in full. Click **Close**. If you lose the key, you must delete it and create a new one.

**Team Managers:**

> **Restrictions:** Team Managers can only migrate webhooks for the Teams they are assigned to. To migrate webhooks for an entire account, have an Admin or Account Owner perform the steps above.

1. Navigate to **User Icon**  →  **My Profile**  →  **User Settings**  →  **Create API User Token**.
2. Enter a **Description** to help you identify the key later.
3. Copy the generated user API key to a secure location — this is the only time it is displayed in full. Click **Close**. If you lose the key, you must delete it and create a new one.

#### Step 2: Get a List of Existing Webhooks

Get a list of existing V2 webhooks using the [extensions API endpoint](/developer/api/reference/rest/extensions/list-extensions). Set the `query` field in the request to `webhook` to filter by Generic Webhooks only. If the extension has a name other than Generic Webhook, use that name in the `query` field instead.

> **Team Managers:** Filter results by services belonging to your Team(s).

In this example, calling the `GET /extensions` endpoint returns a list containing a single extension:

```json
{
    "extensions": [
        {
            "endpoint_url": "https://example.com/webhooks_go_here",
            "name": "My Webhook",
            "config": {
                "headers": null,
                "referer": "https://subdomain.pagerduty.com/extensions"
            },
            "extension_schema": {
                "id": "PJFWPEP",
                "type": "extension_schema_reference",
                "summary": "Generic V2 Webhook",
                "self": "https://api.pagerduty.com/extension_schemas/PJFWPEP",
                "html_url": null
            },
            "extension_objects": [
                {
                    "id": "PYKHOXQ",
                    "type": "service_reference",
                    "summary": "My Application Service",
                    "self": "https://api.pagerduty.com/services/PYKHOXQ",
                    "html_url": "https://subdomain.pagerduty.com/service-directory/PYKHOXQ"
                }
            ],
            "id": "PUGLEKG",
            "type": "webhook",
            "summary": "My Webhook",
            "self": "https://api.pd-staging.com/webhooks/PUGLEKG",
            "html_url": null
        }
    ],
    "query": "webhook",
    "limit": 25,
    "offset": 0,
    "total": null,
    "more": false
}
```

#### Step 3: Note the Important Fields

For each `extension` in the `extensions` array returned in Step 2, take note of the `endpoint_url`, `name`, and `id`. To identify the service the extension is linked with, note the `id` and `type` inside the `extension_objects` array.

From the response in Step 2, take note of lines 4, 5, 19, 20, and 26.

#### Step 4: Decide on Event Types

V3 webhook subscriptions introduce a new way to refine subscriptions with event types. Before creating a new V3 webhook subscription, select the [event types](/developer/webhooks-overview#event-types) you want to receive.

> **Replicating V2 Behavior:** To receive the same data as a V2 generic webhook extension, all V3 event types must be added.

To replicate the existing behavior of the V2 generic webhook extension, use all available `event_types`:

```json
"incident.acknowledged"
"incident.annotated"
"incident.delegated"
"incident.escalated"
"incident.priority_updated"
"incident.reassigned"
"incident.reopened"
"incident.resolved"
"incident.responder.added"
"incident.responder.replied"
"incident.triggered"
"incident.unacknowledged"
```

#### Step 5: Create a New V3 Webhook Subscription

Using the [webhook subscriptions API endpoint](/developer/api/reference/rest/webhooks/create-webhook-subscription), create a new webhook subscription. The following table maps the V2 request fields to the V3 request fields:

| V2 Generic Webhook Extension | V3 Webhook Subscription |
| :--------------------------- | :---------------------- |
| `endpoint_url`               | `delivery_method.url`   |
| `name`                       | `description`           |
| `extension_objects.id`       | `filter.id`             |
| `extension_objects.type`     | `filter.type`           |

The new request to `POST /webhook_subscriptions` looks like the following:

```json
{
    "webhook_subscription": {
        "delivery_method": {
            "type": "http_delivery_method",
            "url": "https://example.com/webhooks_go_here"
        },
        "description": "My Webhook",
        "events": [
            "incident.acknowledged",
            "incident.annotated",
            "incident.delegated",
            "incident.escalated",
            "incident.priority_updated",
            "incident.reassigned",
            "incident.reopened",
            "incident.resolved",
            "incident.responder.added",
            "incident.responder.replied",
            "incident.triggered",
            "incident.unacknowledged"
        ],
        "filter": {
            "id": "PYKHOXQ",
            "type": "service_reference"
        },
        "type": "webhook_subscription"
    }
}
```

#### Step 6: Clean Up

A new V3 webhook subscription has been created to replicate the existing V1 or V2 generic webhook extension. Duplicate webhooks are sent as long as both V1/V2 and V3 subscriptions exist. Once you confirm that the new V3 webhook subscription is functional, [delete the old generic webhook extension](/developer/api/reference/rest/extensions/delete-extension) using the `id` found in Step 2.

From the example in Step 2, the old extension `id` is found on line 26.
