API ScanBase — проверяйте сайты на 152-ФЗ программно
Один HTTP-запрос → оценка соответствия, список нарушений с суммами штрафов, разбор политики/оферты/согласия, cookie и трекеров. Тот же движок, что и на scanbase.ru. Для CI/CD, агентств, платформ и AI-агентов (через MCP).
Base URL: https://scanbase.ru/wp-json/scanbase-api/v1
Auth: Authorization: Bearer sb_live_…
Аутентификация
Каждый запрос — с API-ключом формата sb_live_… в заголовке. Ключ в URL-параметрах не принимается (утекает в логи).
# предпочтительно Authorization: Bearer sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # либо X-Api-Key: sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Тариф и доступ определяются аккаунтом ключа, а не параметрами запроса. Ключ вы получаете сами в личном кабинете — см. Получить ключ.
Квоты и тарифы
| Режим | Объём | Домены | Burst | Отчёт |
|---|---|---|---|---|
| Free | 5 / сутки | любые | 1 / мин | урезанный (часть деталей и несоответствия скрыты) |
| Подписка | 30 / мес | только свои (мониторинг) | 3 / мин | полный |
| API-пакеты | по пакету | любые | 3 / мин | полный |
Доступ — по аккаунту ключа. Free сбрасывается в 00:00 UTC. Пакеты (кредиты) действуют 12 месяцев и дают полный отчёт по любому домену. Остаток — в GET /account и в заголовках X-RateLimit-*. Превышение → 429 с Retry-After.
Пакеты сканов
Разовая покупка, без подписки. Полный отчёт по любому домену, кредиты живут 12 месяцев. Оплата и активация — в личном кабинете.
| Пакет | Сканов | Цена | За скан |
|---|---|---|---|
| P10 | 10 | 12 000 ₽ | 1 200 ₽ |
| P50 | 50 | 45 000 ₽ | 900 ₽ |
| P200 | 200 | 140 000 ₽ | 700 ₽ |
| P1000 | 1000 | 500 000 ₽ | 500 ₽ |
Нужен объём вне пакетов, приоритетная поддержка или счёт на юрлицо — info@scanbase.ru.
Ошибки
Единый конверт ошибки:
{ "success": false, "error": { "code": "quota_exceeded", "message": "Daily quota exceeded" } }
| HTTP | code | Значение |
|---|---|---|
| 401 | unauthorized | Нет/неверный/отозванный ключ |
| 429 | quota_exceeded / rate_limited | Дневная квота / burst-лимит |
| 503 | scanner_busy | Сканер временно недоступен |
| 404 | no_active_scan / not_found | Нет активного скана для опроса / скан не найден или не ваш |
Статус 202 с {"status":"pending"} — это не ошибка, а «скан ещё идёт» (тяжёлый сайт). Опрашивайте GET /scans/pending.
Запустить скан
Сканирует URL. Быстрый сайт (≤120с) → 200 с результатом. Тяжёлый → 202 pending, добор через /scans/pending.
curl -X POST https://scanbase.ru/wp-json/scanbase-api/v1/scans \ -H "Authorization: Bearer sb_live_…" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.ru/"}'
Ответ 200 (сокращённо)
{
"success": true, "scan_id": "0b8e…-uuid", "schema_version": 1,
"url": "https://example.ru/", "domain": "example.ru",
"score": 62, "tier": "subscription",
"summary": { "violations_count": 7, "total_fine_max": 1200000 },
"all_checks": [ { "id": "cookie_reject", "category": "Cookie",
"name": "Кнопка «Отклонить»…", "passed": false, "fine": 300000 } ],
"documents": { … }, "foreign_services": [], "mismatch_findings": [],
"subdomains": [], "subdomains_meta": { "status": "ok|partial|unavailable", "source": "ct+dns|dns|links" },
"dev_tasks": [], "edu_documents": null, "peer_percentile": 41, "industry": null
}
Ответ 202 (тяжёлый сайт)
{ "success": false, "status": "pending", "reason": "scan_running",
"url": "https://example.ru/",
"poll": { "path": "/scans/pending?url=…", "retry_after": 15 } }
Добрать длинный скан
Опрос результата после 202. Тем же ключом, что запускал скан. Опрашивайте раз в ~15с.
| Ответ | Значит |
|---|---|
| 200 | Готово — тело как у POST /scans 200 |
| 202 | Ещё идёт — опрашивайте дальше |
| 404 | no_active_scan — нечего опрашивать (истёк/не запускался) |
Сохранённый результат
Прошлый скан по scan_id (uuid). Доступны только сканы вашего аккаунта. Гейтится по текущему тарифу (кончилась подписка → отчёт деградирует до free). Тело — идентичная схема scan_result.
curl https://scanbase.ru/wp-json/scanbase-api/v1/scans/0b8e…-uuid \
-H "Authorization: Bearer sb_live_…"
История сканов
Компактный список сканов аккаунта. per_page ≤ 50.
{ "success": true, "scans": [ { "scan_id": "…", "url": "…", "domain": "…",
"score": 62, "violations_count": 7, "total_fine_max": 1200000, "created_at": "…" } ],
"page": 1, "per_page": 20, "total": 48, "total_pages": 3, "has_more": true }
Полная серверная пагинация: total — всего сканов аккаунта, has_more — есть ли ещё страницы. Листайте page до has_more:false.
Статус аккаунта
{ "success": true, "api_version": "v1", "schema_version": 1,
"email": "you@company.ru", "tier": "subscription", "subscription_active": true,
"entitlement": {
"credits": { "balance": 40, "scope": "any_domain" },
"subscription": { "active": true, "domains": ["site.ru"],
"quota": { "period": "month", "limit": 30, "used": 4, "remaining": 26 } },
"free": { "quota": { "period": "day", "limit": 5, "remaining": 5 } } } }
Доступ зависит от домена конкретного скана: кредиты пакета — любой домен; подписка — только свои; иначе free. Есть также GET /rate-limit — быстрый остаток без лишней нагрузки.
Справочник проверок
Публичный каталог всех проверок сканера — id, название, категория, тип (violation/warning/check), статья закона и верхняя граница штрафа. Ключ не нужен. Удобно промаппить наши id на свою систему до первого скана.
{ "success": true, "count": 44, "categories": [ … ],
"checks": [ { "id": "google_analytics", "category": "Трансграничная передача",
"type": "violation", "law": "ст. 12 ФЗ-152, ст. 13.11 КоАП РФ", "fine_max": 6000000 } ] }
Схема scan_result
Единая для всех путей (POST /scans sync, /scans/pending, /scans/{id}).
| Поле | Тип | Описание |
|---|---|---|
scan_id | string|null | uuid скана — им вызывается GET /scans/{scan_id}. Обычно строка; в редком sync-race может быть null (сам результат уже получен, а id найдёте в GET /scans) |
score | int|null | Оценка соответствия 0–100 |
tier | string | free / subscription — под каким гейтом отдан результат |
summary | object | { violations_count, total_fine_max } |
all_checks[] | array | Проверки: { id, category, name, passed, warning, fine, … } |
documents | object|null | Найденные документы (политика/оферта/согласие/cookie) |
foreign_services[] | array | Зарубежные сервисы (трансграница) |
subdomains[] | array | Связанные хосты домена (периметр организации) |
subdomains_meta | object|null | Полнота перечня: status — ok (проверены журналы TLS-сертификатов), partial (только ссылки и типовые имена — список может быть неполным), unavailable; source — использованные источники. Пустой subdomains при partial не означает отсутствия поддоменов. |
mismatch_findings[] | array | Несоответствия документ↔сайт (подписка) |
dev_tasks[] | array | ТЗ на устранение (подписка) |
edu_documents | array|null | Обязательные документы образовательной организации |
peer_percentile | int|null | Перцентиль относительно отрасли |
schema_version | int | Версия схемы результата (сейчас 1) |
Состав all_checks постоянно расширяется вместе со сканером — новые проверки не ломают контракт. Контракт — это структура полей, конверт и коды ошибок. Клиент должен игнорировать незнакомые поля.
Версионирование
Версия в пути: scanbase-api/v1. Внутри v1 — только аддитивные изменения (новые поля/эндпоинты). Ломающие изменения → v2 рядом, с окном деприкации. schema_version в результате и api_version в /account — для страховки.
MCP-сервер (AI-агенты)
Для Claude Desktop, Cursor и других AI-агентов — MCP-сервер scanbase-mcp: агент вызывает наш скан как инструмент («проверь этот сайт на 152-ФЗ»). Добавьте в конфиг MCP:
{
"mcpServers": {
"scanbase": {
"command": "npx",
"args": ["-y", "scanbase-mcp"],
"env": { "SCANBASE_API_KEY": "sb_live_…" }
}
}
}
Инструменты: scan_site, get_scan, list_scans, account. Ключ sb_live_… — из личного кабинета.
Получить ключ
- Войдите в личный кабинет (вход по email — magic-link).
- Вкладка 💳 Аккаунт → 🔌 API-доступ → кнопка «Создать бесплатный ключ».
- Скопируйте ключ
sb_live_…— он показывается один раз. Готово: 5 сканов в сутки бесплатно.
Нужно больше — там же докупите пакет сканов или оформите подписку. Ключей можно завести до трёх (например, dev и prod), любой отзывается в один клик.