Skip to main content

Status API

Public service-health endpoints — current status, historical uptime, and the incident feed that power status.callmissed.com.

These endpoints are public (no auth) and back status.callmissed.com. Use them to embed live status in your own dashboards or to gate automated jobs on platform health.

Credential class: none

Send no Authorization header. A dashboard JWT or a cm_ API key is accepted but ignored: these routes have no auth dependency and return identical data either way. They are not tenant-scoped, so nothing here reveals your account.

Base URL for every example: https://api.callmissed.com. Errors are {"detail": "..."}; out-of-range query parameters are 422.

The JSON endpoints share the same status vocabulary:

status valueMeaning
operationalHealthy
degradedWorking with reduced quality
downNot serving
not_configuredNot enabled on this deployment
unknownNo data recorded for that day (uptime only)

GET /api/v1/status

Live health snapshot. No parameters.

curl https://api.callmissed.com/api/v1/status
{
  "overall": "operational",
  "checked_at": "2026-08-04T10:31:07.512004+00:00",
  "services": [
    {
      "name": "CallMissed API",
      "group": "infrastructure",
      "status": "operational",
      "description": "REST API, dashboard, webhooks, and API keys",
      "latency_ms": 4
    },
    {
      "name": "AI, speech & language",
      "group": "ai",
      "status": "operational",
      "description": "Chat, speech-to-text, text-to-speech, and embeddings-compatible routes"
    },
    {
      "name": "Billing & checkout",
      "group": "payments",
      "status": "operational",
      "description": "Subscriptions and one-time payments"
    },
    {
      "name": "WhatsApp Business",
      "group": "channels",
      "status": "operational",
      "description": "Meta WhatsApp Cloud API"
    },
    {
      "name": "Voice & SMS",
      "group": "channels",
      "status": "operational",
      "description": "PSTN voice and SMS"
    },
    {
      "name": "Transactional email",
      "group": "notifications",
      "status": "operational",
      "description": "Account notifications and receipts"
    }
  ],
  "self_heal": [],
  "interval_seconds": 30
}
FieldTypeNotes
overallstringdown if any monitored row is down, else degraded if any is degraded, else operational. Rows with not_configured are ignored
checked_atstringISO-8601 UTC timestamp of this check
services[].namestringHuman label
services[].groupstringOne of infrastructure, ai, payments, channels, notifications
services[].statusstringSee the vocabulary above
services[].descriptionstringWhat the row covers
services[].latency_msintegerOptional. Present only where a live latency was measured
services[].checked_atstringOptional. ISO-8601 UTC time this row was last checked
services[].ciobject | nullOptional. Latest automated API check for the row: status (operational or degraded) and checked_at
self_heal[]arrayAutomatic recoveries in the last 7 days, each with at, component (a services[].name), and result (recovered or still_failing)
interval_secondsintegerHow often the snapshot is refreshed

To gate a job on platform health, poll this and require overall == "operational". Other fields may appear in the response; treat only the ones above as stable.

GET /api/v1/status/stream

The same payload as GET /api/v1/status, pushed as Server-Sent Events: one status event on connect and another on every change, with a : ping comment every 25 seconds to keep the connection open.

curl -N https://api.callmissed.com/api/v1/status/stream
event: status
data: {"overall":"operational","checked_at":"…","services":[…]}

Connections are capped: too many from one client returns 429, and 503 means the stream is at capacity — fall back to polling GET /api/v1/status.

GET /api/v1/status/uptime

Per-service daily uptime for a rolling window ending today.

ParameterTypeRequiredConstraints
daysintegerNo1 <= days <= 90, default 90
curl "https://api.callmissed.com/api/v1/status/uptime?days=30"
{
  "days": 30,
  "services": [
    {
      "service_name": "CallMissed API",
      "uptime_percent": 99.94,
      "daily": [
        {
          "date": "2026-07-06",
          "total_checks": 288,
          "operational_checks": 288,
          "degraded_checks": 0,
          "down_checks": 0,
          "worst_status": "operational"
        },
        {
          "date": "2026-07-07",
          "total_checks": 0,
          "operational_checks": 0,
          "degraded_checks": 0,
          "down_checks": 0,
          "worst_status": "unknown"
        }
      ]
    }
  ]
}

daily always contains exactly days entries, oldest first. Days with no recorded checks are returned as zero-filled placeholders with worst_status: "unknown" so a chart axis stays continuous.

uptime_percent counts a degraded check as half an operational one:

uptime_percent = round(((operational + 0.5 * degraded) / total) * 100, 2)

It is 0.0 when the window contains no checks at all. Services are sorted by name.

422 when days is outside 1 .. 90.

GET /api/v1/status/incidents

Incidents overlapping the requested window, newest first. An incident is included when it started before now and either has not ended or ended inside the window.

ParameterTypeRequiredConstraints
daysintegerNo1 <= days <= 90, default 7
curl "https://api.callmissed.com/api/v1/status/incidents?days=7"
{
  "days": 7,
  "incidents": [
    {
      "id": "b7c8d9e0-f1a2-4b3c-8d4e-5f6a7b8c9d0e",
      "service_name": "CallMissed API",
      "severity": "degraded",
      "title": "Elevated latency on the CallMissed API",
      "summary": "Requests were slower than normal for roughly 20 minutes.",
      "started_at": "2026-08-01T04:12:00+00:00",
      "ended_at": "2026-08-01T04:33:00+00:00",
      "resolved": true
    }
  ]
}
FieldTypeNotes
idstringUUID
service_namestringMatches a services[].name from /status
severitystringdegraded or down
titlestringGenerated from service and severity when no custom title was written
summarystring | nullOptional detail
started_atstringISO-8601 UTC
ended_atstring | nullnull while the incident is ongoing
resolvedbooleanWhether the incident is closed

incidents is an empty array when the window is clean. 422 when days is outside 1 .. 90.