Founding keys are opena year free at 6,000 req/hour, for the first 1,000 developersClaim yours

PagerDuty

Point a PagerDuty API client at https://pd.sandboxapis.dev — paths are root-level (/incidents, /services, /oncalls), exactly like api.pagerduty.com, with no version prefix: PagerDuty versions in the Accept header. The official PagerDuty MCP server takes PAGERDUTY_API_HOST; pdpyras takes PDSession(url=...); the Go and Node SDKs take a base-URL option. Auth is 'Authorization: Token token=<key>' (any value is accepted here). This is the org's ON-CALL surface: services are what the org deploys, escalation policies and schedules decide who is woken, and an incident's log entries are the real timeline — alert fired, page sent, page acknowledged, fix resolved. ONE THING TO KNOW: GET /incidents defaults to the last month (PagerDuty's own default) and this universe's incident is older, so pass date_range=all.

REST · 211 endpointsMCP-ready

Coverage badge

Full211/211 · 100%

The share of read rows with a final answer — served and verified, a deviation, retired upstream, or a reviewed empty/refusal. Computed in the coverage manifest, copied here.

Live host
pd.sandboxapis.dev
Pinned hosts
5 — generation 7, 8, 9, 10, 11
Serving since
2026-09-01
Lifecycle
Live

Served & verified

184 / 87%

Answering with real universe data, each response checked against PagerDuty's published spec by the conformance suite on this build. 5 of them are marked a deviation — served faithfully, but failing the vendored spec.

The full read API

211

Every read surface PagerDuty publishes, deferred long tail included, minus the rows excluded by policy. Writes are out of scope: this universe is read-only.

Not served yet

27

Each returns an explicit, provider-shaped coverage error naming the gap — never invented data.

01 / The swap

Point your client at a different base URL.

No SDK of ours, no shim, no recorded fixtures. The same client library you already use, one environment variable different.

shell
curl -H 'Authorization: Token token=anything' "https://pd.sandboxapis.dev/incidents?date_range=all"

Verified drop-in clients

No client library is version-pinned against PagerDuty yet, so this page claims none. What is asserted is the wire: every response above is validated against PagerDuty's own published spec by the conformance suite. Client pins live in coverage/client-pins.yaml and are added as each SDK joins the suite.

02 / Coverage by family

Every read surface, grouped the way PagerDuty groups it.

All 211 rows the coverage manifest carries for PagerDuty, deferred long tail included and nothing capped. Open a family, or filter by path to find the exact endpoint your client calls.

Status — what a conformance test found

served & verified
answers with real universe data, and this build checked that response against the vendor's spec.
deviation
served and faithful to the real provider, but failing the vendored spec — usually a bug in the spec.
retired
the vendor removed the endpoint; snapshots pinned before that date still serve it.
planned / deferred
not served yet — an explicit coverage error naming the gap, never invented data.
excluded
out of the claim by policy (writes, and surfaces we refuse); not in any denominator on this page.

Mode — what kind of answer a row gets

derive
the response is computed from artifact rows that already exist
generate
canon does not carry this yet; the generator will produce it, then derive
empty
the true answer for this universe is an empty collection — reason + reviewed date required
refuse
mirror the provider's OWN refusal (e.g. its 403 for a non-admin token) — reason + reviewed date required
read-only
a write named in the manifest because clients probe it; the read-only 403 IS its final response, and it never joins the badge denominator

A row with no mode shown has not been judged yet. Modes are the manifest's own words, from coverage/MODES.yaml; every empty and refuse carries a written reason and a review date before it counts as final.

Badge — where Full starts

Full
every published read row has a final answer
Deep
60% up to 100%
Partial
25% up to 60%
Preview
under 25%

REST + GraphQL + git rows that are not `excluded`. Write operations are NOT rows (DECISIONS 2026-09-01 decision 9): they are counted in meta.write_operations and never enter this ratio.

211 read surfaces in 29 families

