PagerDuty Sensor
What it ingests
Incidents, services, and on-call shifts from PagerDuty REST API v2:
| PagerDuty object | Ontology entity | Signal |
|---|---|---|
| Service | Project | service |
| Incident | Issue | incident |
| On-call shift | Event | oncall |
A service is a body of work (the Jira project analog); an incident is the ticket. Assignees and on-call users are identity — they resolve to Person via name, the same contract as a HubSpot contact. Each object kind has its own signal, so you can disable a noisy stream (on-calls, typically) from the source's bindings without disabling the source.
This is PagerDuty alone. OpsGenie is a different product with a different API and stays a coming-soon catalog entry.
Read-only and poll-based against https://api.pagerduty.com (or https://api.eu.pagerduty.com when region is eu). PagerDuty webhooks exist but are configured in the PagerDuty UI, never via API, so they cannot be provisioned at install time.
Credential
References a pagerduty_api_key credential by id. The secret is a REST API key (account-level from Integrations → API Access Keys, or a user API token). PagerDuty authenticates with Authorization: Token token=<key>. There is no site URL beside the key — EU vs US is the sensor region field.
curl -sS -X POST https://your-corveil-host/api/credentials \
-H "Authorization: Bearer <admin>" -H "Content-Type: application/json" \
-d '{"type":"pagerduty_api_key","name":"acme-pagerduty","secret":"<rest-api-key>"}'OAuth access tokens are a different product and are out of scope in v1.
Config fields
| Key | Required | Notes |
|---|---|---|
enabled_objects | no | Comma-separated object kinds. Blank polls every supported kind. Unknown names are rejected at configure time. |
service_ids | no | Comma-separated PagerDuty service IDs (e.g. PIJ90N7). Restricts incidents and on-calls. Blank ingests every service the key can read. |
region | no | us (default) or eu. Selects api.pagerduty.com vs api.eu.pagerduty.com. |
Supported object names: services, incidents, oncalls.
There is no default_entity_type. This source emits multiple primary types, so a single override would silently mistype the rest.
Provider-side setup
- In PagerDuty, go to Integrations → API Access Keys (account-level) or My Profile → User Settings → API Access (user token).
- Create a REST API key. Grant read access to incidents, services, and on-calls.
- Copy the key. Store only the key value, not
Token token=…. - If the account lives in the EU service region, set
regiontoeu.
Wire-up
POST /api/sensors
{
"sensor_type": "pagerduty",
"name": "Acme PagerDuty",
"config": {
"enabled_objects": "services, incidents, oncalls",
"region": "us"
},
"credentials": { "api_key": "<pagerduty_api_key credential id>" }
}Verify
Run Test connection. It authenticates the key against the first enabled object's list endpoint, so a 401/403 fails at save/test rather than on the first poll.
Once polling, each object kind's count appears in the per-poll summary log (incidents_collected, services_collected, oncalls_collected). A kind stuck at zero while the others move is the signal to check that kind's REST permission.
How incremental sync works
- Incidents filter on
since(created_at), oldest-first. The per-object watermark followscreated_at— the same clock assince. Advancing fromlast_status_change_atwould skip incidents whose create time is older than a recently-updated sibling. PagerDuty's list defaults to the last month whensinceis omitted; after the first poll the cursor carries that watermark. A test pins thesincequery parameter. - Each poll re-reads a two-minute overlap. List clocks can lag the write, so a strict resume would step permanently past a record that was briefly behind.
since/untilrange is capped at six months. A watermark older than that is clamped rather than 400ing the list.- Deletes are invisible. A record vanishing from results is not treated as a deletion.
- Rate limits are shared. PagerDuty's published REST budget is 900 requests per minute per account, shared with every other integration. The source paces itself under that floor and backs off for the cycle on a 429 rather than retrying in-loop.
Not included
- OpsGenie. A different product; do not configure this source against OpsGenie.
- OAuth / connected apps. Only needed for multi-customer marketplace distribution.
- Webhooks. PagerDuty supports them, but subscriptions are created in the PagerDuty UI, never via API — so they cannot be provisioned at install time. Polling is the supported path.
- Alerts, notes, log-entry N+1. Deferred. Incident title, status, urgency, service, and assignees are the structured floor.