Skip to main content

Monitors

Configure what services to monitor in monitors.json. ShadowStatus supports 9 different monitor types for various use cases.

Basic Structure

monitors.json
{
"groups": [
{
"name": "Group Name",
"monitors": [
{ "name": "Monitor 1", "type": "http", "target": "https://example.com" }
]
}
],
"monitors": [
{ "name": "Ungrouped Monitor", "type": "ping", "target": "1.2.3.4" }
]
}
  • groups — Array of monitor groups (collapsible sections)
  • monitors — Array of ungrouped monitors (shown at top level)

Monitor Groups

Groups let you organize related monitors into collapsible sections.

{
"name": "Web Services",
"description": "Core web applications",
"defaultOpen": true,
"showGroupStatus": true,
"showGroupHistory": false,
"monitors": []
}
PropertyTypeDefaultDescription
namestringRequiredGroup display name
descriptionstringnullOptional description tooltip
defaultOpenbooleantrueStart expanded or collapsed
showGroupStatusbooleantrueShow aggregate status indicator
showGroupHistorybooleanfalseShow 90-day history for the group
monitorsarrayRequiredArray of monitors in this group

Common Monitor Options

These options apply to all monitor types:

{
"name": "My Service",
"type": "http",
"target": "https://example.com",
"description": "Main website",
"showTarget": true,
"showHistory": true,
"notify": true,
"inverse": false,
"applyToOverall": true,
"discordPingRole": "123456789"
}
PropertyTypeDefaultDescription
namestringRequiredDisplay name for the monitor
typestringRequiredMonitor type (see below)
targetstringRequired*What to monitor (*not required for manual)
descriptionstringnullTooltip description
showTargetbooleantrueDisplay the target URL publicly
showHistorybooleantrueShow 90-day uptime history
notifyboolean(from config)Send notifications for this monitor
inversebooleanfalseReverse logic (down = operational)
applyToOverallbooleantrueInclude in overall status calculation
discordPingRolestring(from config)Override Discord ping role for this monitor

Monitor Types

HTTP

Check HTTP/HTTPS endpoints for specific status codes.

{
"name": "Website",
"type": "http",
"target": "https://example.com",
"expectedStatus": [200, 301, 302],
"timeout": 10000
}
PropertyTypeDefaultDescription
targetstringRequiredFull URL to check
expectedStatusarray[200]HTTP status codes to consider "operational"
timeoutnumber10000Request timeout in milliseconds
tip

For APIs that return 404 on their root path, add 404 to expectedStatus:

"expectedStatus": [200, 404]

Ping

ICMP ping to check host availability.

{
"name": "Server",
"type": "ping",
"target": "192.168.1.1",
"timeout": 15
}
PropertyTypeDefaultDescription
targetstringRequiredIP address or hostname
timeoutnumber10Ping timeout in seconds
note

For IPv6 addresses, use bracket notation: [2001:db8::1]


TCP

Check if a TCP port is open and accepting connections.

{
"name": "Database",
"type": "tcp",
"target": "db.example.com:5432",
"timeout": 5000
}
PropertyTypeDefaultDescription
targetstringRequiredHost and port in host:port format
timeoutnumber10000Connection timeout in milliseconds

DNS

Verify DNS resolution and optionally check for expected IP.

{
"name": "Domain DNS",
"type": "dns",
"target": "example.com",
"recordType": "A",
"expectedIp": "93.184.216.34",
"timeout": 5000
}
PropertyTypeDefaultDescription
targetstringRequiredDomain name to resolve
recordTypestring"A"DNS record type: A, AAAA, MX, TXT, CNAME, NS
expectedIpstringnullExpected IP address (optional validation)
timeoutnumber5000Resolution timeout in milliseconds

JSON

Check JSON API responses for specific values.

{
"name": "API Health",
"type": "json",
"target": "https://api.example.com/health",
"jsonPath": "status",
"expectedValue": "ok",
"timeout": 10000
}
PropertyTypeDefaultDescription
targetstringRequiredAPI endpoint URL
jsonPathstring"status"Path to the JSON value (dot notation supported)
expectedValueanynullExpected value (null = just check existence)
timeoutnumber10000Request timeout in milliseconds

JSONPath Examples:

  • "status" — Top-level status field
  • "data.health" — Nested data.health field
  • "services.0.status" — First item in services array

StatusPage

Monitor third-party Atlassian StatusPage-powered status pages.

{
"name": "GitHub",
"type": "statuspage",
"target": "https://www.githubstatus.com",
"applyToOverall": false,
"notify": false
}
PropertyTypeDefaultDescription
targetstringRequiredStatusPage URL (Atlassian-powered)

Supported StatusPages include:

  • GitHub: https://www.githubstatus.com
  • Cloudflare: https://www.cloudflarestatus.com
  • Discord: https://discordstatus.com
  • Stripe: https://status.stripe.com
  • Many others using Atlassian StatusPage
tip

Set applyToOverall: false for third-party monitors so their outages don't affect your overall status.


Steam

Monitor Steam game servers using A2S_INFO protocol.

{
"name": "Game Server",
"type": "steam",
"target": "192.168.1.100",
"port": 27015,
"timeout": 5000
}
PropertyTypeDefaultDescription
targetstringRequiredServer IP or hostname
portnumber27015Query port (usually game port or game port + 1)
timeoutnumber5000Query timeout in milliseconds

Minecraft

Monitor Minecraft Java Edition servers.

{
"name": "Minecraft Server",
"type": "minecraft",
"target": "mc.example.com",
"port": 25565,
"timeout": 5000
}
PropertyTypeDefaultDescription
targetstringRequiredServer IP or hostname
portnumber25565Server port
timeoutnumber5000Connection timeout in milliseconds

Manual

Manually control status via GitHub Issues.

{
"name": "External Service",
"type": "manual"
}

Manual monitors don't have a target. Their status is controlled by creating GitHub Issues with the manual label (or your configured manualMonitorLabel).

To set manual monitor status:

  1. Create a GitHub Issue
  2. Set the title to the exact monitor name
  3. Add the manual label
  4. In the body, specify the status:
<!-- status: degraded -->
We're investigating reports of slowness with this service.

Available status values: operational, degraded, partial, major, maintenance

Close the issue to return to operational status.


Example Configurations

{
"groups": [
{
"name": "Web",
"defaultOpen": true,
"monitors": [
{
"name": "Website",
"type": "http",
"target": "https://example.com"
}
]
}
],
"monitors": []
}

Troubleshooting

HTTP Monitor Always Shows Down

  • Verify the URL is accessible from the public internet
  • Check if the site blocks automated requests (User-Agent filtering)
  • Add the actual status code to expectedStatus if it's not 200
  • Increase timeout for slow endpoints

Ping Not Working

  • Some hosts block ICMP ping requests
  • GitHub Actions runners may have limited ping capabilities
  • Consider using TCP or HTTP checks instead

StatusPage Shows Wrong Status

  • Ensure the URL is an Atlassian StatusPage
  • Some status pages use custom implementations that won't work
  • The monitor checks the API endpoint at /api/v2/status.json

Manual Monitor Not Updating

  • Ensure the issue title exactly matches the monitor name
  • Verify the correct label is applied
  • Check that the status comment format is correct