Skip to content
AISARAISAR
REST API

Platform status

Public AISAR platform status (status.aisar.app) — three endpoints, no authorization: the current indicator plus a per-component signal, a 90-day history, and a feed of incidents/maintenance windows. The data is not scoped to any company or partner — any caller can read it.

Access

None of the three endpoints requires an Authorization header — they are open, tokenless routes, limited only by throttle:60,1 (60 requests per minute per IP). The response is a "raw" JSON object with no { data: ... } wrapper, unlike most other REST groups.

External status page mirror vs api's own data

summary and history are server-to-server mirrors of the matching files the external status-page node (status.aisar.app) publishes: summary is pulled every minute, history every hour (matching the node's own rebuild cadence). Both endpoints serve ONLY the cache of the last successful pull — they never make a live call to the status-page node at request time, and never fabricate a status: if no pull has ever succeeded, the response is 503, not a cheerful "all good".

incidents, by contrast, is NOT a mirror — it is a direct query against api's own tables (status_incidents/status_incident_updates), the same ones the admin panel already reads live. It therefore stays available even if the external status-page node is unreachable or the mirror has never run once, and it never goes stale between pull cycles the way summary/history can.

Platform components

All three endpoints use the same fixed set of 10 components: api, workspace, whatsapp, whatsapp_business, telegram, instagram, crm_integrations, telephony, ai_agents, broadcasts. The per-component signal values (components[key].signal, the daily status in history, component_impact on incidents): operational, degraded, partial_outage, major_outage, maintenance, unknown.

GET /status/summary — response fields

  • status.indicator — the page's overall indicator: none (all systems operational), minor, major, critical, maintenance, or unknown; status.description — a human-readable label for it.
  • components — an object keyed by component name; each value is {name, signal, reason_code, source}. source explains where the final value came from: edge (an emergency override set directly on the status-page node), incident (drawn from an active incident's component_impact), admin (a manual override from the admin panel), or auto (an automatically computed signal).
  • incidents / maintenances — only ACTIVE rows (unresolved incidents and maintenance windows within ±7 days), in the same field-whitelist shape as GET /status/incidents (see below).
  • generated_at, internal_age_seconds, external_age_seconds — honest freshness metrics of the status-page node's own underlying snapshot (not api's last pull time — that's the separate mirror_age_seconds, below).
  • unknown_component_count — how many of the 10 components are currently unknown (no data); an honest blind-spot metric, not a load figure.
  • attested — an OPTIONAL block {payload, signature, key_id}: an ECDSA P-256 signature of api's own internal snapshot, relayed verbatim through the status-page node. The field is absent when the server isn't configured to sign — do not treat it as required.
  • mirrored_at (ISO-8601, when api last successfully pulled summary.json) and mirror_age_seconds (recomputed honestly on every request) are added by api on top of the mirrored object.

GET /status/history — response shape

{components, mirrored_at, mirror_age_seconds} — the same top-level shape as summary. components is an object keyed by component name, each value a 90-point array of daily {date, status} entries (date as YYYY-MM-DD, status using the same signal scale as above). mirrored_at/mirror_age_seconds sit ALONGSIDE components, not inside it — iterate components for the component list, never the response's top level directly.

GET /status/incidents — parameters and response shape

  • days (optional query parameter, integer ≥1) — the trailing window in days. A value above the configured maximum is NOT rejected — it is silently capped (default and maximum: 90 days). A non-integer or ≤0 value → 422.
  • Response: {window_days, incidents, maintenances, generated_at} — window_days reports the window that was actually applied (possibly capped).
  • Each incidents/maintenances item is the same closed field whitelist as GET /status/summary: slug, kind (incident\|maintenance), impact (none\|minor\|major\|critical), status (for incident — investigating\|identified\|monitoring\|resolved; for maintenance — scheduled\|in_progress\|completed), components (list of affected keys), component_impact (an object of component → signal), started_at, resolved_at, scheduled_start_at, scheduled_end_at, title (a localized object, in production carrying ru/kk/en), postmortem_url, updates[] ({status, created_at, body, next_update_at}, body the same localized shape as title).
  • Only published rows (is_published = true) are returned, newest-started_at first; id, is_published, published_at, created_by, updated_by, origin never appear in the response.

Endpoints

MethodPath
GET/v1/public/status/summary

Current platform status and active incidents/maintenance (status.aisar.app mirror, every minute)

GET/v1/public/status/history

90-day per-component status history (status.aisar.app mirror, hourly)

GET/v1/public/status/incidents

Incident and maintenance feed for a period (api's own data, not a mirror)

Examples

Current platform status

Request

bash
curl "https://api.aisar.app/v1/public/status/summary"

Response

json
{
  "status": { "indicator": "minor", "description": "Частичное снижение производительности" },
  "components": {
    "api": { "name": "API", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "workspace": { "name": "Личный кабинет", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "whatsapp": { "name": "WhatsApp", "signal": "degraded", "reason_code": "channel_fleet_ratio", "source": "auto" },
    "whatsapp_business": { "name": "WhatsApp Business", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "telegram": { "name": "Telegram", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "instagram": { "name": "Instagram", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "crm_integrations": { "name": "CRM-интеграции", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "telephony": { "name": "Телефония", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "ai_agents": { "name": "ИИ-агенты", "signal": "operational", "reason_code": "healthy", "source": "auto" },
    "broadcasts": { "name": "Рассылки", "signal": "operational", "reason_code": "healthy", "source": "auto" }
  },
  "incidents": [
    {
      "slug": "whatsapp-degraded-20260907",
      "kind": "incident",
      "impact": "minor",
      "status": "monitoring",
      "components": ["whatsapp"],
      "component_impact": { "whatsapp": "degraded" },
      "started_at": "2026-09-07T08:12:00+00:00",
      "resolved_at": null,
      "scheduled_start_at": null,
      "scheduled_end_at": null,
      "title": { "ru": "Задержки доставки в WhatsApp у части каналов", "kk": "WhatsApp-та кейбір арналарда жеткізу кідірісі", "en": "WhatsApp delivery delays on some channels" },
      "postmortem_url": null,
      "updates": [
        {
          "status": "investigating",
          "created_at": "2026-09-07T08:12:00+00:00",
          "body": { "ru": "Наблюдаем повышенное количество отключений части WhatsApp-каналов, разбираемся.", "kk": "Кейбір WhatsApp арналарының ажырауы көбейгенін байқадық, тексеріп жатырмыз.", "en": "We're seeing an elevated number of WhatsApp channel disconnects and are investigating." },
          "next_update_at": "2026-09-07T09:00:00+00:00"
        },
        {
          "status": "monitoring",
          "created_at": "2026-09-07T08:50:00+00:00",
          "body": { "ru": "Основная причина устранена, наблюдаем за восстановлением затронутых каналов.", "kk": "Негізгі себеп жойылды, зардап шеккен арналардың қалпына келуін бақылап жатырмыз.", "en": "The root cause has been fixed; we're monitoring the affected channels as they recover." },
          "next_update_at": null
        }
      ]
    }
  ],
  "maintenances": [],
  "generated_at": "2026-09-07T09:14:00+00:00",
  "internal_age_seconds": 22,
  "external_age_seconds": 41,
  "unknown_component_count": 0,
  "mirrored_at": "2026-09-07T09:14:05+00:00",
  "mirror_age_seconds": 12
}

Mirror not populated yet

Request

bash
curl "https://api.aisar.app/v1/public/status/summary"

Response

json
{
  "error": "summary_unavailable"
}

90-day per-component history

Request

bash
curl "https://api.aisar.app/v1/public/status/history"

Response

json
{
  "components": {
    "api": [
      { "date": "2026-06-10", "status": "operational" },
      { "date": "2026-06-11", "status": "operational" }
    ],
    "whatsapp": [
      { "date": "2026-06-10", "status": "operational" },
      { "date": "2026-06-11", "status": "degraded" }
    ]
  },
  "mirrored_at": "2026-09-07T09:00:04+00:00",
  "mirror_age_seconds": 896
}

Incident feed for 30 days

Request

bash
curl "https://api.aisar.app/v1/public/status/incidents?days=30"

Response

json
{
  "window_days": 30,
  "incidents": [
    {
      "slug": "whatsapp-degraded-20260907",
      "kind": "incident",
      "impact": "minor",
      "status": "resolved",
      "components": ["whatsapp"],
      "component_impact": {},
      "started_at": "2026-09-07T08:12:00+00:00",
      "resolved_at": "2026-09-07T09:30:00+00:00",
      "scheduled_start_at": null,
      "scheduled_end_at": null,
      "title": { "ru": "Задержки доставки в WhatsApp у части каналов", "kk": "WhatsApp-та кейбір арналарда жеткізу кідірісі", "en": "WhatsApp delivery delays on some channels" },
      "postmortem_url": null,
      "updates": [
        {
          "status": "resolved",
          "created_at": "2026-09-07T09:30:00+00:00",
          "body": { "ru": "Инцидент устранён, все затронутые каналы восстановлены.", "kk": "Инцидент жойылды, барлық зардап шеккен арналар қалпына келтірілді.", "en": "The incident is resolved; every affected channel has recovered." },
          "next_update_at": null
        }
      ]
    }
  ],
  "maintenances": [
    {
      "slug": "db-maintenance-20260910",
      "kind": "maintenance",
      "impact": "none",
      "status": "completed",
      "components": ["api"],
      "component_impact": {},
      "started_at": null,
      "resolved_at": null,
      "scheduled_start_at": "2026-09-10T22:00:00+00:00",
      "scheduled_end_at": "2026-09-10T23:00:00+00:00",
      "title": { "ru": "Плановое обслуживание базы данных", "kk": "Дерекқорға жоспарлы техникалық қызмет көрсету", "en": "Scheduled database maintenance" },
      "postmortem_url": null,
      "updates": []
    }
  ],
  "generated_at": "2026-09-07T09:15:00+00:00"
}

Invalid days (422)

Request

bash
curl "https://api.aisar.app/v1/public/status/incidents?days=0"

Response

json
{
  "message": "The days field must be at least 1.",
  "errors": {
    "days": ["The days field must be at least 1."]
  }
}