PagerDuty
Pages become incidents, 3AM writes its diagnosis on the page, and on-call engineers approve fixes with a note.
PagerDuty does three jobs for 3AM. Open incidents on the services you choose become 3AM incidents. Once 3AM may act on a service, it writes its diagnosis as a note on the page that woke someone up. And it can ask for approvals: 3AM opens an incident on an approval service, and your approvers answer with a note saying approve or reject.
Before you start
- A PagerDuty user with the Admin or Account Owner role, to create an API key.
- The IDs of the services 3AM should watch.
- Outbound HTTPS from 3AM to
api.pagerduty.com(EU accounts:api.eu.pagerduty.com). PagerDuty never connects to 3AM.
1. Create a REST API key
Integrations → API Access Keys → Create New API Key, description 3AM. Leave Read-only API Key unticked:
3AM writes notes and approval incidents. Copy the key; PagerDuty shows it once.
You don't need an App or OAuth client. Add New App is for apps published to the PagerDuty marketplace.
2. Pick the user 3AM writes as
Notes and approval incidents appear under a PagerDuty user. Create a service user such as 3am@bank.example
(People → Users → Add Users) or reuse one. You'll enter its e-mail as from_email.
3. Find the service IDs
A service's ID is in its URL: https://<you>.pagerduty.com/service-directory/PXXXXXX. Leave the list empty to watch
every service.
4. Create an approval service (optional)
Only if PagerDuty should carry approvals. Services → Service Directory → New Service:
- Name:
3AM approvals. - Escalation policy: one that reaches the people who may approve 3AM's changes.
- Integrations: none. Only 3AM creates incidents here.
Note its ID for service_id.
5. Add the connector
In the console: Connections → Add a connection → PagerDuty. Or in connectors.json:
{ "name": "pagerduty", "kind": "pagerduty",
"settings": { "api_token": { "file": "/etc/3am/secrets/pagerduty-token" },
"from_email": "3am@bank.example",
"watch_services": ["P7B0Q8Q", "P3KD92L"],
"service_id": "P5ZUI27",
"approvers": ["anna.k@bank.example", "raj.s@bank.example"] } }kind: pagerdutyalerts inapprovals| Setting | What to enter | Required | Default |
|---|---|---|---|
api_url | REST API base URL (EU: https://api.eu.pagerduty.com) | yes | "https://api.pagerduty.com" |
api_tokensecret | REST API key | yes | — |
from_email | E-mail of the PagerDuty user 3AM acts as | yes | — |
watch_services | Service IDs whose pages 3AM handles (empty: every service) | no | — |
service_id | Service for approval incidents (optional: approvals off without it) | no | — |
approvers | E-mails of users allowed to approve | no | — |
6. Verify
Test connection authenticates, then looks up the user and each service:
Connected. authenticated; 3AM approvals (approvals); core-banking-dbThen send a test page to a watched service through its Events API v2 integration (the integration key is on the service's Integrations tab):
curl -s https://events.pagerduty.com/v2/enqueue -H 'Content-Type: application/json' -d '{
"routing_key": "<integration key>", "event_action": "trigger", "dedup_key": "3am-test-1",
"payload": {"summary": "MySQLReadOnly core-banking-db (3AM test)", "source": "db-1", "severity": "critical",
"custom_details": {"alertname": "MySQLReadOnly", "service": "core-banking-db"}}}'Within one poll interval (15 seconds by default) the console shows an incident for MySQLReadOnly. Resolve the test
page by sending the same request with "event_action": "resolve".
How it behaves
Pages in
- Triggered and acknowledged incidents on the watched services. 3AM's own approval incidents are never read as pages.
- One PagerDuty incident is one signal, even when alert grouping puts several alerts in it. The first alert's dedup
key is kept as the
dedup_keylabel. - Severity comes from the priority (P1–P2 critical, P3–P4 warning, P5 info), otherwise from urgency.
- The alert name and labels come from the integration that raised the page (Alertmanager, Datadog, …).
Notes out
- Written only when 3AM may act on the service. In shadow mode nothing in PagerDuty changes.
Approvals
- Each request opens an incident with a dedup key, so a retry can't open a duplicate.
- High-risk requests ask for high urgency. Services with dynamic notifications decide urgency themselves.
- A note saying approve or reject from someone in
approversis a decision. PagerDuty notes carry the author's name, so 3AM looks up their e-mail. - Two approvers on the same incident make a quorum of two.
- When the request closes, 3AM adds a final note and resolves the approval incident.
Rate limits
- On
429, 3AM waits as long as PagerDuty asks. On5xxit backs off and retries. It never retries authentication or validation errors.
Troubleshooting
the API key is wrong or revoked
Create a new key (step 1) and paste it again.
the key lacks permission
The key is read-only. Create one with Read-only API Key unticked.
no PagerDuty user with e-mail …
from_email doesn't match a user. Check People → Users.
service not found
A service ID is wrong. Copy it from the service's URL.
Pages don't appear
The service isn't in watch_services, or the page was already open when 3AM started. Alerts already firing at start
are treated as known, and they count again once they re-fire.
Approvals aren't counted
The note's author isn't in approvers (compare e-mails), or the note doesn't contain approve or reject.
Certification
Live against a real PagerDuty account (2026-10-04): 16 live checks and 15 contract checks.
- A page raised through Events API v2 arrived with its alert name and labels.
- 3AM's note landed on the incident.
- An approval made by a second user was attributed to that user's e-mail, and the request was closed.
Alert webhooks (any SIEM)
Push alerts to 3AM from any monitoring tool or SIEM with one webhook (Alertmanager, Grafana, Datadog, Splunk, PagerDuty, Azure Monitor and Sentinel, Elastic and OpenSearch, or generic JSON), no connector needed.
Kubernetes
Pod and rollout failures as incidents, the cause read from the cluster, and approved rollbacks, restarts and volume growth.