Incidents API Reference

The core platform incidents module exposes a REST API for managing incidents, correlation rules, team members, and real-time event streams. All endpoints return JSON.

Base URL: http://localhost:3003 (local) or your deployed core-platform backend.


Incidents

Auth + Permissions

All endpoints require dashboard JWT auth. Key permission checks:

  • incidents:view for read endpoints (list/detail/related/similar/runbook reads/SSE).
  • incidents:update_status for status transitions.
  • incidents:update for incident-runbook link/unlink actions.

GET /incidents

List incidents with optional filters.

Query Parameters

ParameterTypeDefaultDescription
statusstringFilter by status: OPEN, INVESTIGATING, REMEDIATING, RESOLVED, CLOSED
severitystringFilter by severity: LOW, MEDIUM, HIGH, CRITICAL
searchstringFull-text search across title, description, and affected services
servicestringFilter by affected service name (exact match against affectedServices array)
assigneeIdstringFilter by assigned team member UUID
sortBystringrecencySort order: recency (newest first) or severity (critical first)
deduplicatedstringfalseSet to true to hide child/merged incidents (only show root incidents)
limitnumber50Maximum number of results

Example

curl "http://localhost:3003/incidents?severity=HIGH&status=OPEN&sortBy=severity&deduplicated=true"

Response — 200 OK

[
  {
    "id": "a0000000-0000-4000-8000-000000000001",
    "title": "High error rate on billing-service",
    "description": "Error rate exceeded threshold...",
    "severity": "HIGH",
    "status": "OPEN",
    "affectedServices": ["billing-service"],
    "triggeringEventId": "evt-123",
    "assigneeId": null,
    "deduplicationKey": "error-rate:billing-service",
    "duplicateCount": 3,
    "lastSeenAt": "2026-03-15T10:30:00.000Z",
    "parentIncidentId": null,
    "diagnosisStatus": "COMPLETED",
    "diagnosis": {
      "rootCause": "...",
      "summary": "...",
      "impactedServices": ["..."],
      "suggestedFixes": [...],
      "confidenceScore": 0.85
    },
    "createdAt": "2026-03-15T10:00:00.000Z",
    "updatedAt": "2026-03-15T10:30:00.000Z"
  }
]

GET /incidents/export/csv

Export incidents as CSV using the same filters as GET /incidents (org-scoped).

Query Parameters

Supports all GET /incidents filters plus:

ParameterTypeDefaultDescription
limitnumber500Maximum rows exported

Example

curl -L "http://localhost:3003/incidents/export/csv?severity=CRITICAL&status=OPEN&deduplicated=true&limit=200" \
  -H "Authorization: Bearer <token>"

Response — 200 OK

  • Content-Type: text/csv; charset=utf-8
  • Content-Disposition: attachment; filename="incidents-export.csv"

CSV columns: id,title,severity,status,environment,primaryService,affectedServices,assigneeId,deduplicationKey,duplicateCount,createdAt,updatedAt,resolvedAt


GET /incidents/:id

Get a single incident by ID.

Diagnosis payloads may include suggestedFixes. The dashboard does not execute those suggestions directly from the incident endpoint; it opens a confirmation dialog, maps the selected suggestion into POST /remediation/request, then refetches remediation history for the incident. See Remediation API Reference for the execution request, approval, rejection, error, and optimistic UI contracts.

Example

curl "http://localhost:3003/incidents/a0000000-0000-4000-8000-000000000001"

POST /incidents

Manually create a new incident.

Request Body

FieldTypeRequiredDescription
titlestringYesHuman-readable summary
descriptionstringYesDetailed description
severitystringYesLOW, MEDIUM, HIGH, or CRITICAL
affectedServicesstring[]YesList of impacted service names

Example

curl -X POST http://localhost:3003/incidents \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Elevated latency on api-gateway",
    "description": "P99 latency exceeded 2s for the past 10 minutes",
    "severity": "HIGH",
    "affectedServices": ["api-gateway", "auth-service"]
  }'

Response — 201 Created

Returns the created incident object.


PATCH /incidents/:id/status

Update an incident's lifecycle status.

Request Body

FieldTypeRequiredDescription
statusstringYesNew status: OPEN, INVESTIGATING, REMEDIATING, RESOLVED, CLOSED

Example

curl -X PATCH http://localhost:3003/incidents/a0000000-0000-4000-8000-000000000001/status \
  -H "Content-Type: application/json" \
  -d '{ "status": "INVESTIGATING" }'

