Corsair
PluginsPagerDuty

PagerDuty

Integrate PagerDuty incidents, alerts, and on-call management

Quick Start

Install the plugin:

pnpm install @corsair-dev/pagerduty

Add the PagerDuty plugin to your Corsair instance:

corsair.ts
import { createCorsair } from "corsair";
import { pagerduty } from "@corsair-dev/pagerduty";

export const corsair = createCorsair({
    plugins: [
        pagerduty(),
    ],
});

Once configured, you can access the PagerDuty API:

// Create an incident
await corsair.pagerduty.api.incidents.create({
    title: "Production database is down",
    serviceId: "SERVICE123",
    urgency: "high",
});

Authentication

Supported Auth Types

The PagerDuty plugin supports:

  • api_key (default) - Use a PagerDuty API key

Default Auth Type

If no authType is specified, the plugin defaults to api_key.

Configuring API Key Authentication

Store credentials with the CLI:

pnpm corsair setup --pagerduty api_key=your-api-key

For webhook signature verification:

pnpm corsair setup --pagerduty webhook_signature=your-webhook-secret

Alternatively, provide credentials directly in the config:

corsair.ts
pagerduty({
    key: process.env.PAGERDUTY_API_KEY,
    webhookSecret: process.env.PAGERDUTY_WEBHOOK_SECRET,
})

See Authentication for details on managing credentials.

Options

OptionTypeDescription
authType'api_key'Authentication method (defaults to 'api_key')
keystringAPI key (optional, uses database if not provided)
webhookSecretstringWebhook secret for signature verification
hooksobjectEndpoint hooks for custom logic
webhookHooksobjectWebhook hooks for event handling
errorHandlersobjectCustom error handlers
permissionsobjectPermission configuration for AI agent access

Hooks

pagerduty({
    hooks: {
        incidents: {
            create: {
                before: async (ctx, input) => {
                    console.log("Creating incident:", input.title);
                    return { ctx, input };
                },
            },
        },
    },
})

See Hooks for complete documentation.

Error Handling

The plugin includes built-in error handlers for common scenarios. For complete documentation, see the Error Handlers reference.

Usage

Accessing the API

// List open incidents
const incidents = await corsair.pagerduty.api.incidents.list({
    statuses: ["triggered", "acknowledged"],
});

// Acknowledge an incident
await corsair.pagerduty.api.incidents.update({
    id: "INC123",
    status: "acknowledged",
    from: "engineer@example.com",
});

// Add a note to an incident
await corsair.pagerduty.api.incidentNotes.create({
    incidentId: "INC123",
    content: "Investigating the issue...",
    from: "engineer@example.com",
});

See API Endpoints for the complete reference.

Webhooks

PagerDuty sends incident events to your webhook endpoint:

app/api/webhook/route.ts
import { processWebhook } from "corsair";
import { corsair } from "@/server/corsair";

export async function POST(request: Request) {
    const headers = Object.fromEntries(request.headers);
    const body = await request.json();

    const result = await processWebhook(corsair, headers, body);
    return result.response;
}

See Webhooks for all available events.

Database Access

const incidents = await corsair.pagerduty.db.incidents.search({
    data: { status: "triggered" },
});

See Database for the complete schema.

Multi-Tenancy

const tenant = corsair.withTenant("org-123");

await tenant.pagerduty.api.incidents.create({
    title: "Service outage",
    serviceId: "SERVICE123",
    urgency: "high",
});

Examples

Example 1: Auto-acknowledge Incidents from Known Alerts

corsair.ts
import { inngest } from "./inngest";

export const corsair = createCorsair({
    plugins: [
        pagerduty({
            webhookHooks: {
                incidents: {
                    triggered: {
                        after: async (ctx, result) => {
                            await inngest.send({ 
                                name: "pagerduty/incident-triggered", 
                                data: { 
                                    tenantId: ctx.tenantId, 
                                    incidentId: result.data.event?.data?.id, 
                                    title: result.data.event?.data?.title, 
                                }, 
                            }); 
                        },
                    },
                },
            },
        }),
    ],
});
inngest/functions.ts
export const handleIncident = inngest.createFunction(
    { id: "handle-pagerduty-incident" },
    { event: "pagerduty/incident-triggered" },
    async ({ event }) => {
        const tenant = corsair.withTenant(event.data.tenantId);

        await tenant.pagerduty.api.incidentNotes.create({
            incidentId: event.data.incidentId,
            content: "Automated triage started.", 
            from: "automation@example.com",
        });
    }
);

Example 2: Notify Slack on Incident Resolution

corsair.ts
export const corsair = createCorsair({
    plugins: [
        pagerduty({
            webhookHooks: {
                incidents: {
                    resolved: {
                        after: async (ctx, result) => {
                            await inngest.send({
                                name: "pagerduty/incident-resolved",
                                data: {
                                    tenantId: ctx.tenantId,
                                    incidentId: result.data.event?.data?.id,
                                    title: result.data.event?.data?.title,
                                },
                            });
                        },
                    },
                },
            },
        }),
        slack(),
    ],
});
inngest/functions.ts
export const notifyOnResolution = inngest.createFunction(
    { id: "notify-incident-resolved" },
    { event: "pagerduty/incident-resolved" },
    async ({ event }) => {
        const tenant = corsair.withTenant(event.data.tenantId);

        await tenant.slack.api.messages.post({
            channel: "C_INCIDENTS",
            text: `✅ Incident resolved: ${event.data.title}`, 
        });
    }
);