Skip to main content

Configure PagerDuty to Send Webhooks

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 V3 Webhooks for the recommended approach.

Go to Webhook Extensions for the legacy method.


Configure V3 webhooks

V3 webhooks are the recommended approach for modern PagerDuty integrations.

Create a V3 webhook

  1. In PagerDuty, navigate to IntegrationsGeneric 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

  1. Navigate to Services → Select your service
  2. Go to the Integrations tab
  3. Click Add Integration
  4. Select Generic Webhook

Configure the extension

  • 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"
}
}
}

Basic field mapping

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

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

Test webhook extension

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

Verify in Harness

  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

Webhook not receiving events

Cause: PagerDuty webhook not subscribed to events or scope is incorrect.

Solution:

  • Verify webhook subscription includes the event types you need
  • Check that webhook scope covers the services you want to monitor
  • Review PagerDuty Webhook Logs under webhook configuration
  • Ensure incidents are actually being created in the scoped services

Payload fields are null or missing

Cause: PagerDuty payload structure varies by event type, and not all fields are always populated.

Solution:

  • Use CEL has() to check if fields exist before accessing them:
assignee: has(webhook.event.data.assignments) &&
size(webhook.event.data.assignments) > 0
? webhook.event.data.assignments[0].assignee.summary
: "unassigned"
  • Check PagerDuty webhook test payload to see actual field values
  • For webhook extensions, note that payload structure differs from V3

High webhook failure rate

Cause: Harness webhook timeout or errors processing payload.

Solution:

  • Check Harness webhook logs for error messages
  • Verify field mapping CEL expressions are syntactically valid
  • Test CEL expressions in Harness CEL playground
  • Ensure Harness webhook is enabled and accessible
  • Review PagerDuty retry logs (V3 webhooks retry automatically on 5xx errors)

Duplicate alerts in Harness

Cause: Multiple PagerDuty webhooks or event types triggering the same Harness webhook.

Solution:

  • Use Harness alert routing rules to deduplicate by incident_id tag
  • Filter in CEL to process only specific event types:
filter: webhook.event.event_type == "incident.triggered"
  • 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

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

Harness webhook field mapping

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

  • Go to Route Alerts to route and deduplicate PagerDuty incidents.
  • Go to Use CEL in Webhooks to add advanced filtering and transformation logic.
  • Go to AI Agent to enable automated incident investigation.

Further reading

PagerDuty Official Documentation