GraphQL API
Overview
The GraphQL API provides a flexible, efficient interface for querying and mutating incident data. It’s designed for mobile and web clients that need to minimize data transfer and network requests.
Endpoint: http://localhost:8080/api/v1/graphql
Authentication: Bearer token (JWT)
Playground: http://localhost:8080/graphql/playground (development mode only)
Authentication
All GraphQL requests require a valid JWT token in the Authorization header:
curl -X POST http://localhost:8080/api/v1/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"query": "{ myIncidents { id title } }"}'Schema
Enums
enum Severity {
SEV_1
SEV_2
SEV_3
SEV_4
}
enum Status {
OPEN
ACKNOWLEDGED
MITIGATED
RESOLVED
CLOSED
DUPLICATE
CANCELED
}
enum RACIRole {
IC
OPS
COMMS
SECURITY
PRIVACY
}
enum ActionType {
ACK
ESCALATE
JOIN_WAR_ROOM
ADD_NOTE
CHANGE_SEVERITY
ASSIGN_ROLE
}Types
type IncidentSummary {
id: ID!
title: String!
severity: Severity!
status: Status!
lastUpdate: DateTime!
}
type IncidentMobileView {
id: ID!
title: String!
severity: Severity!
status: Status!
assignedTo: UserSummary
lastUpdate: String!
warRoomLink: String
quickTimeline: [TimelineEventSummary!]!
}
type MobileAction {
id: ID!
label: String!
icon: String!
actionType: ActionType!
enabled: Boolean!
confirmText: String
}
type NotificationPreferences {
userId: ID!
pushEnabled: Boolean!
severityFilter: [Severity!]!
quietHours: QuietHours
channels: [String!]!
}Queries
type Query {
# Get incidents assigned to the current user (array filters)
myIncidents(limit: Int = 20, status: [Status!], severity: [Severity!]): [IncidentSummary!]!
# Get mobile-optimized incident details (limited timeline)
incidentStatus(id: ID!): IncidentMobileView
# Get available quick actions based on user role and incident state
quickActions(incidentId: ID!): [MobileAction!]!
# Get user's notification preferences
notificationSettings: NotificationPreferences
}Mutations
type Mutation {
# Declare a new incident
declareIncident(input: DeclareIncidentInput!): Incident!
# Acknowledge an incident
ackIncident(id: ID!): Incident!
# Add a note to an incident
addNote(incidentId: ID!, content: String!): Note!
# Assign a role on an incident
assignRole(incidentId: ID!, role: RACIRole!, userId: ID!): Incident!
# Update notification preferences
updateNotificationSettings(input: NotificationPreferencesInput!): NotificationPreferences!
}
input DeclareIncidentInput {
title: String!
severity: Severity!
services: [String!]
labels: JSON
visibility: String
}
input NotificationPreferencesInput {
pushEnabled: Boolean
severityFilter: [Severity!]
quietHours: QuietHoursInput
channels: [String!]
}Example Queries
List My Incidents
query MyIncidents {
myIncidents(status: [OPEN, ACKNOWLEDGED], limit: 10) {
id
title
severity
status
lastUpdate
}
}Get Incident Details (Mobile View)
query IncidentDetails($id: ID!) {
incidentStatus(id: $id) {
id
title
severity
status
lastUpdate
warRoomLink
quickTimeline {
id
type
summary
time
}
}
}Variables:
{
"id": "INC-12345"
}Get Quick Actions
query QuickActions($incidentId: ID!) {
quickActions(incidentId: $incidentId) {
id
label
icon
actionType
enabled
confirmText
}
}Example Mutations
Declare Incident
mutation DeclareIncident($input: DeclareIncidentInput!) {
declareIncident(input: $input) {
id
title
severity
status
createdAt
}
}Variables:
{
"input": {
"title": "Database Connection Timeout",
"severity": "SEV_2",
"services": ["auth-service"]
}
}Acknowledge Incident
mutation AckIncident($id: ID!) {
ackIncident(id: $id) {
id
status
updatedAt
}
}Add Note
mutation AddNote($incidentId: ID!, $content: String!) {
addNote(incidentId: $incidentId, content: $content) {
id
content
createdAt
}
}Variables:
{
"incidentId": "INC-12345",
"content": "Investigating database connection pool exhaustion"
}Update Notification Preferences
mutation UpdateNotifications($input: NotificationPreferencesInput!) {
updateNotificationSettings(input: $input) {
pushEnabled
severityFilter
channels
}
}Variables:
{
"input": {
"pushEnabled": true,
"severityFilter": ["SEV_1", "SEV_2"],
"channels": ["push", "email"]
}
}Using with curl
Query
curl -X POST http://localhost:8080/api/v1/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"query": "query { myIncidents { id title severity } }"
}'Mutation with Variables
curl -X POST http://localhost:8080/api/v1/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"query": "mutation($id: ID!) { ackIncident(id: $id) { id status } }",
"variables": {"id": "INC-12345"}
}'Error Handling
GraphQL errors are returned in the standard format:
{
"errors": [
{
"message": "incident not found",
"path": ["incidentStatus"],
"extensions": {
"code": "NOT_FOUND"
}
}
],
"data": {
"incidentStatus": null
}
}Query Complexity
The API enforces a maximum query complexity of 1000 to prevent abuse. Complex nested queries may be rejected if they exceed this limit.
Development Playground
In development mode, a GraphQL Playground is available at:
http://localhost:8080/graphql/playground
This provides an interactive IDE for exploring the schema and testing queries.