GET /incidents/:id/related

Get related/correlated incidents for a given incident. Returns incidents that share a parent or are linked via correlation rules.

Example

curl "http://localhost:3003/incidents/a0000000-0000-4000-8000-000000000001/related"

GET /incidents/:id/similar?limit=5

Get ranked similar incidents from same organization and last 180 days.

Query Parameters

ParameterTypeDefaultDescription
limitnumber5Max matches returned (1..20)

Response — 200 OK

[
  {
    "incidentId": "a0000000-0000-4000-8000-000000000002",
    "title": "Payment API timeout burst",
    "severity": "HIGH",
    "status": "RESOLVED",
    "score": 0.65,
    "reasons": ["shared service", "same severity", "resolved outcome"],
    "topSuccessfulActions": ["restart-service"],
    "mttrMinutes": 42,
    "resolvedAt": "2026-04-10T07:02:11.000Z"
  }
]

GET /incidents/:id/escalation-plan

Get escalation routing plan from ownership graph + on-call roster.

Dependency mapping impact:

  • blastRadiusCount is derived from service graph downstream edges.
  • reason and nextStep include graph health context (blast radius + unmapped edges).
  • Update dependencies via PUT /services/catalog/:serviceName/dependencies (see Service Catalog API).

Response — 200 OK

{
  "state": "ready",
  "primaryService": "payment-service",
  "ownerTeam": "payments-platform",
  "escalationPolicy": "pagerduty:payments-primary",
  "blastRadiusCount": 2,
  "reason": "payment-service mapped with escalation target. 2 downstream services in blast radius; dependency graph mapped.",
  "nextStep": "Page Alice via pagerduty:payments-primary. 2 downstream services in blast radius; dependency graph mapped.",
  "timeToAcknowledge": {
    "dueAt": "2026-04-13T12:05:00.000Z",
    "minutesRemaining": 4,
    "breached": false
  },
  "timeToEscalate": {
    "dueAt": "2026-04-13T12:10:00.000Z",
    "minutesRemaining": 9,
    "breached": false
  },
  "suggestedTargets": [
    {
      "id": "member_123",
      "name": "Alice",
      "email": "alice@example.com",
      "reason": "Service owner",
      "isOnCall": true
    }
  ]
}

GET /incidents/:id/priority-signal

Get operator priority signal for an incident using severity + timeline + event pressure, then apply service-tier SLO / error-budget pressure when catalog context exists.

SLO depth:

  • objectiveTargetPct gives explicit SLO target by service tier.
  • burnRatePctPerHour and projectedExhaustionHours expose budget-burn trajectory.
  • burnState + burnWindowHours show whether budget exhaustion risk is inside operator window.

Response — 200 OK

{
  "level": "critical",
  "label": "Critical",
  "reason": "Error budget nearly exhausted for tier-1 service.",
  "eventCount": 37,
  "durationMinutes": 154,
  "serviceCount": 3,
  "sloContext": {
    "tier": "tier-1",
    "riskThresholdMinutes": 15,
    "breachThresholdMinutes": 30,
    "objectiveTargetPct": 99.9,
    "errorBudgetRemainingPct": 8,
    "burnRatePctPerHour": 12.4,
    "projectedExhaustionHours": 0.6,
    "burnWindowHours": 6,
    "burnState": "critical",
    "atRisk": true,
    "breached": true
  }
}

GET /incidents/:id/preventive-signal

Get repeat-failure preventive signal for the incident's primary service.

Response — 200 OK

{
  "state": "at-risk",
  "summary": "api-gateway shows elevated repeat-incident pressure.",
  "reasons": [
    "4 api-gateway incidents in last 24h",
    "2 unresolved",
    "1 critical"
  ],
  "recommendation": "Increase monitoring sensitivity and validate fallback path before next deploy.",
  "actions": [
    {
      "id": "tighten-alert-thresholds",
      "title": "Tighten error/saturation alerts for api-gateway",
      "why": "4 incidents in 24h suggest early warning thresholds are too loose.",
      "priority": "medium",
      "category": "observability"
    },
    {
      "id": "refresh-runbook",
      "title": "Refresh api-gateway first-response runbook",
      "why": "Repeat incidents should map to a faster and more consistent first-response path.",
      "priority": "medium",
      "category": "runbook"
    }
  ],
  "windowHours": 24,
  "sameServiceIncidents": 4,
  "unresolvedIncidents": 2,
  "criticalIncidents": 1
}

GET /incidents/:id/change-risk