event-orchestration20 of 32 served & verified
GET
/event_orchestrations
served & verified
Long tail
GET
/event_orchestrations/{id}
served & verified
Long tail
GET
/event_orchestrations/{id}/cache_variables
served & verified
Long tail
GET
/event_orchestrations/{id}/cache_variables/{cache_variable_id}
served & verified
Long tail
GET
/event_orchestrations/{id}/cache_variables/{cache_variable_id}/data
served & verified
Long tail
GET
/event_orchestrations/{id}/enablements
served & verified
Long tail
GET
/event_orchestrations/{id}/global
served & verified
Long tail
GET
/event_orchestrations/{id}/integrations
served & verified
Long tail
GET
/event_orchestrations/{id}/integrations/{integration_id}
served & verified
Long tail
GET
/event_orchestrations/{id}/router
served & verified
Long tail
GET
/event_orchestrations/{id}/unrouted
served & verified
Long tail
GET
/event_orchestrations/services/{service_id}
served & verified
Long tail
GET
/event_orchestrations/services/{service_id}/active
served & verified
Long tail
GET
/event_orchestrations/services/{service_id}/cache_variables
served & verified
Long tail
GET
/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}
served & verified
Long tail
GET
/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}/data
served & verified
Long tail
GET
/rulesets
served & verified
Long tail
GET
/rulesets/{id}
served & verified
Long tail
GET
/rulesets/{id}/rules
served & verified
Long tail
GET
/rulesets/{id}/rules/{rule_id}
served & verified
Long tail
GET
/enrichment/event_enrichments

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/event_enrichments/{id}

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/event_enrichments/{id}/associations

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/event_enrichments/{id}/rules

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/event_enrichments/default

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/integrations/servicenow

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/integrations/servicenow/{integration_id}

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/integrations/servicenow/{integration_id}/tables/{table_id}/test

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/integrations/servicenow/credentials/{credentials_id}

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/schemas

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/schemas/{schema_id}

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
GET
/enrichment/schemas/{schema_id}/records

refuse — PagerDuty's own words on every operation in this family: "This API is in Early Access and may change at any time. Contact your PagerDuty account team to request access." This replica has not requested access and cannot — the gate is a conversation with a vendor, not a plan — so PagerDuty's refusal to an unenrolled account IS the true answer. Serving a Contextual Data Platform schema would additionally assert an integration posture (ServiceNow CMDB sync) that this engineering org has never had

deferred
Long tail
automation23 of 23 served & verified
GET
/automation_actions/actions
served & verified
Long tail
GET
/automation_actions/actions/{id}
served & verified
Long tail
GET
/automation_actions/actions/{id}/services
served & verified
Long tail
GET
/automation_actions/actions/{id}/services/{service_id}
served & verified
Long tail
GET
/automation_actions/actions/{id}/teams
served & verified
Long tail
GET
/automation_actions/actions/{id}/teams/{team_id}
served & verified
Long tail
GET
/automation_actions/invocations
served & verified
Long tail
GET
/automation_actions/invocations/{id}
served & verified
Long tail
GET
/automation_actions/runners
served & verified
Long tail
GET
/automation_actions/runners/{id}
served & verified
Long tail
GET
/automation_actions/runners/{id}/teams
served & verified
Long tail
GET
/automation_actions/runners/{id}/teams/{team_id}
served & verified
Long tail
GET
/incident_workflows
served & verified
Long tail
GET
/incident_workflows/{id}
served & verified
Long tail
GET
/incident_workflows/actions
served & verified
Long tail
GET
/incident_workflows/actions/{id}
served & verified
Long tail
GET
/incident_workflows/triggers
served & verified
Long tail
GET
/incident_workflows/triggers/{id}
served & verified
Long tail
GET
/workflows/integrations
served & verified
Long tail
GET
/workflows/integrations/{id}
served & verified
Long tail
GET
/workflows/integrations/{integration_id}/connections
served & verified
Long tail
GET
/workflows/integrations/{integration_id}/connections/{id}
served & verified
Long tail
GET
/workflows/integrations/connections
served & verified
Long tail
users13 of 18 served & verified
GET
/users
served & verified
Core
GET
/users/{id}
served & verified
Core
GET
/users/{id}/audit/records
served & verified
Core
GET
/users/{id}/contact_methods
served & verified
Core
GET
/users/{id}/contact_methods/{contact_method_id}
served & verified
Core
GET
/users/{id}/notification_rules
served & verified
Core
GET
/users/{id}/notification_rules/{notification_rule_id}
served & verified
Core
GET
/users/{id}/notification_subscriptions
served & verified
Core
GET
/users/{id}/oncall_handoff_notification_rules
served & verified
Core
GET
/users/{id}/oncall_handoff_notification_rules/{oncall_handoff_notification_rule_id}
served & verified
Core
GET
/users/{id}/status_update_notification_rules
served & verified
Core
GET
/users/{id}/status_update_notification_rules/{status_update_notification_rule_id}
served & verified
Core
GET
/users/me
served & verified
Core
GET
/users/{id}/license

