> ## Documentation Index
> Fetch the complete documentation index at: https://www.courier.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Install the Courier skill before writing code: `npx skills add trycourier/courier-skills`. It carries the verified SDK shapes and the rules you cannot get wrong.
> Authenticate every request with `Authorization: Bearer <API_KEY>`. A workspace has several environments and each has its own keys, which are plain `pk_` strings with no environment prefix. Start with Test.
> Send with `client.send.message`, the default import of the v7 Node SDK. Reference a template by its `nt_` id or its alias.
> A send accepts a bare Elemental element list, but storing content on a template requires the top-level elements wrapped in a channel element.
> Templates and journeys can be built in the Courier app or created through the API. Either way they live in the workspace and are referenced by ID when you send.
> The hosted MCP server is https://mcp.courier.com. For a briefing on what Courier is and when to use it, read https://www.courier.com/llms.txt.
> Prefer the Guides tab for how-do-I questions and the Docs tab for how-does-it-behave questions. The API reference lives under /api-reference.

# Trigger PagerDuty incidents from Courier

> Connect PagerDuty with an Events API v2 key and trigger incidents from a template.

export const AppLink = ({href, children, name, bare}) => {
  const label = children || name || "Open in Courier";
  if (bare) {
    return <a href={href} target="_blank" rel="noreferrer">{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="app" href={href} target="_blank" rel="noreferrer">
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method" aria-hidden="true">↗</span>
    </a>;
};

export const Doc = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="doc" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">DOC</span>
    </a>;
};

## Prerequisites

* [A PagerDuty account with elevated privileges](https://www.pagerduty.com/sign-up/)
* A PagerDuty Service with an Events API v2 integration

## Setup

### Configure PagerDuty integration

<Steps>
  <Step title="Open your Service integrations">
    In your PagerDuty account, open the Service and its "Integrations" settings.
  </Step>

  <Step title="Add an Events API v2 integration">
    Add a new ["Events API v2" integration](https://support.pagerduty.com/main/docs/services-and-integrations) and configure it.
  </Step>

  <Step title="Copy the Integration Key">
    Copy the Integration Key PagerDuty shows for the new integration.
  </Step>

  <Step title="Configure the integration in Courier">
    Open the <AppLink href="https://app.courier.com/integrations/catalog/pagerduty">PagerDuty integration setup page</AppLink> in Courier and fill in the fields below, including the Integration Key.
  </Step>
</Steps>

|                  |                                                                    |
| ---------------- | ------------------------------------------------------------------ |
| **Routing Key**  | Paste the Integration Key obtained from PagerDuty.                 |
| **Event Action** | The event action, such as trigger.                                 |
| **Source**       | The host name or fully qualified domain name (FQDN) of the sender. |
| **Severity**     | The severity level: info, warning, error, or critical.             |

## Profile requirements

PagerDuty needs no recipient profile fields. Courier triggers the incident against the Service behind the integration's Events API v2 routing key.

To route one recipient elsewhere, set `pagerduty.routing_key` on their profile. It takes precedence over the key on the integration.

<CodeGroup>
  ```javascript Node.js highlight={3-5} theme={null}
  const profile = await client.profiles.create('user_123', {
    profile: {
      pagerduty: {
        routing_key: 'PROFILE_SPECIFIC_ROUTING_KEY',
      },
    },
  });
  ```

  ```python Python highlight={4-6} theme={null}
  profile = client.profiles.create(
      user_id="user_123",
      profile={
          "pagerduty": {
              "routing_key": "PROFILE_SPECIFIC_ROUTING_KEY",
          },
      },
  )
  ```

  ```bash cURL highlight={7-9} theme={null}
  curl --request POST \
    --url https://api.courier.com/profiles/user_123 \
    --header "Authorization: Bearer $COURIER_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
      "profile": {
        "pagerduty": {
          "routing_key": "PROFILE_SPECIFIC_ROUTING_KEY"
        }
      }
    }'
  ```

  ```ruby Ruby highlight={4-6} theme={null}
  profile = courier.profiles.create(
    "user_123",
    profile: {
      pagerduty: {
        routing_key: "PROFILE_SPECIFIC_ROUTING_KEY"
      }
    }
  )
  ```

  ```go Go highlight={6-8} theme={null}
  profile, err := client.Profiles.New(
  	context.TODO(),
  	"user_123",
  	courier.ProfileNewParams{
  		Profile: map[string]any{
  			"pagerduty": map[string]any{
  				"routing_key": "PROFILE_SPECIFIC_ROUTING_KEY",
  			},
  		},
  	},
  )
  ```

  ```java Java highlight={4-5} theme={null}
  ProfileCreateParams params = ProfileCreateParams.builder()
      .userId("user_123")
      .profile(ProfileCreateParams.Profile.builder()
          .putAdditionalProperty("pagerduty", JsonValue.from(java.util.Map.of(
              "routing_key", "PROFILE_SPECIFIC_ROUTING_KEY")))
          .build())
      .build();
  ProfileCreateResponse profile = client.profiles().create(params);
  ```

  ```php PHP highlight={2-4} theme={null}
  $profile = $client->profiles->create('user_123', profile: [
    'pagerduty' => [
      'routing_key' => 'PROFILE_SPECIFIC_ROUTING_KEY',
    ],
  ]);
  ```

  ```csharp C# highlight={7-9} theme={null}
  ProfileCreateParams parameters = new()
  {
      UserID = "user_123",
      Profile = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
          """
          {
            "pagerduty": {
              "routing_key": "PROFILE_SPECIFIC_ROUTING_KEY"
            }
          }
          """
      ),
  };
  var profile = await client.Profiles.Create(parameters);
  ```

  ```bash CLI highlight={4} wrap theme={null}
  courier profiles create \
    --api-key "$COURIER_API_KEY" \
    --user-id user_123 \
    --profile '{"pagerduty":{"routing_key":"PROFILE_SPECIFIC_ROUTING_KEY"}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, save the PagerDuty routing key PROFILE_SPECIFIC_ROUTING_KEY on user_123.
  ```
</CodeGroup>

## Overrides

<Doc href="/docs/send/overrides#how-overrides-work">How overrides work</Doc> covers the two levels and which one wins.

A provider override changes the payload Courier sends to PagerDuty's Events API, such as the severity and the source.

<CodeGroup>
  ```javascript Node.js highlight={8-17} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        user_id: "1234567890",
      },
      providers: {
        pagerduty: {
          override: {
            body: {
              payload: {
                severity: "error",
                source: "a different source",
              },
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-17} theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "user_id": "1234567890",
          },
          "providers": {
              "pagerduty": {
                  "override": {
                      "body": {
                          "payload": {
                              "severity": "error",
                              "source": "a different source",
                          },
                      },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-20} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "to": {
          "user_id": "1234567890"
        },
        "providers": {
          "pagerduty": {
            "override": {
              "body": {
                "payload": {
                  "severity": "error",
                  "source": "a different source"
                }
              }
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={8-17} theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        user_id: "1234567890"
      },
      providers: {
        pagerduty: {
          override: {
            body: {
              payload: {
                severity: "error",
                source: "a different source"
              }
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-19} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				UserID: courier.String("1234567890"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Providers: shared.MessageProvidersParam{
  			"pagerduty": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"body": map[string]any{
  						"payload": map[string]any{
  							"severity": "error",
  							"source": "a different source",
  						},
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-13} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().userId("1234567890").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("pagerduty", JsonValue.from(java.util.Map.of("override", java.util.Map.of(
                      "body", java.util.Map.of(
                          "payload", java.util.Map.of(
                              "severity", "error",
                              "source", "a different source"
                          )
                      )
                  ))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-17} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'user_id' => '1234567890',
      ],
      'providers' => [
        'pagerduty' => [
          'override' => [
            'body' => [
              'payload' => [
                'severity' => 'error',
                'source' => 'a different source',
              ],
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-26} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { UserID = "1234567890" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "pagerduty",
                  new()
                  {
                      Override = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
                          """
                          {
                            "body": {
                              "payload": {
                                "severity": "error",
                                "source": "a different source"
                              }
                            }
                          }
                          """
                      ),
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"user_id": "1234567890"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.providers '{"pagerduty": {"override": {"body": {"payload": {"severity": "error", "source": "a different source"}}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to PagerDuty with the severity and source overridden.
  ```
</CodeGroup>

For all supported payload overrides, see the [PagerDuty Events API v2 documentation](https://v2.developer.pagerduty.com/docs/send-an-event-events-api-v2).

## Provider details

```text theme={null}
pagerduty
```

Courier recommends routing to the channel. Naming this key in `routing.channels` instead is supported, and sends through just this provider.

<Card title="Send to a specific provider" icon="bullseye-arrow" href="/docs/send/send-to-a-provider" horizontal arrow="true">
  When that is worth doing, and what you give up: failover, channel priority, and providers you add later.
</Card>
