> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arzguard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Данные и статусы отчётов

> Структура ответов, схема сервера и канала, полнота общей суммы, свежесть отчётов и метаданные изображений.

Успешный HTTP-запрос означает, что API обработал запрос. Чтобы понять, можно ли использовать статистику, проверьте состояние отчёта в `status`, а для общего списка — также `complete`.

> [!NOTE]
>
> Отсутствующий или устаревший отчёт сам по себе не вызывает HTTP-ошибку: API может вернуть HTTP `200`, а состояние конкретного сервера передать в JSON.

## Что входит в счётчики

Сервис считает сообщения в настроенных основных общих каналах Discord. Учитываются все авторы, включая ботов, без фильтра по ролям. API публикует счётчики, названия и идентификаторы серверов и каналов; тексты сообщений и данные авторов не возвращаются.

Удалённые, недоступные и ещё не проиндексированные Discord сообщения не учитываются. После переиндексации счётчики могут измениться. Поэтому значение отражает сохранённый отчёт, а не поток событий в реальном времени.

## Два формата ответа

| Запрос | Поле с данными | Назначение |
| - | - | - |
| С параметром `server` | `server` | Один объект сервера |
| Без параметра `server` | `servers` | Массив серверов и общие показатели |

Объект сервера имеет одинаковую схему в обоих форматах и для всех периодов. В общем списке серверы идут в порядке номеров; сортировка рейтинга на сайте этот порядок не меняет.

### Общие метаданные

| Поле | Тип | Когда возвращается | Значение |
| - | - | - | - |
| `month` | `string` | Для месяца | Выбранный месяц в формате `YYYY-MM` |
| `period` | `string` | Для остальных периодов | `day`, `week` или `range` |
| `from` | `string` | Для остальных периодов | Первый день в формате `YYYY-MM-DD`, включительно |
| `to` | `string` | Для остальных периодов | Последний день в формате `YYYY-MM-DD`, включительно |
| `start` | `string` | Для остальных периодов | Начало периода в ISO 8601, включительно |
| `endExclusive` | `string` | Для остальных периодов | Конец периода в ISO 8601, исключительно |
| `timezone` | `string` | Всегда | Часовой пояс расчёта: `Europe/Moscow` |
| `refreshMinutes` | `number` | Всегда | Пауза между проходами сборщика в минутах |

Подробные примеры календарных границ приведены на странице [«Периоды и даты»](/kalenich-stats/periods).

### Один сервер

Условный пример месячного ответа без собранного отчёта. Название, идентификатор и значения приведены для иллюстрации схемы:

```json theme={null}
{
  "month": "2026-10",
  "timezone": "Europe/Moscow",
  "refreshMinutes": 60,
  "server": {
    "number": 2,
    "name": "Пример сервера",
    "guildId": "123456789012345678",
    "iconUrl": null,
    "bannerUrl": null,
    "totalMessages": null,
    "channels": [],
    "generatedAt": null,
    "status": "pending",
    "error": null
  }
}
```

### Общий список

В дополнение к метаданным периода общий ответ содержит:

| Поле | Тип | Значение |
| - | - | - |
| `servers` | `Server[]` | Все настроенные серверы с индивидуальными состояниями отчётов |
| `totalServers` | `number` | Количество настроенных серверов |
| `readyServers` | `number` | Количество серверов со статусом `ok` |
| `totalMessages` | `number` | Сумма сообщений **только у серверов со статусом `ok`** |
| `complete` | `boolean` | `true`, если у всех серверов есть актуальный отчёт |

> [!WARNING]
>
> При `complete: false` общая сумма неполная. Даже если у сервера со статусом `stale` заполнен счётчик, этот счётчик не включается в верхнеуровневое поле `totalMessages`.

Например, если один сервер имеет `status: "ok"` и 1 200 сообщений, а другой — `status: "stale"` и 800 сообщений, общий итог составит **1 200**, `readyServers` — **1**, а `complete` — **false**. Это условный пример, показывающий правило агрегации.

> [!TIP]
>
> В интерфейсе рядом с общей суммой показывайте охват: `readyServers` из `totalServers`. Так пользователь увидит, за сколько серверов получены актуальные данные.

## Объект Server

| Поле | Тип | Описание |
| - | - | - |
| `number` | `number` | Номер сервера в списке сервиса |
| `name` | `string` | Название сервера |
| `guildId` | `string` | Полный Discord ID сервера |
| `iconUrl` | `string \| null` | Ссылка на текущую иконку в Discord CDN или `null` |
| `bannerUrl` | `string \| null` | Ссылка на текущий баннер в Discord CDN или `null` |
| `totalMessages` | `number \| null` | Количество сообщений в сохранённом отчёте; `null`, если пригодного отчёта нет |
| `channels` | `Channel[]` | Учтённые каналы и их счётчики |
| `generatedAt` | `string \| null` | Время формирования отчёта в ISO 8601 или `null` |
| `status` | `string` | Состояние отчёта: `ok`, `pending`, `stale`, `missing_channel` или `error` |
| `error` | `string \| null` | Код ошибки сбора или чтения, если он есть; иначе `null` |