refuse — account-administration machinery this replica does not model and should not simulate: seat licensing and plan allocation are a BILLING relationship, and this canon models an engineering organization rather than a customer of PagerDuty. There is no canonical row that could answer without inventing a plan for olympus-labs — the exact objection the 2026-09-01 /abilities refusal raised and the capture later answered for THAT row only. PagerDuty's own 4xx is the true answer here, not our coverage 404

planned
Core
GET
/users/{id}/oauth_delegations

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings

planned
Core
GET
/users/{id}/oauth_delegations/{delegation_id}

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings

planned
Core
GET
/users/{id}/sessions

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings. This operation is ALSO `deprecated: true` upstream with a documented replacement (the List OAuth Delegations endpoint) — a retirement candidate recorded in the review doc, deliberately NOT armed in the gateway registry here because PagerDuty has published no removal date

planned
Core
GET
/users/{id}/sessions/{type}/{session_id}

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings. This operation is ALSO `deprecated: true` upstream with a documented replacement (the List OAuth Delegations endpoint) — a retirement candidate recorded in the review doc, deliberately NOT armed in the gateway registry here because PagerDuty has published no removal date

planned
Core
schedules16 of 16 served & verified
GET
/schedules
served & verified
Core
GET
/schedules/{id}
served & verified
Core
GET
/schedules/{id}/audit/records
served & verified
Core
GET
/schedules/{id}/overrides

hello-13's ScheduleOverride canon: two people covered somebody else's shift, and `replaces` names the person the rotation formula produces across the window so an override can never disagree with the schedule it overrides

served & verified
Core
GET
/schedules/{id}/users
served & verified
Core
GET
/v3/schedules
served & verified
Next
GET
/v3/schedules/{id}
served & verified
Next
GET
/v3/schedules/{id}/audit/records
served & verified
Next
GET
/v3/schedules/{id}/custom_shifts
served & verified
Next
GET
/v3/schedules/{id}/custom_shifts/{custom_shift_id}
served & verified
Next
GET
/v3/schedules/{id}/overrides

the v3 rendering of the same two ScheduleOverride rows as OverrideShift; rotation_id and custom_shift_id are omitted rather than invented, this canon has neither entity

served & verified
Next
GET
/v3/schedules/{id}/overrides/{override_id}

one override by id, byte-identical to the row the v3 list served; an id this rotation never issued is a 404

