The PagerDuty Events API v2 format, explained

Learn the PagerDuty Events API v2 format. See required fields, dedup_key logic, and a curl example for triggers and resolves.

Published 14 November 2026.

The PagerDuty Events API v2 is an asynchronous HTTP API. It takes machine events from monitoring tools and routes them to a PagerDuty service (Events API v2 overview). Prometheus Alertmanager sends this format when you set routing_key in a pagerduty_config (Alertmanager configuration). Some other alert receivers accept the same JSON. Every field and limit below comes from PagerDuty's developer documentation.

Endpoints and keys

The API exposes two endpoints, one for each event type:

Event typeEndpointNotifies anyone?
Alerthttps://events.pagerduty.com/v2/enqueueYes
Changehttps://events.pagerduty.com/v2/change/enqueueNo

Send a POST request with a JSON body to either endpoint. The routing_key field in that body directs the event. Use the 32-character integration key from an Events API v2 integration on a service, or from a global ruleset (Sending an alert event). Ruleset keys start with R and reject change events (overview). Store the key securely. Anyone with access to it can trigger alerts on that service.

The top-level fields

FieldRequiredNotes
routing_keyYesThe 32-character integration key
event_actionYestrigger, acknowledge or resolve
dedup_keyFor acknowledge and resolveUp to 255 characters. Identifies the alert
payloadFor triggerThe event details, below
clientNoName of the sending tool. Trigger only
client_urlNoLink back to the sending tool. Trigger only
linksNoArray of { "href", "text" }. href is required
imagesNoArray of { "src", "href", "alt" }. src is required and must be HTTPS

You can find the full specification in the Sending an alert event guide and the API reference.

The payload fields

The payload object follows the PagerDuty Common Event Format, PD-CEF (overview).

FieldRequiredNotesExample
summaryYesBecomes the alert title. Up to 1024 charactersDISK at 99% on machine prod-datapipe03.example.com
sourceYesThe affected system, preferably a hostname or FQDNprod-datapipe03.example.com
severityYesOne of critical, error, warning, infocritical
timestampNoISO 8601. PagerDuty fills it in if missing2015-07-17T08:42:58.315+0000
componentNoThe broken part of the sourcemysql
groupNoA cluster or grouping of sourcesprod-datapipe
classNoThe class or type of eventdisk
custom_detailsNoFree-form object{"free space": "1%"}

The on-call person sees summary first, whether on a lock screen or in an SMS. State what is wrong, where it is, and how bad it is. See writing alert messages people can act on. Use the four severity values deliberately. The format allows no others, so map your own severity levels to them.

How dedup_key works

The dedup_key ties a trigger to its follow-up acknowledge and resolve events (Sending an alert event):

  • A trigger with a dedup_key that matches an open alert adds a log entry to that alert. It does not open a second one.
  • A trigger with no dedup_key always opens a new alert. PagerDuty generates a UUID and returns it in the response.
  • Acknowledge and resolve events apply only to an open alert with the same dedup_key, sent with the same routing_key. Otherwise they are dropped. They never create an alert.
  • After an alert is resolved, a new trigger with the same key opens a new alert. It does not reopen the old one.

The sensible default is to set the key yourself from stable values like service, environment, and check name. A repeat trigger then folds into the open alert, and the resolve finds it without you storing state. See alert deduplication and grouping for more.

A worked example: trigger, then resolve

This example triggers an alert for a high error rate. The script reads the integration key from an environment variable. This practice keeps the key out of shell history and scripts. The host names and values in the example are illustrative.

curl -sS -X POST https://events.pagerduty.com/v2/enqueue \
  -H 'Content-Type: application/json' \
  -d '{
  "routing_key": "'"$PD_ROUTING_KEY"'",
  "event_action": "trigger",
  "dedup_key": "checkout-api/prod/high-error-rate",
  "payload": {
    "summary": "checkout-api prod: 5xx rate 7.2% (threshold 2%) for 10m",
    "source": "checkout-api.prod.example.com",
    "severity": "critical",
    "timestamp": "2026-11-14T09:30:00.000+0000",
    "component": "checkout-api",
    "group": "prod-eu-west-1",
    "class": "high error rate",
    "custom_details": {
      "error_rate": "7.2%",
      "threshold": "2%",
      "runbook": "https://runbooks.example.com/checkout-api/high-error-rate"
    }
  },
  "client": "Example Monitoring",
  "client_url": "https://monitoring.example.com",
  "links": [
    {
      "href": "https://grafana.example.com/d/checkout",
      "text": "Checkout dashboard"
    }
  ]
}'

A 202 response returns a JSON body like this (API reference):

{
  "status": "success",
  "message": "Event processed",
  "dedup_key": "checkout-api/prod/high-error-rate"
}

When the error rate recovers, send a resolve event with the same dedup_key. You do not need a payload for this request:

curl -sS -X POST https://events.pagerduty.com/v2/enqueue \
  -H 'Content-Type: application/json' \
  -d '{
  "routing_key": "'"$PD_ROUTING_KEY"'",
  "event_action": "resolve",
  "dedup_key": "checkout-api/prod/high-error-rate"
}'

An acknowledge event has the same structure, but uses "event_action": "acknowledge". PagerDuty sends no further notifications while an incident is acknowledged, even if new triggers arrive.

Responses, limits and retries

ResponseMeaningRetry?
202AcceptedNo
400Bad request. Check the JSON is validNo
429Too many API callsYes, after a while
500 or other 5xxPagerDuty server errorYes, after a while
Network errorCould not reach PagerDutyYes, after a while

Source: overview, response codes. Error bodies carry status, message and an errors array.

Limits:

  • The payload size limit is 512 KB (overview).
  • Each integration key allows about 120 calls per minute, measured over a rolling 60-second window. Account-level limits also apply. Exceeding the limit returns 429 and drops the event (rate limits).
  • PagerDuty adjusts throttling based on traffic volume. It recommends retrying up to 3 times with 30-second intervals. For events that must not be lost, use a backoff of a few minutes.

The API is asynchronous, so a 202 status means the event was accepted, not that it reached a person. Notification delivery depends on the service configuration, the escalation policy, and individual contact rules.

Change events

Change events record deployments or config changes. They appear on the service and incident timeline. They never trigger notifications (Sending a change event).

The body requires routing_key and a payload with a summary (max 1024 characters). Optional fields include source, timestamp, custom_details, and links. The format excludes event_action and dedup_key. PagerDuty retains change events for 90 days.

{
  "routing_key": "samplekeyhere",
  "payload": {
    "summary": "Build Success: Increase snapshot create timeout to 30 seconds",
    "timestamp": "2020-07-17T08:42:58.315+0000",
    "source": "acme-build-pipeline-tool-default-i-9999",
    "custom_details": {
      "build_state": "passed",
      "build_number": "2",
      "run_time": "1236s"
    }
  },
  "links": [
    {
      "href": "https://acme.pagerduty.dev/build/2",
      "text": "View more details in Acme!"
    }
  ]
}

That example is copied from PagerDuty's docs.

How Alertmanager fills these fields

This minimal Alertmanager receiver sends Events API v2 events:

receivers:
  - name: pagerduty-critical
    pagerduty_configs:
      - routing_key_file: /etc/alertmanager/secrets/pd-routing-key
        severity: '{{ if .CommonLabels.severity }}{{ .CommonLabels.severity }}{{ else }}error{{ end }}'
        links:
          - href: '{{ .CommonAnnotations.runbook_url }}'
            text: Runbook

The mapping between Alertmanager fields and the PagerDuty format comes from the configuration reference and the notifier source:

  • Use routing_key or routing_key_file to select Events API v2. The service_key field targets the older Prometheus integration.
  • send_resolved is true by default. Alertmanager sends a resolve event when a group resolves.
  • severity defaults to error. The template in the example passes the alert's severity label directly, so that label must contain one of the four PagerDuty values.
  • The description field maps to summary. Alertmanager truncates it to 1024 characters.
  • dedup_key is a hash of the alert group key. Each Alertmanager group becomes one PagerDuty alert, so group_by controls how alerts merge. See Alertmanager routing.
  • details defaults to the firing and resolved alerts as JSON, along with their counts.

The receiver above passes amtool check-config (Alertmanager v0.35.0) when included in a config that also defines a route.

Tools

The directory categorizes event senders and receivers into alert routing and notification delivery and on-call and escalation. Test any new receiver that claims PagerDuty compatibility by sending a trigger and a resolve with the same dedup_key before you switch.