ShiftBeta

Getting started · Integrations · API

API

Everything in the app is also a JSON API. For agents, use the MCP server instead: seeAI & MCP.

REST: https://shift.nightroll.app/api/v1

Create an API key in Settings → API keys and send it asAuthorization: Bearer $KEY. The key belongs to one org and carries scopes: read for GETs,write for changes, admin for the phone provider, chat webhooks and alert archives. Role is your role in the org (viewer, member, admin, owner); a key never has more access than the person who made it.

curl https://shift.nightroll.app/api/v1/oncall -H "Authorization: Bearer $KEY"
MethodPathRoleWhat
GET/alerts?all=1&q=viewerOpen alerts; all=1 adds the latest resolved (100 at most), q searches. Resolved alerts older than 30 days are archived and not here
GET/alerts/:idviewer{alert, log} with the timeline
GET/alerts/archivesadminArchived days, newest first: {days: [{day, rows, where: bucket | nightroll}]}, rows = alerts
GET/alerts/archives/:dayadminThat day's file (gzipped JSON lines, one alert with its timeline per line), YYYY-MM-DD as listed
POST/alertsmember{service_id, title, severity?} opens an alert, or {user_id, message} pages one person. Over an API key or OAuth: 5 an hour per org
POST/alerts/:idmember{action: acknowledge | resolve | unacknowledge | reassign | note, to?, text?}
POST/alerts/:id/summarymemberSummarize on your own AI key; adds the summary as a note
GET/servicesviewerServices with their keys and settings
POST/servicesmember{name} creates a service and its first key → {id}
PUT/services/:idmemberAny of {name, policy_id, urgency, ack_timeout_min, auto_resolve_min, mapping}
DELETE/services/:idmemberRemoves the service
POST/services/:id/keysmemberA new integration key → {key}
DELETE/keys/:keymemberRevokes an integration key
GET PUT/services/:id/chatadminChat webhooks (slack, teams, discord, mattermost, telegram, ntfy); GET shows hosts only
GET POST/policiesviewer / memberEscalation policies: 1 to 20 levels of {timeout_min, targets, round_robin}, repeat up to 9
PUT DELETE/policies/:idmemberUpdate or delete a policy
GET POST/schedulesviewer / memberSchedules with who is on call now and the next shifts; create one
PUT DELETE/schedules/:idmemberUpdate or delete a schedule
GET/schedules/:id/roster?days=viewerWho is on call, shift by shift, for 1 to 60 days
POST/schedules/:id/overridesmember{user_id, start, end} (ms or ISO 8601), 90 days at most
DELETE/schedules/:id/overrides/:oidmemberRemoves an override
GET/oncallviewerWho is on call now on each schedule, and until when
GET POST/me/contactsanyYour contact methods (push, email, sms, voice); DELETE /me/contacts/:id removes one
GET PUT/me/rulesanyYour paging rules for high and low urgency, and handoff hours
POST/me/test-pagememberSends you a test page
GET PUT/telephonyadminYour Twilio or Telnyx account; GET shows provider, From number and the last 4 of the credential

Members, invites, API keys, usage and the audit log are the platform's endpoints under/api/orgs/:org/…; the matching MCP tools are listed on AI & MCP.

Alerts in: https://shift.nightroll.app

These paths take a service's integration key instead of an API key, and answer in the shape of the API they copy. See Integrations for each tool.

MethodPathWhat
POST/v2/enqueuePagerDuty Events API v2 (routing_key in the body)
POST/generic/2010-04-15/create_event.jsonPagerDuty Events API v1 (service_key in the body)
POST/v2/change/enqueueChange events: accepted (202), not stored
POST/i/KEYAlertmanager, Grafana, presets or any webhook
POST/v2/alertsOpsgenie: create (Authorization: GenieKey KEY)
GET/v2/alerts, /v2/alerts/:idOpsgenie: list and get
POST/v2/alerts/:id/close | acknowledge | unacknowledge | notesOpsgenie: actions
PUT/v2/alerts/:id/message | descriptionOpsgenie: edit
GET/v2/alerts/requests/:idOpsgenie: request status