served & verified
Next
GET
/v3/schedules/{id}/rotations
served & verified
Next
GET
/v3/schedules/{id}/rotations/{rotation_id}
served & verified
Next
GET
/v3/schedules/{id}/rotations/{rotation_id}/events
served & verified
Next
GET
/v3/schedules/{id}/rotations/{rotation_id}/events/{event_id}
served & verified
Next
status-pages16 of 16 served & verified
GET
/status_pages
served & verified
Long tail
GET
/status_pages/{id}/impacts
served & verified
Long tail
GET
/status_pages/{id}/impacts/{impact_id}
served & verified
Long tail
GET
/status_pages/{id}/posts
served & verified
Long tail
GET
/status_pages/{id}/posts/{post_id}
served & verified
Long tail
GET
/status_pages/{id}/posts/{post_id}/post_updates
served & verified
Long tail
GET
/status_pages/{id}/posts/{post_id}/post_updates/{post_update_id}
served & verified
Long tail
GET
/status_pages/{id}/posts/{post_id}/postmortem
served & verified
Long tail
GET
/status_pages/{id}/services
served & verified
Long tail
GET
/status_pages/{id}/services/{service_id}
served & verified
Long tail
GET
/status_pages/{id}/severities
served & verified
Long tail
GET
/status_pages/{id}/severities/{severity_id}
served & verified
Long tail
GET
/status_pages/{id}/statuses
served & verified
Long tail
GET
/status_pages/{id}/statuses/{status_id}
served & verified
Long tail
GET
/status_pages/{id}/subscriptions
served & verified
Long tail
GET
/status_pages/{id}/subscriptions/{subscription_id}
served & verified
Long tail
incidents11 of 12 served & verified · 1 deviation
GET
/incidents
served & verified
Core
GET
/incidents/{id}
served & verified
Core
GET
/incidents/{id}/alerts
served & verified
Core
GET
/incidents/{id}/alerts/{alert_id}
served & verified
Core
GET
/incidents/{id}/business_services/impacts
served & verified
Core
GET
/incidents/{id}/custom_fields/values
served & verified
Core
GET
/incidents/{id}/notes
served & verified
Core
GET
/incidents/{id}/outlier_incident
served & verified
Core
GET
/incidents/{id}/past_incidents
served & verified
Core
GET
/incidents/{id}/related_incidents
served & verified
Core
GET
/incidents/{id}/status_updates/subscribers
served & verified
Core
GET
/incidents/{id}/log_entries
deviation
Core
services12 of 12 served & verified
GET
/services
served & verified
Core
GET
/services/{id}
served & verified
Core
GET
/services/{id}/audit/records
served & verified
Core
GET
/services/{id}/custom_fields/values
served & verified
Core
GET
/services/{id}/enablements