Get change-risk signal from correlated change insights + severity pressure.

Response — 200 OK

{
  "state": "elevated",
  "score": 57,
  "summary": "Recent changes may be contributing to current incident pressure.",
  "reasons": [
    "severity baseline 18",
    "3 correlated changes",
    "max change confidence 78%",
    "incident still active"
  ],
  "recommendation": "Review top correlated changes and confirm rollback/fallback readiness.",
  "changeCount": 3,
  "maxChangeConfidence": 0.78,
  "topChangeReason": "api deploy v1.2.3"
}

GET /incidents/:id/deployment-risk

Get deployment-pressure risk signal for the incident's primary service from recent deployments + post-deploy incident pressure.

Response — 200 OK

{
  "state": "high",
  "score": 71,
  "summary": "High deployment-linked pressure detected on api-gateway.",
  "reasons": [
    "2 deployments in last 24h",
    "2 unresolved incidents on api-gateway",
    "1 incident(s) after latest deployment"
  ],
  "recommendation": "Pause risky deploys for this service, validate rollback readiness, and review latest release diff now.",
  "windowHours": 24,
  "deploymentCount": 2,
  "unresolvedIncidents": 2,
  "postDeployIncidents": 1,
  "latestDeploymentAt": "2026-04-26T19:22:41.000Z"
}

POST /incidents/:id/escalate

Escalate now using ownership graph + suggested targets. Also assigns incident to chosen target.

Body (optional)

{
  "targetId": "member_123"
}

Response — 200 OK

{
  "escalated": true,
  "target": {
    "id": "member_123",
    "name": "Alice",
    "email": "alice@example.com"
  },
  "state": "ready",
  "nextStep": "Page Alice via pagerduty:payments-primary. 2 downstream services in blast radius; dependency graph mapped."
}

GET /incidents/:id/runbooks

List runbooks currently linked to incident.

Response — 200 OK

{
  "links": [
    {
      "incidentId": "a0000000-0000-4000-8000-000000000001",
      "runbookId": "r0000000-0000-4000-8000-000000000001",
      "source": "manual",
      "createdAt": "2026-04-13T02:12:00.000Z"
    }
  ],
  "runbooks": [
    {
      "id": "r0000000-0000-4000-8000-000000000001",
      "slug": "restart-payments",
      "title": "Restart payments service",
      "latestVersion": "1.2.0",
      "status": "published",
      "actionTags": ["restart-service"]
    }
  ]
}

GET /incidents/:id/runbooks/recommended

Get runbook recommendations from diagnosis action tags + links from similar incidents.

Response — 200 OK

{
  "runbooks": [
    {
      "id": "r0000000-0000-4000-8000-000000000001",
      "slug": "restart-payments",
      "title": "Restart payments service",
      "latestVersion": "1.2.0",
      "status": "published",
      "actionTags": ["restart-service"]
    }
  ],
  "linkedRunbookIds": ["r0000000-0000-4000-8000-000000000001"],
  "sources": {
    "actionTypes": ["restart-service"],
    "similarIncidentCount": 3
  }
}

POST /incidents/:id/runbooks/:runbookId/link

Link runbook to incident.

Response — 200 OK

{ "linked": true }

Unlink runbook from incident.

Response — 200 OK

{ "unlinked": true }

POST /incidents/:id/diagnose

Manually trigger an AI diagnosis for an incident. This is a fire-and-forget operation; the endpoint returns immediately while the diagnosis runs in the background. Progress updates are sent via the SSE stream.

Example

curl -X POST http://localhost:3003/incidents/a0000000-0000-4000-8000-000000000001/diagnose

Response — 200 OK

{ "queued": true }

POST /incidents/:id/diagnostic-tools/run

Run allowlisted, read-only diagnostic investigation tool for incident.

Safety model:

  • No arbitrary shell commands.
  • Tool type validated against typed allowlist.
  • Pod tools restricted to incident-scoped services + allowed namespaces.
  • AWS tools restricted to incident-scoped mapped resources (incident_resources) + allowlisted accounts.
  • Output summarized and stored with reference (rawRef), not dumped inline.
  • Every run emits incident timeline audit events (diagnosis_completed / diagnosis_failed) with metadata eventKind = diagnostic_tool_run / diagnostic_tool_failed.

Request Body

{
  "tool": {
    "type": "getPodLogs",
    "namespace": "production",
    "pod": "api-gateway-0",
    "tailLines": 200,
    "sinceSeconds": 900
  }
}

