The Change Management plugin's API
Under /api/v1/x/changes, 404 while the plugin is off; changes:read, changes:write, and changes:approve to
decide. You see a change when you hold change.read in a unit of one of its services. Guide: changes.
| Endpoint | What |
|---|---|
GET ?status=&type=&risk=&serviceId=&orgId=&mine=&from=&to=&q=&page=&pageSize= | Changes: status open, done (newest first) or one status; mine me (you own, implement or asked for it), none (nobody implements it) or approve (waiting for your approval); person=<userId> changes that person owns or implements; from/to the planned window; serviceId the service or one of its offerings, as main or other service. |
GET count, GET options?orgId= | { approve, open, mine, unassigned } (open changes; yours to own, implement or that you asked for; nobody implementing); the categories, risk questions and required plans. |
POST | { serviceId, otherServiceIds, type (normal, emergency), title, description, categoryId, ownerId, implementerId, plannedStart, plannedEnd, urgency, caseRef or incidentId }. |
GET export?format=&columns= (the list's filters) | The list as a file: csv, xlsx or pdf; up to 20,000, logged with its filters, rows and checksums (exports). |
GET <id or key> | The change with approvalsList (current version; each approval with approverList, who could decide it then), schedule (windows and freezes per service), conflicts, blockers (what stops sending or starting it), links, tasks, updates and may. |
PATCH <id> | Edit; editing the plans, window, services, risk or customers of a change waiting for or past approval asks again. |
POST <id>/submit | A new version and its approvals (400 not_ready lists what is missing). |
POST <id>/approvals/<approvalId> | { decision: approve or reject, comment }; 403 separation_of_duties, 409 not_yet while an earlier stage waits. |
GET <id>/suspects | Incidents on its services that started while it ran or in the 4 hours after, not linked yet: { incidents: [{ id, key, title, status, startedAt }] }. Link one with POST <id>/links and role: caused. |
PUT <id>/legal-hold | { reason } sets a legal hold, { reason: null } lifts it (case.legal_hold). |
POST <id>/proceed | { reason }: past customers who haven't answered (change.manage). |
POST <id>/start, POST <id>/finish, POST <id>/review, POST <id>/cancel | 409 cannot_start says why; finish takes { outcome, note }; review { review }; cancel { reason }. |
POST <id>/notes, POST <id>/links, DELETE <id>/links/<kind>/<refId>, POST <id>/tasks, PATCH <id>/tasks/<taskId> | The timeline, links ({ kind: case or incident, ref, role }) and tasks. |
GET settings?orgId=, PATCH settings?orgId= | Settings (change.settings). |
GET settings/vocabulary?orgId= | What the policy editor picks from: teams, roles, units, accounts, account labels and properties, and the names of the people and services the policies name. |
GET settings/policies?orgId=, POST …, PATCH settings/policies/<id>?orgId= | Approval policies: { name, conditions, stages: [{ name, when?: conditions, approvers: [{ kind, ref, fallback?: [{ when?: { accountIds, labels, props }, approver: { kind: person | team | role, ref } }] }], need }], enabled }, where conditions is { types, risks, tiers, serviceIds, categoryIds, serviceUnitIds, accountLabels, accountProps: [{ key, values }], accountWithoutApprovers } (every one set must hold). fallback is only for customer: who approves for an account without approvers of its own; its approvals carry forAccount. kind is person, team, role, service_owner, customer or cab (the CAB, in a meeting: decided by the chair of a CAB meeting). |
GET settings/history?orgId= | Every change to the settings and policies. |
GET delegations, POST delegations, DELETE delegations/<id> | Your stand-ins: { deputyId, startsAt, endsAt }. |
POST from-template | { templateId, plannedStart, plannedEnd, title, outsideWindowReason, implementerId, externalRef, caseRef }: a standard change, scheduled at once (409 template_not_approved). |
GET <id>/gate | The deployment gate: { change, status, allowed, reasons }. |
GET report?days=&orgId=&tz= | Needs report.read: by type and outcome, successRate, emergencyShare, approvalLeadMinutes, causedIncidents, services. |
GET exceptions?from=&to=&orgId=, GET exceptions.csv | { exceptions: [{ changeId, key, title, what, detail, at }] } (the last year by default). |
GET emergencies?from=&to=&orgId=, GET emergencies.csv | The emergency register. |
GET templates?orgId=, GET templates/<id>, POST templates, PATCH templates/<id>, POST templates/<id>/submit, POST templates/<id>/decision, DELETE templates/<id> | Standard change templates: { name, description, serviceId, otherServiceIds, categoryId, impact, the plans, tasks }; a decision { decision, comment } by someone with change.approve who didn't write it. |
GET public/<slug>/approvals | No staff sign-in: the portal's signed-in contact's { signedIn, account, open, decided }. |
POST public/<slug>/approvals/<approvalId>/code, POST …/decision | From the portal's own page only (its origin): a code by email; then { decision, comment, code }. |
Service Configuration offers plannedWorkProvider (planned work for the portals and status pages) and
hasApprovers; Change Management uses both.
Work on a service. Incident, Problem and Change Management register a workProvider with Service Configuration
(itsm.workProvider({ type, label, isOn, rows, stats })): their records on a service and its offerings for the
service's dashboard and its Work table, read through their own access rules. A plugin built on Service
Configuration adds its own records the same way.
| Hook | Returns |
|---|---|
rows(scope, user, { serviceIds, open, q, person, updatedSince, take }) | { rows, total }, newest update first. |
stats(scope, user, serviceIds, period) | The counts, per-day series, facts and highlights. |