Skip to main content

PagerDuty Integration Guide

Last updated on

Configure PagerDuty to send webhook notifications to Harness AI SRE when incidents are created, updated, or resolved.

Before you begin

  • Harness webhook endpoint: Create a PagerDuty webhook in Harness AI SRE using the PagerDuty webhook template.
  • PagerDuty permissions: Admin or Account Owner role (for V3 webhooks) or Service permissions (for extensions).
  • Webhook URL: Copy the webhook URL from your Harness webhook configuration.
  • PagerDuty V3 webhooks documentation: Go to PagerDuty V3 Webhooks Overview to understand V3 webhook capabilities and event types.
  • Webhook extensions documentation: Go to PagerDuty Webhooks for legacy webhook extension setup.

Choose webhook type

PagerDuty offers two webhook mechanisms:

TypeScopeUse CaseFlexibility
V3 Webhooks (Recommended)Account, team, or serviceEnterprise-wide incident synchronizationHigh (supports filtering, custom headers)
Webhook Extensions (Legacy)Service-levelSimple service-specific integrationLimited

Go to Configure V3 webhooks to use the recommended approach.

Go to Configure webhook extensions to use the legacy method.


Configure V3 webhooks

V3 webhooks are the recommended approach for modern PagerDuty integrations.

Create a V3 webhook

Start a new V3 webhook in PagerDuty:

  1. In PagerDuty, navigate to Integrations, then select Generic Webhooks (v3)
  2. Click New Webhook

Configure webhook settings

Configure these fields:

  • Webhook URL: Your Harness webhook URL
    https://<your-harness-instance>/gateway/ai-sre/api/webhooks/<webhook-id>
  • Scope Type: Select the scope
    • Account: All incidents across the account
    • Team: Incidents for specific teams
    • Service: Incidents for specific services
  • Description: Harness AI SRE Integration

Configure custom headers

Add custom headers if your Harness webhook requires authentication:

Content-Type: application/json
X-Webhook-Secret: your-secret-key

Select event subscriptions

Choose which incident events trigger the webhook:

Select all event types:

  • incident.triggered
  • incident.acknowledged
  • incident.escalated
  • incident.resolved
  • incident.reassigned
  • incident.annotated
  • incident.priority_updated
  • incident.reopened
  • incident.delegated
  • incident.unacknowledged
  • incident.responder.added
  • incident.responder.replied
  • incident.status_update_published

Configure event filters

Add filters to control when the webhook fires:

  • Service: Select specific services or "All"
  • Urgency: High, low, or both
  • Priority: Filter by incident priority (P1-P5)

Save the webhook

Click Save to create the V3 webhook.


Configure webhook extensions (legacy)

Webhook extensions are simpler but less flexible than V3 webhooks.

Add webhook extension to service

Add a generic webhook integration to the service:

  1. Navigate to Services, then select your service
  2. Select the Integrations tab
  3. Click Add Integration
  4. Select Generic Webhook

Configure the extension

Set the extension name, URL, and description:

  • Name: Harness AI SRE
  • URL: Your Harness webhook URL
  • Description: Send incidents to Harness AI SRE

Save the extension

Click Add Integration to save.


Configure field mapping in Harness

In your Harness webhook configuration, map the PagerDuty payload fields to alert properties.

PagerDuty V3 webhook payload structure

V3 webhooks send a standardized payload:

{
"event": {
"id": "...",
"event_type": "incident.triggered",
"occurred_at": "2025-07-01T10:30:00Z",
"agent": {
"type": "user",
"summary": "John Doe"
},
"data": {
"id": "PXXXXXX",
"incident_number": 123,
"title": "High CPU on prod-server-01",
"status": "triggered",
"urgency": "high",
"priority": {
"summary": "P1"
},
"service": {
"id": "PXXXXXX",
"summary": "API Service"
},
"assignments": [
{
"assignee": {
"summary": "Jane Smith"
}
}
],
"created_at": "2025-07-01T10:30:00Z",
"html_url": "https://company.pagerduty.com/incidents/PXXXXXX"
}
}
}

Map basic fields

Use Mustache templates for simple mapping:

title: "{{webhook.event.data.title}}"
message: "PagerDuty incident #{{webhook.event.data.incident_number}}: {{webhook.event.data.title}}"
severity: "{{webhook.event.data.urgency}}"
source: "pagerduty"
link: "{{webhook.event.data.html_url}}"
tags:
- "incident_id:{{webhook.event.data.id}}"
- "service:{{webhook.event.data.service.summary}}"
- "status:{{webhook.event.data.status}}"

Advanced field mapping with CEL

Use CEL for conditional logic and nested field access:

// Extract nested fields and transform values
title: webhook.event.data.title
message: "PagerDuty " + webhook.event.event_type + ": " + webhook.event.data.title +
" (Incident #" + string(webhook.event.data.incident_number) + ")"

// Map PagerDuty urgency to Harness severity
severity: webhook.event.data.urgency == "high" ? "critical" : "medium"

// Extract assignee if present
assignee: has(webhook.event.data.assignments) &&
size(webhook.event.data.assignments) > 0
? webhook.event.data.assignments[0].assignee.summary
: "unassigned"

source: "pagerduty"
link: webhook.event.data.html_url

tags: [
"incident_id:" + webhook.event.data.id,
"service:" + webhook.event.data.service.summary,
"status:" + webhook.event.data.status,
"priority:" + (has(webhook.event.data.priority) ? webhook.event.data.priority.summary : "none")
]

// Filter: only process triggered and escalated incidents
filter: webhook.event.event_type in ["incident.triggered", "incident.escalated"]

Test the integration

Test V3 webhook

Send a test event from the V3 webhook:

  1. In PagerDuty, go to Integrations, then select Generic Webhooks (v3)
  2. Find your webhook and click Test Webhook
  3. Select a test scenario
  4. Click Send Test

Test webhook extension

Trigger a test incident on the integrated service:

  1. Create a test incident in the integrated service
  2. Verify the webhook fires (check service integration logs)

Verify in Harness

Confirm the incident arrived and mapped correctly:

  1. Navigate to Alerts in Harness AI SRE
  2. Check that the test alert appears
  3. Verify field mapping:
    • Alert title matches incident title
    • Severity is mapped correctly
    • Tags include incident metadata
    • Link navigates to PagerDuty incident

Available PagerDuty event types

V3 webhooks support these incident event types:

Event TypeDescriptionWhen to Use
incident.triggeredNew incident createdInitial alert processing and investigation
incident.acknowledgedIncident acknowledged by responderUpdate alert status, notify team
incident.escalatedIncident escalated to next levelIncrease priority, involve specialists
incident.resolvedIncident marked as resolvedClose alert, trigger post-incident analysis
incident.reassignedIncident reassigned to different responderUpdate assignee, transfer context
incident.annotatedNote added to incidentProcess additional context
incident.priority_updatedIncident priority changedAdjust alert severity
incident.reopenedResolved incident reopenedReopen alert, resume investigation
incident.delegatedIncident delegated to another escalation policyUpdate ownership, notify new team
incident.unacknowledgedIncident automatically unacknowledged after timeoutRe-trigger alert notification
incident.responder.addedResponder added to incidentUpdate assignee list, notify responder
incident.responder.repliedResponder replied to a responder requestLog responder response
incident.status_update_publishedStatus update posted to incidentSync status notes to alert

Advanced configuration

Route by event type

Create separate Harness webhooks for different incident events:

PagerDuty webhook 1:

  • Event types: incident.triggered
  • Harness webhook: wh_new_incidents

Harness field mapping:

title: "🚨 " + webhook.event.data.title
severity: "critical"
filter: webhook.event.event_type == "incident.triggered"

Filter by service

Use CEL to filter incidents from specific services:

// Only process incidents from production services
filter: has(webhook.event.data.service) &&
webhook.event.data.service.summary.contains("Production")

Filter by urgency

Process only high-urgency incidents:

// Only process high-urgency incidents
filter: webhook.event.data.urgency == "high"

Enrich with custom fields

Add custom context to help Harness AI agent investigation:

title: webhook.event.data.title
message: |
PagerDuty Incident #{{webhook.event.data.incident_number}}

Status: {{webhook.event.data.status}}
Urgency: {{webhook.event.data.urgency}}
Service: {{webhook.event.data.service.summary}}
Assigned To: {{assignee}}

Investigate this incident and correlate with recent deployments.
severity: webhook.event.data.urgency == "high" ? "critical" : "medium"
link: webhook.event.data.html_url
custom_fields: {
"incident_id": webhook.event.data.id,
"incident_number": string(webhook.event.data.incident_number),
"pagerduty_status": webhook.event.data.status,
"service_id": webhook.event.data.service.id
}

Troubleshooting

PagerDuty webhook is not receiving events for Harness AI SRE

Verify the webhook subscription includes the event types you need, check that the webhook scope covers the services you want to monitor, review the PagerDuty Webhook Logs, and ensure incidents are being created in the scoped services.

PagerDuty webhook payload fields are null or missing in Harness AI SRE

PagerDuty payload structure varies by event type. Use the CEL has() function to check whether fields exist before accessing them, check the PagerDuty webhook test payload for actual values, and note that webhook extension payloads differ from V3.

PagerDuty webhook has a high failure rate to Harness AI SRE

Check the Harness webhook logs for error messages, verify the field mapping CEL expressions are syntactically valid, test CEL expressions in the Harness CEL playground, ensure the Harness webhook is enabled, and review the PagerDuty retry logs.

PagerDuty is creating duplicate alerts in Harness AI SRE

Use Harness alert routing rules to deduplicate by the incident_id tag, filter in CEL to process only specific event types, and create separate Harness webhooks for different event types.


Example: complete integration

This example shows a production-ready PagerDuty-to-Harness integration for incident synchronization.

PagerDuty V3 webhook configuration

Configure the V3 webhook with these settings:

  • Scope: Account (all services)
  • Event types: incident.triggered, incident.escalated, incident.resolved
  • Filters:
    • Urgency: High only
    • Services: All

Map fields in the Harness webhook

title: |
webhook.event.event_type == "incident.triggered" ? "🚨 New Incident: " :
webhook.event.event_type == "incident.escalated" ? "⚠️ Escalated: " :
webhook.event.event_type == "incident.resolved" ? "✅ Resolved: " :
""
+ webhook.event.data.title

message: |
PagerDuty Incident #{{webhook.event.data.incident_number}}

Event: {{webhook.event.event_type}}
Status: {{webhook.event.data.status}}
Urgency: {{webhook.event.data.urgency}}
Priority: {{webhook.event.data.priority.summary}}
Service: {{webhook.event.data.service.summary}}
Assigned To: {{assignee}}

Created: {{webhook.event.data.created_at}}
Link: {{webhook.event.data.html_url}}

severity: |
webhook.event.data.urgency == "high" ? "critical" : "medium"

source: "pagerduty"
link: "{{webhook.event.data.html_url}}"

tags:
- "source:pagerduty"
- "incident_id:{{webhook.event.data.id}}"
- "incident_number:{{webhook.event.data.incident_number}}"
- "service:{{webhook.event.data.service.summary}}"
- "status:{{webhook.event.data.status}}"
- "urgency:{{webhook.event.data.urgency}}"
- "priority:{{webhook.event.data.priority.summary}}"
- "event_type:{{webhook.event.event_type}}"

filter: |
webhook.event.event_type in ["incident.triggered", "incident.escalated", "incident.resolved"] &&
webhook.event.data.urgency == "high"

custom_fields:
incident_id: "{{webhook.event.data.id}}"
incident_number: "{{webhook.event.data.incident_number}}"
pagerduty_status: "{{webhook.event.data.status}}"
service_id: "{{webhook.event.data.service.id}}"
assignee: "{{assignee}}"

CEL helper for assignee

assignee: has(webhook.event.data.assignments) &&
size(webhook.event.data.assignments) > 0
? webhook.event.data.assignments[0].assignee.summary
: "unassigned"

Next steps


PagerDuty official documentation