Supported tool types:

  • getPodLogs
  • describePod
  • getPodResources
  • getPodProcesses (ps aux only)
  • checkHttpHealth
  • getCloudWatchLogs
  • getRdsHealth
  • getAlb5xxMetrics
  • getLambdaErrors
  • getSqsBacklog
  • getEcsServiceHealth

Response — 200 OK

{
  "toolRunId": "a0000000-0000-4000-8000-000000000123",
  "summary": "Detected 2 key failure patterns in diagnostic output.",
  "keyPatterns": ["timeout", "connection refused"],
  "rawRef": "toolrun_a0000000-0000-4000-8000-000000000123",
  "status": "success"
}

GET /incidents/:id/resources

List incident-scoped diagnostic resources used by AWS/Kubernetes tool validation.

Response — 200 OK

[
  {
    "id": "b0000000-0000-4000-8000-000000000001",
    "incidentId": "a0000000-0000-4000-8000-000000000001",
    "organizationId": "org_123",
    "provider": "aws",
    "resourceType": "cloudwatch-log-group",
    "resourceId": "/aws/ecs/api-gateway",
    "resourceArn": null,
    "region": "us-east-1",
    "createdAt": "2026-04-23T02:15:00.000Z"
  }
]

PUT /incidents/:id/resources

Replace incident-scoped diagnostic resources (deduped by provider/type/id|arn|region).

Request Body

{
  "resources": [
    {
      "provider": "aws",
      "resourceType": "alb",
      "resourceArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/api-gw/abc123",
      "region": "us-east-1"
    },
    {
      "provider": "aws",
      "resourceType": "lambda-function",
      "resourceId": "api-gateway-edge-handler",
      "region": "us-east-1"
    }
  ]
}

Response — 200 OK

{
  "updated": true,
  "resources": [
    {
      "id": "b0000000-0000-4000-8000-000000000001",
      "incidentId": "a0000000-0000-4000-8000-000000000001",
      "organizationId": "org_123",
      "provider": "aws",
      "resourceType": "alb",
      "resourceId": null,
      "resourceArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/api-gw/abc123",
      "region": "us-east-1",
      "createdAt": "2026-04-23T02:15:00.000Z"
    }
  ]
}

GET /incidents/:id/diagnostic-tools/runs?limit=20

List recent diagnostic tool runs for incident investigation timeline.

Query Parameters

ParameterTypeDefaultDescription
limitnumber20Max runs returned (1..100)
fromstring (ISO datetime)noneInclude runs with startedAt >= from
tostring (ISO datetime)noneInclude runs with startedAt <= to

Response — 200 OK

[
  {
    "id": "a0000000-0000-4000-8000-000000000123",
    "toolType": "getPodLogs",
    "status": "success",
    "summary": "Repeated DB timeout errors in last 200 lines.",
    "keyPatterns": ["timeout", "connection refused"],
    "outputRef": "toolrun_a0000000-0000-4000-8000-000000000123",
    "startedAt": "2026-04-21T09:45:01.000Z",
    "completedAt": "2026-04-21T09:45:03.000Z",
    "error": null
  }
]

GET /incidents/:id/diagnostic-tools/metrics?hours=24

Compact rollup for diagnostic runs in recent time window.

Response — 200 OK

{
  "windowHours": 24,
  "total": 12,
  "success": 8,
  "failed": 3,
  "running": 1,
  "truncated": 2,
  "byProvider": [
    {
      "provider": "aws",
      "total": 8,
      "success": 6,
      "failed": 2,
      "running": 0,
      "truncated": 2
    },
    {
      "provider": "kubernetes",
      "total": 4,
      "success": 2,
      "failed": 1,
      "running": 1,
      "truncated": 0
    }
  ],
  "topFailingTool": {
    "toolType": "getCloudWatchLogs",
    "failed": 2
  },
  "failurePatterns": [
    { "pattern": "timeout", "count": 2 },
    { "pattern": "throttling", "count": 1 }
  ],
  "byTool": [
    {
      "toolType": "getCloudWatchLogs",
      "total": 5,
      "success": 3,
      "failed": 2,
      "running": 0,
      "truncated": 2
    },
    {
      "toolType": "getRdsHealth",
      "total": 3,
      "success": 3,
      "failed": 0,
      "running": 0,
      "truncated": 0
    }
  ]
}

GET /incidents/:id/diagnostic-tools/runs/:runId

Fetch detail for a single diagnostic tool run.

Response — 200 OK

