Skip to content

REST API Service Status

Ed Mozley edited this page Jul 3, 2026 · 1 revision

🚦 REST API: Service Status

The complete usage guide for the Service Status module of the REST API — the health board and monitoring-driven incidents. Mirrors the interactive documentation at System → API → Documentation (with its live "Try it" tester).

Note

New to the API? The basics table on REST API: Tickets covers base URL, authentication, the response envelope, error codes, rate limits and PATCH semantics — identical across all modules.

What's distinctive about Service Status:

🧮 Status is derived, never stored A service has no status column — its live state is computed as the worst impact level across its open incidents, else Operational. The API runs the dashboard's exact worst-severity subquery, so the health board is one call.
🤖 Built for the monitoring round-trip Open an incident when a probe fails (the service degrades instantly), escalate the impact, resolve on recovery (the service returns to Operational automatically). This module is the natural target for alerting integrations.
📝 One narrative, not a timeline An incident's comment is a single field, overwritten on each update — the product has no append-only update feed. (A timeline table and a public unauthenticated status feed are both future candidates if a customer-facing page is ever wanted; today everything is key-authenticated.)
🎯 Per-service impact One incident can hit several services at different severities — services is an array of {service_id, impact_level} pairs.

🚀 Quick start — the full monitoring loop

B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_…"

# Probe fails → open an incident; the Email service flips to Degraded instantly
INC=$(curl -s -X POST "$B/service-status/incidents" -H "$K" -H "Content-Type: application/json" -d '{
  "title": "Email delivery delays",
  "comment": "SMTP queue growth detected by probe.",
  "services": [ { "service_id": 1, "impact_level": "Degraded" } ]
}' | jq -r '.data.id')

# It got worse → escalate
curl -s -X PATCH "$B/service-status/incidents/$INC" -H "$K" -H "Content-Type: application/json" \
  -d '{"status": "Identified", "services": [{"service_id": 1, "impact_level": "Major Outage"}]}'

# Probe recovers → resolve; resolved_at stamps, the service returns to Operational
curl -s -X PATCH "$B/service-status/incidents/$INC" -H "$K" -H "Content-Type: application/json" \
  -d '{"status": "Resolved", "comment": "Queue drained; delivery normal since 14:20."}'

🚦 Services (the health board)

🟢 GET /service-status/services   🔑 services.read

Active services (pass is_active=false for retired ones, q to search names), each with its derived live status:

{ "data": [ { "id": 1, "name": "Email", "description": "Exchange Online",
    "is_active": true, "display_order": 0,
    "current_status": { "name": "Degraded", "colour": "#eab308", "severity_order": 3 } } ] }

severity_order ranks worst-first (1 = Major Outage … Operational = 5), so a status page can sort or colour by it directly.

🟢 GET /service-status/services/{id}   🔑 services.read

The service plus its open incidents inline — everything a per-service status panel needs.

🔵 POST · 🟠 PATCH · 🔴 DELETE /service-status/services[/{id}]   🔑 services.create/update/delete

Only name is required to create; description, display_order and is_active optional. Deleting removes the service and its incident links transactionally (the incidents themselves survive).


🔥 Incidents

🟢 GET /service-status/incidents   🔑 service_incidents.read

Open-first, then most recently updated (the module's ordering).

Parameter Description
state open | resolved | all (default all)
service_id Incidents touching one service
q Search titles
created_since / resolved_since ISO 8601 bounds
page / per_page Pagination

The incident shape:

{ "id": 3, "title": "Email delivery delays",
  "status": { "id": 1, "name": "Investigating", "is_resolved": false, "colour": "#dc2626" },
  "comment": "SMTP queue growth detected by probe.",
  "services": [ { "service_id": 1, "name": "Email",
                  "impact": { "id": 3, "name": "Degraded", "colour": "#eab308", "severity_order": 3 } } ],
  "created_by": { "id": 1, "name": "Administrator" },
  "created_at": "2026-07-03T16:33:12Z", "updated_at": "2026-07-03T16:33:37Z", "resolved_at": null }

🔵 POST /service-status/incidents — open   🔑 service_incidents.create

Field Required Description
title Incident title
status / status_id Lifecycle status (default Investigating)
comment The current-state narrative
services Array of {service_id, impact_level | impact_level_id} — impact defaults Operational

Unknown services or impact levels are a 422 — stricter than the UI, which silently skips them (a monitoring integration should never half-apply). Creating directly in a resolved status stamps resolved_at. Returns 201.

🟠 PATCH /service-status/incidents/{id} — update / resolve   🔑 service_incidents.update

Update title, status, comment (replaces the narrative), and/or send services to replace the affected set. The resolution rule is the UI's exactly:

  • moving into a resolved-type status stamps resolved_at once (preserved if already set),
  • reopening (any non-resolved status) clears it.

🔴 DELETE /service-status/incidents/{id}   🔑 service_incidents.delete

Removes the incident and its service links, transactionally.


📚 Reference data

Under the shared 🔑 reference.read permission:

Endpoint Returns
🟢 GET /service-incident-statuses The lifecycle: Investigating → Identified → Monitoring → 3rd Party → Resolved (with is_resolved flags and colours — resolvedness is the flag, not the name)
🟢 GET /service-impact-levels Impact levels worst-first: Major Outage (1) → Partial Outage → Degraded → Maintenance → Operational → No Disruption

🧪 Worked example: chat-ops status summary

A read-only key (services: read + service_incidents: read):

B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_…"

# The board, one line per service, warning emoji when not Operational
curl -s -H "$K" "$B/service-status/services" \
  | jq -r '.data[] | "\(if .current_status.severity_order < 5 then "🔴" else "🟢" end) \(.name): \(.current_status.name)"'

# What's open right now, with affected services
curl -s -H "$K" "$B/service-status/incidents?state=open" \
  | jq -r '.data[] | "• \(.title) [\(.status.name)] — \(.services | map(.name) | join(", "))"'

Under the hood: REST API — How It Works · Other modules: Tickets · Assets · Problems · Changes · Knowledge · Tasks · CMDB · Contracts · Calendar · Software · Keys & permissions: System → API (System module) · Module docs: Service Status.

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally