Справочник API

REST API StatusFox покрывает всё, что умеет панель: мониторы, уведомления, статус-страницы, окна обслуживания, API-ключи и биллинг.

База

https://api.statusfox.ru/api/v1

Аутентификация

Все приватные эндпоинты принимают заголовок:

Authorization: Bearer <токен>

Токен — одно из двух:

API-ключом нельзя: управлять API-ключами, выходить из сессии и создавать платежи — эти операции требуют сессии (защита на случай утечки ключа).

curl -H "Authorization: Bearer sf_ваш_ключ" \
  https://api.statusfox.ru/api/v1/monitors

Формат ошибок

Любая ошибка — JSON-объект с человекочитаемым сообщением:

{ "error": "monitor not found" }
КодЗначение
400Некорректный запрос: невалидный JSON или значения полей
401Нет токена, либо он невалиден или истёк
402Платёж не может быть создан
403Не хватает прав: нет scope, требование сессии, лимит тарифа
404Объект не найден (или принадлежит другому аккаунту)
409Конфликт: email уже зарегистрирован, slug занят
429Слишком много запросов — повторите позже
500Внутренняя ошибка StatusFox
502Сеть проверки временно недоступна
503Временная недоступность — повторите с паузой

Регистрация и вход

POST /v1/auth/register

Создаёт аккаунт на бесплатном тарифе и открывает сессию. Пароль — минимум 10 символов.

curl -X POST https://api.statusfox.ru/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@example.ru", "password": "длинный-пароль"}'

Ответ 201:

{
  "token": "c29e…",
  "user": {
    "id": "u_9f2c…",
    "email": "dev@example.ru",
    "plan": "free",
    "owner_id": "8a1b…",
    "email_verified": false,
    "created_ms": 1719990000000
  }
}

Ошибки: 400 (невалидный email / короткий пароль), 409 (email занят).

POST /v1/auth/login

curl -X POST https://api.statusfox.ru/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@example.ru", "password": "длинный-пароль"}'

Ответ 200 — та же пара {token, user}. Ошибка 401 — неверный email или пароль (случаи не различаются).

POST /v1/auth/logout

Только сессия. Завершает текущую сессию. Ответ 204.

GET /v1/me

Текущий аккаунт (scope read):

curl -H "Authorization: Bearer $TOKEN" https://api.statusfox.ru/api/v1/me

Ответ 200 — объект user (см. выше).


API-ключи

Управление ключами доступно только с сессионным токеном.

POST /v1/apikeys

curl -X POST https://api.statusfox.ru/api/v1/apikeys \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"scopes": ["read"]}'

scopes — массив из read и/или write; пустой массив = оба.

Ответ 201ключ показывается один-единственный раз:

{
  "id": "k_4d0a…",
  "key": "sf_1f2e3d…",
  "scopes": ["read"],
  "created_ms": 1719990000000
}

GET /v1/apikeys

Ответ 200 — список без самих ключей:

[
  { "id": "k_4d0a…", "scopes": ["read"], "created_ms": 1719990000000 }
]

DELETE /v1/apikeys/{id}

Ответ 204. Ошибка 404 — ключ не найден.


Мониторы

Объект монитора:

{
  "id": "m_7c1e…",
  "name": "Продакшен",
  "type": "http",
  "target": "https://example.ru",
  "params": { "expect_status": "401" },
  "interval_seconds": 60,
  "enabled": true,
  "check_id": "a3f1…",
  "state": "up",
  "created_ms": 1719990000000,
  "updated_ms": 1719990000000
}

state: up | degraded | down | pending | disabled | unknown. check_id — идентификатор проверки в сети StatusFox; нужен для /v1/monitors/history.

POST /v1/monitors

Scope write.

curl -X POST https://api.statusfox.ru/api/v1/monitors \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "http",
    "target": "https://example.ru",
    "interval_seconds": 60,
    "name": "Продакшен"
  }'
ПолеОбяз.Описание
typeдаhttp, tcp, dns, tls, icmp, traceroute
targetдаURL или хост; приватные/локальные адреса отклоняются
interval_secondsда1…86400; молча поднимается до минимума тарифа
nameнетДо 200 символов; по умолчанию — target
paramsнетДоп. параметры проверки, например {"expect_status": "401"}

Ответ 201 — объект монитора (state: "pending"). Ошибки: 400 (валидция), 403 (исчерпан лимит активных мониторов тарифа), 503 (сеть проверки временно недоступна — повторите).

GET /v1/monitors

Scope read. Ответ 200 — массив объектов монитора с актуальным state.

GET /v1/monitors/{id}

Scope read. Объект монитора плюс статистика (поля опускаются, пока данных нет):

{
  "id": "m_7c1e…",
  "…": "…поля монитора…",
  "uptime": {
    "24h": { "uptime": 0.9998, "samples": 1440, "up": 1439, "down": 1, "degraded": 0, "available": true },
    "7d":  { "uptime": 0.9976, "samples": 10080, "up": 10056, "down": 24, "degraded": 0, "available": true },
    "30d": { "uptime": 0.9990, "samples": 43200, "up": 43157, "down": 43, "degraded": 0, "available": true }
  },
  "latency": {
    "check_id": "a3f1…", "window": "24h",
    "p50": 142.0, "p95": 388.0, "p99": 512.0, "min": 98.0, "max": 940.0,
    "count": 1440, "available": true
  },
  "incidents": [
    {
      "start_ms": 1719900000000, "end_ms": 1719900420000, "duration_ms": 420000,
      "worst_status": "down", "bucket_count": 7, "resolution": "1m", "ongoing": false
    }
  ]
}

uptime.*.uptime — доля 0…1 (деградация считается доступностью, окна обслуживания исключены). latency — перцентили RTT за 24 часа в мс.

PATCH /v1/monitors/{id}

Scope write. Любое подмножество полей:

curl -X PATCH https://api.statusfox.ru/api/v1/monitors/m_7c1e… \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"interval_seconds": 30, "enabled": true}'
ПолеОписание
nameНовое имя
interval_secondsНовый интервал (минимум тарифа применяется)
enabledfalse — выключить (перестаёт проверяться, слот освобождается), true — включить

Ответ 200 — обновлённый монитор. Ошибки: 400, 403 (включение сверх лимита), 404.

DELETE /v1/monitors/{id}

Scope write. Удаляет монитор и останавливает проверки. Ответ 204.

GET /v1/monitors/{id}/locations

Scope read. Последний результат по каждой точке проверки — данные для карты географии:

curl -H "Authorization: Bearer $TOKEN" \
  https://api.statusfox.ru/api/v1/monitors/m_7c1e…/locations

Ответ 200:

{
  "locations": [
    {
      "probe_id": "9b2e…",
      "country": "RU",
      "city": "Moscow",
      "lat": 55.75,
      "lon": 37.61,
      "status": "up",
      "rtt_ms": 142,
      "timestamp_ms": 1719990000000
    }
  ]
}

lat/lon могут быть 0, 0, если точка не сообщила координаты.

GET /v1/monitors/status

Scope read. Сводка «check_id → статус» по всем проверкам аккаунта — то, чем живёт дашборд. Ответ 200 — массив объектов с полями check_id и overall.

GET /v1/monitors/history

Scope read. Агрегированная история доступности для графиков:

curl -H "Authorization: Bearer $TOKEN" \
  "https://api.statusfox.ru/api/v1/monitors/history?check_id=a3f1…&from_ms=1719900000000&to_ms=1719990000000"
ПараметрОбяз.Описание
check_idдаИз объекта монитора
from_msнетНачало окна
to_msнетКонец окна

Ответ 200 — массив временных корзин с числом успешных/неуспешных проверок:

[
  { "bucket_ms": 1719900000000, "samples": 12, "up_count": 12, "down_count": 0, "degraded_count": 0 }
]

Уведомления

Два ресурса: каналы (куда доставлять) и правила (какие мониторы покрыты). Подробнее о поведении — в руководстве.

POST /v1/notification-channels

Scope write.

curl -X POST https://api.statusfox.ru/api/v1/notification-channels \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type": "email", "destination": ""}'
ПолеОписание
typeemail, telegram, webhook, ntfy
destinationАдрес доставки. Для email игнорируется — всегда используется email аккаунта. Для telegram — не нужен (используется привязанный аккаунт)

Ответ 201:

{
  "id": "nc_5b3d…",
  "type": "email",
  "destination": "dev@example.ru",
  "created_ms": 1719990000000
}

Ошибки: 400 (неизвестный тип, невалидный destination), 403 — канал не входит в тариф (telegram, webhook и ntfy требуют платный тариф), 409 — Telegram ещё не привязан (сначала POST /v1/telegram/link).