> [!WARNING]
>
> Храните `guildId` и идентификаторы каналов строками. Числа Discord могут выходить за пределы точности JavaScript `Number`; преобразование в число способно изменить ID.

`error` описывает ошибку отчёта внутри успешного ответа. Это поле следует читать вместе со `status`. Не рассчитывайте на закрытый перечень кодов ошибок сбора: такой перечень в контракте API не задан.

## Объект Channel

| Поле | Тип | Описание |
| - | - | - |
| `id` | `string` | Discord ID учтённого канала |
| `name` | `string` | Название канала |
| `messages` | `number` | Количество учтённых сообщений в канале за выбранный период |

Условный пример одного канала:

```json theme={null}
{
  "id": "123456789012345679",
  "name": "общий-чат",
  "messages": 1200
}
```

Массив `channels` описывает учтённые каналы, а не полный список каналов Discord-сервера. Пустой массив при отсутствии отчёта не доказывает, что на сервере нет каналов или сообщений.

## Статусы отчёта

| `status` | Что означает | Как использовать в интеграции |
| - | - | - |
| `ok` | Есть актуальный отчёт | Можно включать значение в актуальные итоги |
| `pending` | Отчёт ещё не собран | Показать ожидание данных |
| `stale` | Отчёт устарел или более поздний сбор завершился ошибкой | Если счётчик сохранён, показывать его с отметкой об устаревании; исключать из актуальной общей суммы |
| `missing_channel` | Настроенный канал не найден, пригодного отчёта нет | Показать недоступность данных по каналу |
| `error` | Ошибка сбора, чтения или проверки отчёта | Показать ошибку отчёта и при необходимости прочитать `error` |

При обработке ответа сначала проверьте HTTP-статус, затем `server.status` или статусы элементов `servers`. Одной проверки `response.ok` недостаточно для вывода о полноте статистики.

## `null` и ноль

`totalMessages: 0` — числовое значение счётчика. `totalMessages: null` — пригодного отчёта нет. Эти состояния нельзя объединять: подмена `null` нулём создаст ложное падение активности и исказит сравнение серверов.

```javascript Пример отображения theme={null}
const count = data.server.totalMessages;
const label = count === null
  ? 'Нет данных'
  : count.toLocaleString('ru-RU');
```

Это пример только для отображения значения. Статус отчёта показывайте отдельно, в том числе когда числовой счётчик присутствует.

Для дня, недели и диапазона действуют дополнительные правила:

* Нет хотя бы одного дневного отчёта сервера — `totalMessages: null`; частичная сумма не выдаётся за весь период.
* Все дни есть, но хотя бы один отчёт устарел — сумма сохраняется со статусом `stale`.
* `generatedAt` составного периода — самое раннее время формирования входящих отчётов.

## Свежесть данных

Смотрите на `status` и `generatedAt` вместе. `generatedAt` обозначает время формирования отчёта, а не время последнего сообщения или последнего обращения к API. Для архивных дневных снимков старая дата формирования сама по себе не означает неисправность: API сохраняет завершённые дни.

`refreshMinutes` задаёт паузу между проходами сборщика. Сам сбор также занимает время, а серверы могут иметь разные `generatedAt`. Вызов API не запускает немедленное обновление статистики.

> [!NOTE]
>
> Не выводите одинаковое время обновления для всего списка на основании одного сервера. Время формирования принадлежит конкретному отчёту.

## Иконки и баннеры

Поля `iconUrl` и `bannerUrl` содержат **текущие метаданные сервера**, даже при запросе архивного периода или при отсутствии отчёта. Это не исторические изображения на дату статистики.

| Поле | Изображение | Формат | Когда возможно `null` |
| - | - | - | - |
| `iconUrl` | Иконка, 256 px | PNG; GIF для анимированной иконки | Иконки нет или её метаданные ещё не получены |
| `bannerUrl` | Баннер, 1024 px | PNG; GIF для анимированного баннера | Баннера нет или метаданные ещё не обновились |

Для получения изображений без статистики используйте `GET /api/discord-icons`. Метод возвращает JSON со ссылками на Discord CDN. У объектов в этом ответе есть только поля `number`, `name`, `guildId`, `iconUrl` и `bannerUrl`; счётчики и статусы отчётов не требуются.

Иконка и баннер обновляются сборщиком вместе. В старых метаданных без баннера `bannerUrl` остаётся `null` до обновления. Если метаданные недоступны или повреждены, метод иконок может ответить HTTP `200` с `iconUrl: null`; сам HTTP-запрос не запускает обновление из Discord.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.