{
  "id": "a0000000-0000-4000-8000-000000000123",
  "incidentId": "a0000000-0000-4000-8000-000000000001",
  "toolType": "getPodLogs",
  "status": "success",
  "parameters": {
    "type": "getPodLogs",
    "namespace": "production",
    "pod": "api-gateway-0",
    "tailLines": 200,
    "sinceSeconds": 900
  },
  "summary": "Repeated DB timeout errors in last 200 lines.",
  "keyPatterns": ["timeout", "connection refused"],
  "outputRef": "toolrun_a0000000-0000-4000-8000-000000000123",
  "rawOutputPreview": "…truncated diagnostic output preview…",
  "hasRawOutput": true,
  "startedAt": "2026-04-21T09:45:01.000Z",
  "completedAt": "2026-04-21T09:45:03.000Z",
  "error": null
}

POST /incidents/:id/workflow-event

Log structured incident workflow marker for stakeholder communication, escalation, or handoff.

Request Body

{
  "type": "stakeholder_update_sent",
  "detail": "Customer impact identified. Mitigation in progress; next update in 15m.",
  "metadata": {
    "templateKey": "stakeholder-mitigation",
    "channel": "slack",
    "target": "platform-oncall"
  }
}

Response — 200 OK

{ "created": true }

GET /incidents/:id/events

Return incident workflow/events timeline (includes workflow markers + status/diagnosis/postmortem events).

Response — 200 OK

[
  {
    "id": "evt_123",
    "incidentId": "a0000000-0000-4000-8000-000000000001",
    "type": "stakeholder_update_sent",
    "title": "Stakeholder update sent",
    "detail": "Responder sent stakeholder update via slack for this incident.",
    "metadata": {
      "templateKey": "stakeholder-mitigation",
      "channel": "slack"
    },
    "createdAt": "2026-04-19T06:00:00.000Z"
  }
]

Incident Statistics

GET /incidents/stats

Get aggregate incident statistics.

Query Parameters

ParameterTypeDefaultDescription
daysnumberOnly count incidents from the last N days. Omit for all-time stats

Response — 200 OK

{
  "activeCount": 12,
  "resolvedCount": 45,
  "totalCount": 57,
  "avgRecoveryMinutes": 34.5,
  "bySeverity": {
    "CRITICAL": 2,
    "HIGH": 5,
    "MEDIUM": 3,
    "LOW": 2
  },
  "affectedServices": ["billing-service", "api-gateway"],
  "allServices": ["billing-service", "api-gateway", "auth-service", "checkout-service"]
}

GET /incidents/timeline

Get hourly incident counts for charting.

Query Parameters

ParameterTypeDefaultDescription
hoursnumber24Number of hours to look back

Response — 200 OK

[
  { "hour": "2026-03-15T09:00:00.000Z", "count": 3 },
  { "hour": "2026-03-15T10:00:00.000Z", "count": 1 },
  { "hour": "2026-03-15T11:00:00.000Z", "count": 0 }
]

Comments

GET /incidents/:id/comments

List comments for an incident, ordered by most recent first.

Response — 200 OK

[
  {
    "id": "c0000000-0000-4000-8000-000000000001",
    "incidentId": "a0000000-0000-4000-8000-000000000001",
    "author": "Jane Smith",
    "body": "Investigating — looks like a connection pool issue.",
    "createdAt": "2026-03-15T10:15:00.000Z",
    "updatedAt": "2026-03-15T10:15:00.000Z"
  }
]

POST /incidents/:id/comments

Add a comment to an incident.

Request Body

FieldTypeRequiredDescription
authorstringYesName of the commenter
bodystringYesComment text

Example

curl -X POST http://localhost:3003/incidents/a0000000-0000-4000-8000-000000000001/comments \
  -H "Content-Type: application/json" \
  -d '{ "author": "Jane Smith", "body": "Restarted pods, monitoring recovery." }'

DELETE /incidents/:id/comments/:commentId

Delete a comment.

Response — 200 OK

{ "deleted": true }

Real-time Stream

GET /incidents/stream (SSE)

Server-Sent Events stream of incident updates. Emits an event whenever an incident is created or its status changes.

Example

curl -N http://localhost:3003/incidents/stream
data: {"id":"a0000000-...","title":"High error rate on billing-service","severity":"HIGH","status":"OPEN",...}

data: {"id":"a0000000-...","title":"High error rate on billing-service","severity":"HIGH","status":"INVESTIGATING",...}

The dashboard uses this stream to update the incident list in real time without polling.