GET /v1/notification-channels

Scope read. Ответ 200 — массив каналов.

DELETE /v1/notification-channels/{id}

Scope write. Удаляет канал и зависящие от него правила. Ответ 204.

POST /v1/notification-channels/{id}/test

Scope write. Отправляет в канал настоящее тестовое сообщение (для webhook приходит JSON в боевом формате с полем "test": true и статусом "test").

curl -X POST https://api.statusfox.ru/api/v1/notification-channels/nc_5b3d…/test \
  -H "Authorization: Bearer $TOKEN"

Ответ 200:

{
  "status": "sent",
  "cooldown_s": 60
}

Повторные тесты ограничены по времени на пару «пользователь + тип канала»: email — 60 секунд, telegram/webhook/ntfy — 15 секунд. Пока пауза не истекла, сервер отвечает 429 с заголовком Retry-After и телом:

{
  "error": "a test notification for this channel type was sent recently; retry in 42s",
  "retry_after_s": 42
}

Кулдаун стартует только после успешной отправки — неудачная попытка не блокирует следующую. Прочие ошибки: 403 — канал не входит в тариф, 404 — канал не найден, 502 — сообщение не удалось доставить, 503 — отправка этого типа временно недоступна.

POST /v1/notification-rules

Scope write.

curl -X POST https://api.statusfox.ru/api/v1/notification-rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel_id": "nc_5b3d…", "scope": "all"}'
ПолеОписание
channel_idСуществующий канал
scopeall — все мониторы, включая будущие; monitor — один монитор
monitor_idОбязателен при scope: "monitor"

Ответ 201:

{
  "id": "nr_8e2f…",
  "channel_id": "nc_5b3d…",
  "scope": "all",
  "created_ms": 1719990000000
}

Ошибки: 400 (невалидный scope, нет monitor_id), 404 (канал или монитор не найден), 409 (такое правило уже существует), 503 (временный сбой при регистрации правила в сети проверки — повторите запрос без изменений).

GET /v1/notification-rules

Scope read. Ответ 200 — массив правил (у правил со scope: "monitor" есть поле monitor_id).

DELETE /v1/notification-rules/{id}

Scope write. Ответ 204.


Окна обслуживания

POST /v1/maintenance-windows

Scope write.

curl -X POST https://api.statusfox.ru/api/v1/maintenance-windows \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "monitor_ids": ["m_7c1e…"],
    "start_ms": 1720000000000,
    "end_ms": 1720003600000,
    "reason": "Миграция БД"
  }'

Ответ 201:

{
  "id": "w_1a9c…",
  "start_ms": 1720000000000,
  "end_ms": 1720003600000,
  "reason": "Миграция БД",
  "monitor_ids": ["m_7c1e…"],
  "checks": [ { "check_id": "a3f1…", "native": "accepted" } ]
}

checks[].native: accepted — сеть проверки подтвердила окно; pending — подтверждение в пути (подавление алертов действует в любом случае). Ошибки: 400 (интервал в прошлом / конец раньше начала / неизвестный монитор).

GET /v1/maintenance-windows

Scope read. Ответ 200 — массив окон.

PATCH /v1/maintenance-windows/{id}

Scope write. Начало окна изменить нельзя (удалите и создайте заново).

ПолеОписание
end_msНовый конец; значение «сейчас» завершает окно досрочно
reasonНовый комментарий
monitor_idsНовый состав мониторов (минимум один)

Ответ 200 — обновлённое окно. Ошибки: 400, 404.

DELETE /v1/maintenance-windows/{id}

Scope write. Ответ 204.


Статус-страницы

POST /v1/status-pages

Scope write.

curl -X POST https://api.statusfox.ru/api/v1/status-pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "moy-servis",
    "title": "Статус Моего Сервиса",
    "monitor_ids": ["m_7c1e…"],
    "is_public": true
  }'
ПолеОбяз.Описание
slugдаАдрес страницы (латиница, цифры, дефис); неизменяем
titleдаЗаголовок
monitor_idsдаКомпоненты страницы
is_publicдаПубличность (непубличная отвечает 404)
themeнетТема оформления
accent_colorнетАкцентный цвет

Ответ 201:

{
  "id": "sp_2f7b…",
  "slug": "moy-servis",
  "title": "Статус Моего Сервиса",
  "is_public": true,
  "theme": "light",
  "accent_color": "#e8590c",
  "monitor_ids": ["m_7c1e…"],
  "created_ms": 1719990000000
}

Ошибки: 400, 403 (лимит страниц тарифа; на бесплатном тарифе статус-страницы недоступны), 409 (slug занят).

GET /v1/status-pages

Scope read. Ответ 200 — массив страниц.

PATCH /v1/status-pages/{id}

Scope write. Любое подмножество полей, кроме slug (попытка изменить — 400). Ответ 200 — обновлённая страница.

DELETE /v1/status-pages/{id}

Scope write. Ответ 204.

GET /v1/public/status/{slug}

Публичный, без авторизации. Данные статус-страницы:

curl https://api.statusfox.ru/api/v1/public/status/moy-servis

Ответ 200:

{
  "slug": "moy-servis",
  "title": "Статус Моего Сервиса",
  "theme": "light",
  "accent_color": "#e8590c",
  "overall": "operational",
  "components": [
    {
      "name": "Продакшен",
      "state": "up",
      "uptime_1d": 100,
      "uptime_7d": 99.98,
      "uptime_30d": 99.99
    }
  ],
  "incidents_recent": [
    {
      "check_id": "a3f1…",
      "status": "down",
      "severity": "outage",
      "opened_ms": 1719900000000,
      "closed_ms": 1719900420000
    }
  ],
  "uptime_source": "hub"
}

overall: operational | degraded | outage | unknown. Аптайм — проценты 0…100; null, если данных для окна пока нет. Ошибка 404 — страница не существует или непубличная.

GET /v1/public/status/{slug}/badge.svg

Публичный. Живой SVG-бейдж текущего состояния — для README и сайтов (см. Статус-страницы).


Telegram

POST /v1/telegram/link

Scope write. Выдаёт одноразовую ссылку привязки:

{
  "token": "f4a9…",
  "bot_username": "StatusFoxBot",
  "deep_link": "https://t.me/StatusFoxBot?start=f4a9…",
  "expires_in_seconds": 900
}

Откройте deep_link — бот привяжет чат к аккаунту.

GET /v1/telegram/status

Scope read. Ответ 200:

{ "linked": true, "chat_id": 123456789, "linked_ms": 1719990000000 }

или { "linked": false }.

DELETE /v1/telegram/link

Scope write. Отвязывает Telegram. Ответ 204.


Биллинг

POST /v1/billing/checkout

Только сессия (API-ключом оплатить нельзя).

curl -X POST https://api.statusfox.ru/api/v1/billing/checkout \
  -H "Authorization: Bearer $SESSION" \
  -H "Content-Type: application/json" \
  -d '{"plan_id": "team", "cycle": "month"}'
ПолеОписание
plan_idstarter, team, agency
cyclemonth или year

Ответ 200 — перенаправьте пользователя на confirmation_url для оплаты:

{ "payment_id": "2f0b…", "confirmation_url": "https://yoomoney.ru/checkout/…" }

Ошибки: 400 (неизвестный тариф/цикл), 402 (платёж не создан), 503 (платёжный провайдер временно недоступен).

GET /v1/billing

Scope read. Текущий тариф, подписка и последние платежи:

{
  "plan": "team",
  "subscription": {
    "plan_id": "team",
    "status": "active",
    "billing_cycle": "month",
    "current_period_end_ms": 1722600000000,
    "price_rub": 1290
  },
  "payments": [
    { "id": "2f0b…", "amount_rub": 1290, "status": "succeeded", "created_ms": 1719990000000 }
  ]
}

subscription равен null, если платной подписки нет.


Публичные эндпоинты

Без авторизации.

GET /v1/public/network

Сводка сети проверки StatusFox: точки проверки с координатами и статусами — данные для карты сети.

GET /v1/public/locations

Последние результаты проверок по точкам сети (снимок «точка × цель»).

GET /v1/public/ne-rabotaet

Каталог популярных сервисов с текущим статусом:

{
  "services": [
    {
      "slug": "sberbank",
      "display_name": "Сбербанк",
      "category": "banks",
      "category_label": "Банки",
      "domain": "sberbank.ru",
      "short_description": "Крупнейший банк России",
      "state": "up"
    }
  ]
}

GET /v1/public/ne-rabotaet/{slug}

Детали одного сервиса: статус, аптайм по окнам (включая 90 дней) и история инцидентов.