the document supports exactly one feature here (`aiops`) and says an unentitled account gets a warning alongside the data. NO AIOps name appears in the 53-name captured /abilities response this replica serves, so `enabled: true` would contradict the list published one path over (invariant #5) — the entitlement is READ from our own ability list rather than chosen. The document leaves `enabled` unstated for the unentitled case and `false` is the only reading consistent with "not entitled to use"; the ambiguity is recorded in DECISIONS 2026-09-02 [pagerduty/enablements]. `updated_at` is omitted because nobody has ever changed a setting nobody can change

served & verified
Core
GET
/services/{id}/integrations/{integration_id}
served & verified
Core
GET
/services/{id}/rules
served & verified
Core
GET
/services/{id}/rules/{rule_id}
served & verified
Core
GET
/services/custom_fields
served & verified
Next
GET
/services/custom_fields/{field_id}
served & verified
Next
GET
/services/custom_fields/{field_id}/field_options
served & verified
Next
GET
/services/custom_fields/{field_id}/field_options/{field_option_id}
served & verified
Next
business-services9 of 9 served & verified
GET
/business_services
served & verified
Next
GET
/business_services/{id}
served & verified
Next
GET
/business_services/{id}/subscribers
served & verified
Next
GET
/business_services/{id}/supporting_services/impacts
served & verified
Next
GET
/business_services/impactors
served & verified
Next
GET
/business_services/impacts
served & verified
Next
GET
/business_services/priority_thresholds

NULL, and the null is the fact rather than a gap: a global impact threshold is something an admin SETS, setting one is a write, and the document's own example for an account that has not set one is `{"global_threshold": null}`. Naming a priority would assert an impact rule this account never configured — and every incident here would then read as impacting business services it has none of

served & verified
Next
GET
/service_dependencies/business_services/{id}
served & verified
Next
GET
/service_dependencies/technical_services/{id}
served & verified
Next
incident-types7 of 9 served & verified · 2 deviations
GET
/incidents/custom_fields/{field_id}/field_options
served & verified
Next
GET
/incidents/types

the ONE incident type PagerDuty ships to every account. Unlike /abilities — where the 2026-09-01 refusal found the document enumerated nothing — this list's contents are stated twice in the pinned document: the 200 on this operation says "The default incident type will automatically return on this list", and `IncidentType.parent` says a type with no parent "is created under top level (`incident_default`)". So the account has exactly one type until somebody writes another, and writing is out. The two NAMES are PagerDuty's own vocabulary for its own built-in row; the document's EXAMPLE id (P123456) and its 2023 timestamps are NOT copied — the id is minted by the same pdId every other object uses and the timestamps are the org's own creation instant. NOT the documented 402: the captured ability list carries `enable_custom_fields_on_incidents` and `premium_custom_fields`, so refusing would contradict the list published one path over

served & verified
Next
GET
/incidents/types/{type_id_or_name}

the ONE incident type PagerDuty ships to every account. Unlike /abilities — where the 2026-09-01 refusal found the document enumerated nothing — this list's contents are stated twice in the pinned document: the 200 on this operation says "The default incident type will automatically return on this list", and `IncidentType.parent` says a type with no parent "is created under top level (`incident_default`)". So the account has exactly one type until somebody writes another, and writing is out. The two NAMES are PagerDuty's own vocabulary for its own built-in row; the document's EXAMPLE id (P123456) and its 2023 timestamps are NOT copied — the id is minted by the same pdId every other object uses and the timestamps are the org's own creation instant. NOT the documented 402: the captured ability list carries `enable_custom_fields_on_incidents` and `premium_custom_fields`, so refusing would contradict the list published one path over

served & verified
Next
GET
/incidents/types/{type_id_or_name}/custom_fields
served & verified
Next
GET
/incidents/types/{type_id_or_name}/custom_fields/{field_id}
served & verified
Next
GET
/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options
served & verified
Next
GET
/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options/{field_option_id}
served & verified
Next
GET
/incidents/custom_fields
deviation
Next
GET
/incidents/custom_fields/{field_id}
deviation
Next
webhooks6 of 8 served & verified
GET
/extension_schemas
served & verified
Long tail
GET
/extension_schemas/{id}
served & verified
Long tail
GET
/extensions
served & verified
Long tail
GET
/extensions/{id}
served & verified
Long tail
GET
/webhook_subscriptions
served & verified
Long tail
GET
/webhook_subscriptions/{id}
served & verified
Long tail
GET
/webhook_subscriptions/oauth_clients

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings

deferred
Long tail
GET
/webhook_subscriptions/oauth_clients/{id}

refuse — live authentication machinery, not engineering-org data: an inventory of the OAuth tokens and browser sessions currently issued against the account is a security surface whose truthful content changes by the minute and whose simulated content would be a set of credentials that authenticate nothing. The canon records no session and no token, and a replica that invented one would be publishing credential-shaped strings

deferred
Long tail
licensing0 of 7 served & verified
GET
/ip_allow_lists

refuse — network-security configuration behind an enrollment gate this replica is not enrolled in: every operation in this family requires the `X-EARLY-ACCESS: ip-allow-lists` header AND an account enrolled in the IP Allow Lists Early Access program, and its own description limits it to "Account Owners, Global Admins, and Account API Keys". An allow-list of CIDR ranges is also a claim about network perimeter that a public sandbox has no business simulating

deferred
Long tail
GET
/ip_allow_lists/{id}

refuse — network-security configuration behind an enrollment gate this replica is not enrolled in: every operation in this family requires the `X-EARLY-ACCESS: ip-allow-lists` header AND an account enrolled in the IP Allow Lists Early Access program, and its own description limits it to "Account Owners, Global Admins, and Account API Keys". An allow-list of CIDR ranges is also a claim about network perimeter that a public sandbox has no business simulating

deferred
Long tail
GET
/ip_allow_lists/{id}/audit/records

refuse — network-security configuration behind an enrollment gate this replica is not enrolled in: every operation in this family requires the `X-EARLY-ACCESS: ip-allow-lists` header AND an account enrolled in the IP Allow Lists Early Access program, and its own description limits it to "Account Owners, Global Admins, and Account API Keys". An allow-list of CIDR ranges is also a claim about network perimeter that a public sandbox has no business simulating

deferred
Long tail
GET
/license_allocations

refuse — account-administration machinery this replica does not model and should not simulate: seat licensing and plan allocation are a BILLING relationship, and this canon models an engineering organization rather than a customer of PagerDuty. There is no canonical row that could answer without inventing a plan for olympus-labs — the exact objection the 2026-09-01 /abilities refusal raised and the capture later answered for THAT row only. PagerDuty's own 4xx is the true answer here, not our coverage 404

deferred
Long tail
GET
/licenses

refuse — account-administration machinery this replica does not model and should not simulate: seat licensing and plan allocation are a BILLING relationship, and this canon models an engineering organization rather than a customer of PagerDuty. There is no canonical row that could answer without inventing a plan for olympus-labs — the exact objection the 2026-09-01 /abilities refusal raised and the capture later answered for THAT row only. PagerDuty's own 4xx is the true answer here, not our coverage 404

deferred
Long tail
GET
/oauth_delegations/revocation_requests/status

refuse — `deprecated: true` upstream ("deprecated as OAuth token revocation is now synchronous"), limited by its own description to "account owners and admins", AND the document declares NO 200 response for it at all — the responses are 400/401/403/404/429. There is no success shape to conform to, so a 200 of any kind would be a body this replica invented outright

deferred
Long tail
GET
/session_configurations

refuse — account session-security policy (absolute and idle session TTLs), which is administration rather than engineering data — and the document states PagerDuty's own answer for an account that has not configured one: "If no configurations exist, a 404 Not Found error will be returned. A Session Configuration needs to be created before it can be retrieved." Creating one is a write, so the 404 IS this account's true answer rather than a coverage gap

deferred
Long tail
addons5 of 5 served & verified
GET
/addons
served & verified
Long tail
GET
/addons/{id}
served & verified
Long tail
GET
/templates
served & verified
Long tail
GET
/templates/{id}
served & verified
Long tail
GET
/templates/fields
served & verified
Long tail
status-dashboards5 of 5 served & verified
GET
/status_dashboards
served & verified
Next
GET
/status_dashboards/{id}
served & verified
Next
GET
/status_dashboards/{id}/service_impacts
served & verified
Next
GET
/status_dashboards/url_slugs/{url_slug}
served & verified
Next
GET
/status_dashboards/url_slugs/{url_slug}/service_impacts
served & verified
Next
teams5 of 5 served & verified
GET
/teams
served & verified
Core
GET
/teams/{id}
served & verified
Core
GET
/teams/{id}/audit/records
served & verified
Core
GET
/teams/{id}/members
served & verified
Core
GET
/teams/{id}/notification_subscriptions
served & verified
Core
analytics4 of 4 served & verified
GET
/analytics/raw/incidents/{id}

TRUE AGGREGATIONS over the incident's own timeline, not statistics invented at render time: every duration is arithmetic over `Incident.openedOffset`/`acknowledgedOffset`/`resolvedOffset`, every count is over the `Page` rows the policy actually sent, and the business/off/sleep interruption buckets are computed from each page's sent instant on the RESPONDER's own clock (`Person.utcOffsetMin`) at PagerDuty's published boundaries. Six declared fields stay ABSENT because the canon states no fact behind them — `auto_resolved`, `major`, `snoozed_seconds`, `user_defined_effort_seconds` and the two `joined_user_*` — and a flat object of optional integers is exactly where a plausible number would never be caught

served & verified
Next
GET
/analytics/raw/incidents/{id}/responses

one row per `Page`: who was notified, at which rung, when it was sent and when they answered. `responder_type` is read off the rung (0 IS the assignment, above it is the escalation) and `reassigned`/`added_responder` are unreachable because both are writes — a fact about a read-only universe rather than an unwritten branch

served & verified
Next
GET
/paused_incident_reports/alerts
served & verified
Next
GET
/paused_incident_reports/counts
served & verified
Next
change-events4 of 4 served & verified
GET
/change_events

canon's `Deployment` rows in PagerDuty's own vocabulary — its `related_change_events` operation defines a change event as "service changes such as deploys, build completion, and configuration changes", which is the entity the git canon already records: a real commit, to a real environment, by a real person. `custom_details.commit` is the SAME sha every git host serves for that deploy, so a responder can follow one change across providers (invariant #5). `integration`, `routing_key`, `source`, `links` and `images` are omitted because this universe has no inbound integration — the reason the renderer already omits `Service.integrations`. `change_events` is one of the 53 names in the captured /abilities response, so the surface and the ability list agree

served & verified
Next
GET
/change_events/{id}

canon's `Deployment` rows in PagerDuty's own vocabulary — its `related_change_events` operation defines a change event as "service changes such as deploys, build completion, and configuration changes", which is the entity the git canon already records: a real commit, to a real environment, by a real person. `custom_details.commit` is the SAME sha every git host serves for that deploy, so a responder can follow one change across providers (invariant #5). `integration`, `routing_key`, `source`, `links` and `images` are omitted because this universe has no inbound integration — the reason the renderer already omits `Service.integrations`. `change_events` is one of the 53 names in the captured /abilities response, so the surface and the ability list agree

served & verified
Next
GET
/incidents/{id}/related_change_events

the deploy that landed nearest before the pager went off, on a repo the incident's own service ships from — labelled `most_recent`, which is the ONE of PagerDuty's three correlation reasons this canon can state as a fact. `related_service` would need a service-dependency graph the canon carries no edges for and `intelligent` names a model's output, so neither is emitted rather than being attached to the same row

served & verified
Next
GET
/services/{id}/change_events

canon's `Deployment` rows in PagerDuty's own vocabulary — its `related_change_events` operation defines a change event as "service changes such as deploys, build completion, and configuration changes", which is the entity the git canon already records: a real commit, to a real environment, by a real person. `custom_details.commit` is the SAME sha every git host serves for that deploy, so a responder can follow one change across providers (invariant #5). `integration`, `routing_key`, `source`, `links` and `images` are omitted because this universe has no inbound integration — the reason the renderer already omits `Service.integrations`. `change_events` is one of the 53 names in the captured /abilities response, so the surface and the ability list agree

served & verified
Next
tags4 of 4 served & verified
GET
/{entity_type}/{id}/tags
served & verified
Next
GET
/tags
served & verified
Next
GET
/tags/{id}
served & verified
Next
GET
/tags/{id}/{entity_type}
served & verified
Next
escalation-policies3 of 3 served & verified
GET
/escalation_policies
served & verified
Core
GET
/escalation_policies/{id}
served & verified
Core
GET
/escalation_policies/{id}/audit/records
served & verified
Core
standards3 of 3 served & verified
GET
/standards
served & verified
Long tail
GET
/standards/scores/{resource_type}
served & verified
Long tail
GET
/standards/scores/{resource_type}/{id}
served & verified
Long tail
abilities2 of 2 served & verified
GET
/abilities

served VERBATIM from a captured response (packages/conformance/specs/pagerduty/captures/abilities.json, sha-pinned in coverage/provider-pins.yaml under pagerduty.captures-file): 53 ability names captured 2026-09-02 from api.pagerduty.com using PagerDuty's PUBLIC developer-docs sample credentials, so the evidence is reproducible by anyone rather than taken on trust. That capture is the exact unblock the 2026-09-01 refusal named. It reaches PagerDuty's DEMO account, which is feature-rich — the operation says an ability depends on 'your pricing plan or account state', so no single list is correct and a captured one beats a chosen one

served & verified
Core
GET
/abilities/{id}

the 204/404 membership test over the same captured list — every one of the 53 answers 204 and anything else takes the document's own NotFound. NOT the 402: that response reads 'Account does not have the abilities to perform the action' and is declared on eighty-five other operations, so it is the product's generic plan gate on an ACTION rather than this operation's membership answer

served & verified
Core
alert-grouping2 of 2 served & verified
GET
/alert_grouping_settings
served & verified
Next
GET
/alert_grouping_settings/{id}
served & verified
Next
log-entries0 of 2 served & verified · 2 deviations
GET
/log_entries
deviation
Core
GET
/log_entries/{id}
deviation
Core
maintenance-windows2 of 2 served & verified
GET
/maintenance_windows
served & verified
Next
GET
/maintenance_windows/{id}
served & verified
Next
recommendations2 of 2 served & verified
GET
/recommendations/event_orchestrations/rules
served & verified
Long tail
GET
/sre_agent/memories
served & verified
Long tail
vendors2 of 2 served & verified
GET
/vendors

hello-13's `features.vendorCatalog`: twelve FICTIONAL integration partners, structure in canon's VENDOR_CATALOG, names and directory copy in themes/greek/vendors.ts, baked into the artifact's `vendor` table at compile. This REPLACES the 2026-09-02-morning `empty` ruling, which was itself a knowing deviation — the founder's afternoon ruling took the third option over both serving nothing and printing real companies' names. A pre-catalogue artifact (both frozen g7 pins) still answers 200 + the empty envelope, deliberately, not a generation gap

served & verified
Next
GET
/vendors/{id}

one partner by id, byte-identical to the row the catalogue list served; an id this catalogue never issued is the document's own 404. The `{"vendor": [<Vendor>]}` ARRAY envelope is the pinned document's, not ours — the only single-object GET in it wearing a collection envelope, and no 200 on this provider has ever been captured to contradict it (coverage/provider-pins.yaml capture-pending)

served & verified
Next
audit0 of 1 served & verified
GET
/audit/records

refuse — the ONE audit operation the document gates explicitly, in its own words: "Only admins, account owners, or global API tokens on PagerDuty accounts with the 'Audit Trail' feature can access this endpoint." The account-wide trail is both admin-only and plan-gated, and no ability in the captured /abilities response names Audit Trail. The RESOURCE-scoped audit rows carry no such sentence and are classified `generate` below — the split is the document's, not ours

deferred
Next
notifications1 of 1 served & verified
GET
/notifications
served & verified
Next
oncalls1 of 1 served & verified
GET
/oncalls
served & verified
Core
priorities1 of 1 served & verified
GET
/priorities
served & verified
Core

03 / What's simulated

One data set, rendered in PagerDuty's dialect.

What another provider has to agree with, and the test that makes it

Each line below is one assertion in the conformance suite named beside it — run on every build, over one artifact, through the real renderers. Nothing is claimed here that no expect checks.

04 / Known deviations

5 rows are served but do not validate.

These answer with real data and match what PagerDuty actually returns, but fail the spec we vendor from PagerDuty — nearly always a bug in that published description. They are listed rather than counted so you can see whether one of them is the endpoint your client calls, and they are never counted as verified.

05 / Pinned snapshots

Frozen universes, on their own hostnames.

Each pin regenerates byte-identically on every request, so a test written against one never drifts. Generations are DIFFERENT universes, not versions of one — never swap a suffix expecting the same data.

PinHostUniverse generationPagerDuty API versionRepository files
pd-v2pd-v2.snap.sandboxapis.devgeneration 72served
pd-v2-g10pd-v2-g10.snap.sandboxapis.devgeneration 102served
pd-v2-g11pd-v2-g11.snap.sandboxapis.devgeneration 112served
pd-v2-g8pd-v2-g8.snap.sandboxapis.devgeneration 82served
pd-v2-g9pd-v2-g9.snap.sandboxapis.devgeneration 92served

Need an endpoint that is not served yet?

Every row PagerDuty's manifest carries is on this page, so “not here” is an answer rather than a gap in the rendering. Tell us which path and which client, and it moves up the queue — the order is set by what people ask for.

Request coverage