Correlation Rules

GET /correlation/rules

List all correlation rules.

Response — 200 OK

[
  {
    "id": "r0000000-0000-4000-8000-000000000001",
    "name": "Same-service error storm",
    "description": "Merge incidents from the same service within 10 minutes",
    "enabled": true,
    "conditions": {
      "matchFields": ["service"],
      "timeWindowMinutes": 10
    },
    "action": "merge",
    "priority": 10,
    "createdAt": "2026-03-10T00:00:00.000Z",
    "updatedAt": "2026-03-10T00:00:00.000Z"
  }
]

GET /correlation/rules/:id

Get a single correlation rule by ID.


GET /correlation/rules/tuning/recommendations

Get adaptive priority recommendations computed from recent correlation outcomes.

Response — 200 OK

{
  "lookbackDays": 30,
  "recommendations": [
    {
      "ruleId": "r0000000-0000-4000-8000-000000000001",
      "name": "Same-service error storm",
      "currentPriority": 10,
      "suggestedPriority": 18,
      "recommendation": "increase",
      "usageCount": 12,
      "resolvedCount": 10,
      "successRate": 0.83,
      "rationale": "10/12 correlated incidents resolved after rule applied (83%)."
    }
  ]
}

POST /correlation/rules/tuning/auto-apply

Auto-apply the top safe recommendation when guardrails pass.

Request Body

FieldTypeRequiredDescription
lookbackDaysnumberNoWindow for outcome analysis (1-90, default 30)

Response — 200 OK

{
  "applied": true,
  "lookbackDays": 30,
  "ruleId": "r0000000-0000-4000-8000-000000000001",
  "name": "Same-service error storm",
  "previousPriority": 10,
  "appliedPriority": 18,
  "recommendation": "increase"
}

When no safe recommendation passes guardrails:

{
  "applied": false,
  "lookbackDays": 30,
  "reason": "No safe recommendation met auto-apply guardrails."
}

POST /correlation/rules

Create a new correlation rule.

Request Body

FieldTypeRequiredDescription
namestringYesHuman-readable rule name
descriptionstringYesWhat this rule does
conditionsobjectYesMatch criteria (see below)
actionstringYesmerge, group, or suppress
prioritynumberNoEvaluation order (default: 0)

Conditions Object

FieldTypeRequiredDescription
matchFieldsstring[]YesFields to compare: service, signalType, severity
timeWindowMinutesnumberYesHow close in time incidents must be
severitiesstring[]NoOnly match these severities
signalTypesstring[]NoOnly match these signal types

Example

curl -X POST http://localhost:3003/correlation/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cross-service cascade",
    "description": "Group incidents affecting different services within a 5-minute window",
    "conditions": {
      "matchFields": ["signalType"],
      "timeWindowMinutes": 5,
      "severities": ["HIGH", "CRITICAL"]
    },
    "action": "group",
    "priority": 5
  }'

PUT /correlation/rules/:id

Update an existing correlation rule. Accepts partial updates.


DELETE /correlation/rules/:id

Delete a correlation rule.

Response — 200 OK

{ "deleted": true }

Team

GET /team

List all team members.

Response — 200 OK

[
  {
    "id": "t0000000-0000-4000-8000-000000000001",
    "name": "Jane Smith",
    "email": "jane@example.com",
    "role": "SRE Lead",
    "avatarUrl": null,
    "isOnCall": true,
    "createdAt": "2026-03-01T00:00:00.000Z"
  }
]

GET /team/on-call

List team members currently on call.


POST /team

Add a new team member.

Request Body

FieldTypeRequiredDescription
namestringYesFull name
emailstringYesEmail address
rolestringNoRole/title (e.g. SRE, Platform Engineer)
avatarUrlstringNoURL to avatar image

PATCH /team/:id/on-call

Toggle on-call status for a team member.

Request Body

FieldTypeRequiredDescription
isOnCallbooleanYesWhether the member is on call

DELETE /team/:id

Remove a team member.


PATCH /team/incidents/:incidentId/assign

Assign an incident to a team member.

Request Body

FieldTypeRequiredDescription
assigneeIdstring | nullYesTeam member UUID, or null to unassign

Example

curl -X PATCH http://localhost:3003/team/incidents/a0000000-0000-4000-8000-000000000001/assign \
  -H "Content-Type: application/json" \
  -d '{ "assigneeId": "t0000000-0000-4000-8000-000000000001" }'

Interactive API Docs

When running locally, visit: