EvoHub Docs Sign in

API

Status API

Use with AI
View as MarkdownThis page as plain text, for pasting into an AI tool Open in ClaudeAsk Claude questions about this page Open in ChatGPTAsk ChatGPT questions about this page
Connect to Cursor / VS Code / ClaudeSearch and read these docs from your AI tool (MCP server)

MCP server URL

https://docs-dev.evohub.io/mcp

Claude Code

claude mcp add --transport http evohub-docs-docs https://docs-dev.evohub.io/mcp

Claude (claude.ai and Claude Desktop): Settings → Connectors → Add custom connector, and paste the URL above.

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "evohub-docs-docs": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://docs-dev.evohub.io/mcp"
      ]
    }
  }
}

Cursor — ~/.cursor/mcp.json

{
  "mcpServers": {
    "evohub-docs-docs": {
      "url": "https://docs-dev.evohub.io/mcp"
    }
  }
}

VS Code — .vscode/mcp.json

{
  "servers": {
    "evohub-docs-docs": {
      "type": "http",
      "url": "https://docs-dev.evohub.io/mcp"
    }
  }
}

The Status API lets scripts and CI jobs do what the Status Pages console does: create pages and components, set a component's status by hand, post incidents and scheduled maintenance with their updates, look after subscribers, connect a custom domain and read visitor analytics. Every endpoint, with its parameters, schemas, errors and an example request, is in the Status API reference. This page shows the common tasks and the rules that apply to all of them.

Paths below are relative to https://evohub.io. Requests need an API key, sent as described in API overview, except the public page reads at the end.

Note

In the console, incidents and maintenance on a status page are run from On-Call, which publishes them for you. Use the On-Call API for that flow. The endpoints here write to the page directly, for teams that run their status page on its own.

Scopes

Each endpoint needs one scope. Give a key only the ones its job needs.

To Scope
List and read pages, their domain, logos and analytics status:page:read
Create, change and delete pages; theme, header, layout, logos, domain, analytics settings status:page:write
Read components status:component:read
Add, change, reorder, rename groups of, set the status of and delete components status:component:write
Read incidents status:incident:read
Create incidents, post and edit their updates, write postmortems status:incident:write
Read maintenance status:maintenance:read
Schedule maintenance and post its updates status:maintenance:write
Read subscribers status:subscriber:read
Remove subscribers, change subscription settings status:subscriber:write
Read the Status audit log status:audit:read

A key without the scope gets 403, never 401. See Errors.

Set a component's status

curl -X PATCH https://evohub.io/api/v1/components/$COMPONENT_ID/status \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"current_status": "degraded"}'

The status is one of operational, degraded, partial_outage, major_outage and maintenance. A component linked to an Uptime monitor (source: uptime_monitor) keeps showing its monitor's live state, whatever you set. List a page's components, with their ids, with GET /api/v1/pages/{pageID}/components.

Post an incident

curl -X POST https://evohub.io/api/v1/pages/$PAGE_ID/incidents \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "title": "Elevated API error rates",
        "impact": "major",
        "affected_component_ids": ["'"$COMPONENT_ID"'"],
        "body": "We are looking into elevated error rates on the API.",
        "managed_in": "status_page"
      }'

impact is none, minor, major or critical; it decides how the affected components show while the incident is open. With a body, confirmed subscribers who follow an affected component, or the whole page, get an email.

Then keep the timeline going and close it:

curl -X POST https://evohub.io/api/v1/pages/$PAGE_ID/incidents/$INCIDENT_ID/updates \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved", "body": "Error rates are back to normal."}'

Each update moves the incident to its status (investigating, identified, monitoring or resolved) and mails subscribers. Editing the incident with PATCH changes its title, impact or status without an update and without mail. After it is resolved, publish a postmortem with PUT …/incidents/{id}/postmortem and {"body": "…", "published": true}.

To record an incident that is already over, send started_at, resolved_at and resolution_body when you create it. It lands on the days it happened and mails nobody.

Schedule maintenance

curl -X POST https://evohub.io/api/v1/pages/$PAGE_ID/maintenances \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "title": "Database upgrade",
        "body": "Expect up to five minutes of read-only mode.",
        "scheduled_start": "2026-10-12T22:00:00Z",
        "scheduled_end": "2026-10-13T00:00:00Z",
        "affected_component_ids": ["'"$COMPONENT_ID"'"],
        "managed_in": "status_page"
      }'

Post in_progress and completed updates to …/maintenances/{id}/updates as the work goes. Setting the window to completed with PATCH also closes its timeline with "This maintenance has been completed."

Connect a custom domain

curl -X POST https://evohub.io/api/v1/pages/$PAGE_ID/domain \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "status.example.com"}'

Use a subdomain; an apex domain such as example.com is refused. Create the CNAME records the answer lists at your DNS provider, then poll GET /api/v1/pages/{pageID}/domain until status is active. See Custom domain.

Read visitor analytics

GET /api/v1/pages/{pageID}/analytics?from=2026-09-01&to=2026-09-30 returns views, visitors, feed and AI reads per day and the top routes, referrers, countries and devices. GET /api/v1/pages/analytics does the same across every page the key can see, with subscriber growth and incidents published. Download one report as CSV from …/analytics/export.csv?report=referrers.

Rules that apply everywhere

  • Teams. A page belongs to the whole organization or to one team. A key sees the organization-wide pages; an organization key scoped to a team also sees that team's. A page the key cannot see, and everything under it, answers 404, as if it did not exist.
  • Strict bodies. A field the endpoint does not take is refused with 400 INVALID_BODY, so a typo cannot be silently ignored.
  • Updates. A field you leave out keeps its value, on PUT of a page as on every PATCH. null clears a nullable field. A page's slug and team_id do not change through PUT: a different value is refused with VALIDATION_ERROR.
  • Errors. This service answers a bad field with VALIDATION_ERROR and the field in the message, and an unexpected failure with INTERNAL_ERROR.
  • Public reads. GET /api/v1/public/pages/{pageID} (or /by-domain/{domain}) and their feed.rss and feed.atom need no key and return only what visitors see. A private page answers 404.

Last updated