Connect PagerDuty, Opsgenie, Splunk On-Call (VictorOps), xMatters or OnPage to Versus to trigger, acknowledge and resolve incidents from workflows, and read the current on-call roster — who is primary, who escalates next, and how to reach them — from workflows, the AutoPilot and the Integrations page.
Versus talks to the paging platforms operations teams already carry: PagerDuty, Opsgenie, Splunk On-Call (VictorOps), xMatters and OnPage. One vendor-neutral client covers all of them, so a workflow written against versus.integrations.pager() works unchanged when the team moves platforms.
Two things flow through it:
Integrations → Pager / On-Call → Add Pager Source. Credentials are encrypted at rest and never returned by the API; editing a source lets you leave a secret blank to keep it.
| Vendor | Routing / integration key | REST credential (incidents + on-call) |
|---|---|---|
| PagerDuty | Events API v2 integration key | REST API key (v2 token) |
| Opsgenie | (blank — the API key is used for both) | API key from Settings → API key management; set the custom URL to https://api.eu.opsgenie.com for EU tenants |
| Splunk On-Call | Routing key from Integrations → REST Endpoint | <api id>:<api key> (colon-separated) |
| xMatters | Inbound Integration URL (the full https://…/triggers URL) | user:password for Basic auth, or an xMatters API key |
| OnPage | API key | (same key) — OnPage has no schedule API, so on-call is not available |
Test sends and immediately resolves a harmless test incident on vendors that page (PagerDuty, Splunk On-Call, xMatters), or reads the account on Opsgenie.
Every source except OnPage has an On-call button on its card. It shows one block per group / schedule / escalation policy with the current shift window and the members in escalation order — primary, secondary, then further escalation levels with their delay — plus e-mail and phone where the vendor exposes them. The filter box narrows by group name.
| Vendor | Where the roster comes from |
|---|---|
| PagerDuty | GET /oncalls — grouped by escalation policy, members carry their escalation level |
| Opsgenie | GET /schedules then GET /schedules/{id}/on-calls?flat=true |
| Splunk On-Call | GET /oncall/current — per team and escalation policy |
| xMatters | GET /groups then GET /on-call?groups=…&from=now&to=+24h — per group and shift, members by position and delay |
The badge on the panel says Live when the vendor answered, or Sample roster on a seeded demo source (below). A real source that cannot be reached shows the vendor's error instead of guessing.
pager = versus.integrations.pager() # first enabled source, or pager('Prod PagerDuty')
# page
key = pager.critical('BIG-IP bigip2 sync failed after upgrade',
body=versus.get_input('detail'), component='bigip2', group='ADC')
# … later
pager.resolve(key)
# who should hear about it
primary = pager.who_is_on_call('ADC') # {name, email, phone, group, policy, level, until}
if primary:
versus.integrations.slack().message(f"Paging {primary['name']} ({primary['phone']}) for the ADC group")
# the full roster
for g in pager.on_call():
names = ', '.join(f"{m['name']} ({m['level']})" for m in g['members'])
versus.log(f"{g['group']} [{g['policy']}] until {g['end']}: {names}")
on_call(group=None) returns a list of groups, each with group, policy, start, end, url and members (position, level, delay_min, name, email, phone, role). on_call_report() adds provenance (origin of live, sample or error). The Generate with AI button in the Workflow Builder knows these methods.
In the Diagnostics AutoPilot the same lookup is the who_is_on_call tool, so an agent that has diagnosed a fault can finish with the name and number of the person who owns it.
manage.py seed_xmatters_oncall (also run by the full seed_demo) creates an xMatters (Demo) source whose stored metadata carries a representative on-call roster — Network Operations, ADC / Load Balancing, Firewall & Security, Site Reliability and Change Advisory groups, each with primary / secondary / escalation members, shift windows and contact details — and a few recent events. The On-call panel, pager.on_call(), pager.get_incidents() and the AutoPilot tool serve that data until REST credentials are added to the source, and label it as sample data when they do. The roster itself lives on the source row (metadata.on_call), so it is real seeded data you can inspect through the API.
Real customer sources never fall back to the sample roster.