Перейти к содержимому
AISARAISAR
REST API

Статус платформы

Публичный статус AISAR (status.aisar.app) — три эндпоинта без авторизации: текущий индикатор и сигнал по каждому компоненту платформы, 90-дневная история и лента инцидентов/технических работ. Данные не привязаны ни к компании, ни к партнёру — доступны любому вызывающему.

Доступ

Ни один из трёх эндпоинтов не требует заголовка Authorization — это открытые, безтокенные ручки, ограниченные только throttle:60,1 (60 запросов в минуту на IP). Ответ — «сырой» JSON-объект без обёртки { data: ... }, в отличие от большинства остальных REST-групп.

Зеркало edge01 vs собственные данные api

summary и history — server-to-server зеркала соответствующих файлов, которые публикует edge01 (status.aisar.app): summary подтягивается раз в минуту, history — раз в час (с тем же тактом, с каким его пересобирает сам edge01). Оба эндпоинта отдают ТОЛЬКО кэш последнего успешного pull — никогда не выполняют живой запрос к edge01 в момент HTTP-вызова и никогда не выдумывают статус: если ни одного успешного pull ещё не было, ответ — 503, а не бодрый «всё хорошо».

incidents, наоборот, НЕ зеркало — это прямой запрос к собственным таблицам api (status_incidents/status_incident_updates), тем же, что уже показывает админ-панель. Поэтому он остаётся доступен, даже если edge01 недоступен или зеркалирование ни разу не отработало, и никогда не устаревает между циклами так, как могут устареть summary/history.

Компоненты платформы

Все три эндпоинта используют один и тот же фиксированный набор из 10 компонентов: api, workspace, whatsapp, whatsapp_business, telegram, instagram, crm_integrations, telephony, ai_agents, broadcasts. Значения сигнала по компоненту (components[key].signal, ежедневный status в history, component_impact в инцидентах): operational, degraded, partial_outage, major_outage, maintenance, unknown.

GET /status/summary — поля ответа

  • status.indicator — общий индикатор страницы: none (всё работает), minor, major, critical, maintenance или unknown; status.description — человекочитаемая подпись к нему.
  • components — объект, ключ = имя компонента; значение — {name, signal, reason_code, source}. source объясняет, откуда взялось итоговое значение: edge (аварийный override с самого edge01), incident (взято из component_impact активного инцидента), admin (ручной override из админ-панели) или auto (автоматически вычисленный сигнал).
  • incidents / maintenances — только АКТИВНЫЕ записи (неразрешённые инциденты и окна работ в пределах ±7 дней), в том же формате whitelist-полей, что и у GET /status/incidents (см. ниже).
  • generated_at, internal_age_seconds, external_age_seconds — честные метрики свежести исходного снапшота edge01 (не время последнего pull api — это отдельно mirror_age_seconds, см. ниже).
  • unknown_component_count — сколько из 10 компонентов сейчас unknown (нет данных); это честная метрика слепоты по сигналу, а не нагрузка платформы.
  • attested — ОПЦИОНАЛЬНЫЙ блок {payload, signature, key_id}: подпись ECDSA P-256 внутреннего снапшота api, перевозимая через edge01 дословно. Поле отсутствует, если сервер не настроен на подпись, — не считайте его обязательным.
  • mirrored_at (ISO-8601, когда api в последний раз успешно забрал summary.json) и mirror_age_seconds (честно вычисляемый на каждый запрос возраст этого зеркала) добавляются api поверх зеркалируемого объекта.

GET /status/history — форма ответа

{components, mirrored_at, mirror_age_seconds} — та же форма верхнего уровня, что и у summary. components — объект, ключ — имя компонента, значение — массив из 90 дневных точек {date, status} (date в формате YYYY-MM-DD, status — та же шкала сигналов, что и выше). mirrored_at/mirror_age_seconds лежат РЯДОМ с components, а не внутри него, — не перебирайте верхний уровень ответа как список компонентов, только components.

GET /status/incidents — параметры и форма ответа

  • days (необязательный query-параметр, целое ≥1) — глубина окна в днях. Значение выше настроенного максимума НЕ отклоняется — тихо ограничивается максимумом (по умолчанию и максимум — 90 дней). Нецелое или ≤0 значение → 422.
  • Ответ: {window_days, incidents, maintenances, generated_at}window_days показывает фактически применённое (возможно, урезанное) окно.
  • Каждый элемент incidents/maintenances — тот же закрытый whitelist полей, что и в GET /status/summary: slug, kind (incident\|maintenance), impact (none\|minor\|major\|critical), status (для incidentinvestigating\|identified\|monitoring\|resolved; для maintenancescheduled\|in_progress\|completed), components (список затронутых ключей), component_impact (объект компонент → сигнал), started_at, resolved_at, scheduled_start_at, scheduled_end_at, title (локализованный объект, в проде включает ru/kk/en), postmortem_url, updates[] ({status, created_at, body, next_update_at}, body — тот же локализованный объект, что и title).
  • Возвращаются только опубликованные записи (is_published = true), отсортированные по started_at от новых к старым; id, is_published, published_at, created_by, updated_by, origin никогда не попадают в ответ.

Эндпоинты

МетодПуть
GET/v1/public/status/summary

Текущий статус платформы и активные инциденты/работы (зеркало status.aisar.app, раз в минуту)

GET/v1/public/status/history

90-дневная история статуса по компонентам (зеркало status.aisar.app, раз в час)

GET/v1/public/status/incidents

Лента инцидентов и техработ за период (собственные данные api, не зеркало)

Примеры

Текущий статус платформы

Запрос

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

Ответ

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
}

Зеркало ещё не заполнено

Запрос

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

Ответ

json
{
  "error": "summary_unavailable"
}

90-дневная история по компонентам

Запрос

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

Ответ

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
}

Лента инцидентов за 30 дней

Запрос

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

Ответ

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"
}

Невалидный days (422)

Запрос

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

Ответ

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