API Enterno.io
Программный доступ ко всем инструментам enterno.io: HTTP-заголовки, DNS, SSL, пинг, IP-геолокация, оценка здоровья, мониторы и страницы статуса. REST API с ответами в формате JSON.
Открытый API — без ключа и регистрации
Один GET, ответ обычным текстом. Вставьте в терминал, в браузер, в CI-скрипт или в таблицу — работает сразу, читать перед этим ничего не нужно и регистрироваться тоже. API с ключом ниже умеет больше; этот — тот, что можно попробовать за пять секунд.
curl "https://enterno.io/api/open/headers?q=https://example.com"
curl "https://enterno.io/api/open/ssl?q=example.com"
curl "https://enterno.io/api/open/dns?q=example.com&types=MX,TXT"
/api/open/ без инструмента печатает каталог — сориентироваться можно прямо из консоли, не возвращаясь на эту страницу.
Инструменты
| Инструмент | q = | Описание | Ещё |
|---|---|---|---|
headers |
url |
HTTP response headers | — |
dns |
domain |
DNS records | types |
ssl |
host |
TLS certificate | port |
ip |
host |
IP geolocation | — |
ping |
host |
ICMP reachability | — |
whois |
host |
Domain registration | — |
mx |
domain |
Mail exchangers | — |
asn |
query |
ASN / network owner | — |
dkim |
domain |
DKIM public key | selector |
propagation |
domain |
DNS propagation across resolvers | — |
http-status |
url |
Status code only | — |
redirects |
url |
Redirect chain | max |
csp |
url |
Content-Security-Policy | — |
cors |
url |
CORS policy | origin |
cookie |
url |
Cookie flags | — |
robots |
domain |
robots.txt rules | test_url |
schema |
url |
Structured data | — |
protocol |
url |
HTTP version and TLS | — |
url-expand |
url |
Resolve a short link | — |
Форматы
&format=text (по умолчанию) для консоли, &format=json для кода, &format=csv для таблицы. Текстовый ответ заканчивается строкой-комментарием # с источником — она переживает grep и остаётся на месте, когда вывод вставляют в тикет.
Лимиты и чего здесь нет
Ограничение по IP и та же дневная норма, что и для анонимных посетителей сайта. Ответы кэшируются на 60 секунд и читаются с любого источника.
Два семейства инструментов остаются за ключом. Всё, за чем стоит реальный счёт — headless-браузер, обход сайта, платные сторонние запросы, — потому что вызов без ключа можно повторять безнаказанно и без имени, на которое выставить счёт. И всё, что щупает хост так, как его владелец прочитает как сканирование: перебор портов, перечисление поддоменов, проверки на вредонос и злоупотребления. Без ключа это уже не диагностика, а способ просканировать чужой хост с нашего адреса. ping здесь только как проверка доступности, режим сканирования портов ему закрыт.
Нужен инструмент не из списка или тот же вызов без анонимного потолка? Для этого и есть API с ключом ниже.
Что на этом строят
Каждый пункт — законченное применение, а не демонстрация одного эндпоинта.
1. Уронить сборку раньше, чем сертификат
Сертификат, истекающий в субботу, обнаруживают клиенты. Поставьте проверку в CI — и его обнаружит конвейер.
# .gitlab-ci.yml / GitHub Actions — no key needed
DAYS=$(curl -s "https://enterno.io/api/open/ssl?q=$SITE&format=json" | jq -r '.certificate.days_left')
[ "$DAYS" -gt 14 ] || { echo "TLS expires in $DAYS days"; exit 1; }
2. Таблица, которая проверяет себя сама
Google Таблицы читают CSV по HTTP штатно. Одна формула на строку, обновление при открытии — без скриптов, дополнений и ключа.
=IMPORTDATA("https://enterno.io/api/open/ssl?q=" & A2 & "&format=csv")
3. Мониторинг своим кроном
Когда расписание и оповещения хочется держать у себя, а одолжить только проверку.
*/5 * * * * curl -sf "https://enterno.io/api/open/http-status?q=https://example.com" \
| grep -q "^code: 200" || /usr/local/bin/notify "example.com is not answering 200"
4. Дать AI-агенту инструмент, который он вправду вызовет
Агент не может зарегистрироваться и получить ключ. GET без ключа, отдающий обычный текст, — та форма, которую модель с инструментами берёт без обёртки. А полный типизированный список инструментов есть в MCP-сервере.
5. Zapier, Make, n8n
В каждом из них есть шаг «сделать GET» и туго со всем остальным. &format=json ложится прямо в следующий узел.
6. Однострочники, которые остаются в истории команд
# which CDN is in front of it
curl -s "https://enterno.io/api/open/headers?q=https://example.com" | grep -i "server\|cf-ray"
# where does this short link really go
curl -s "https://enterno.io/api/open/url-expand?q=https://bit.ly/xxxx"
# is my SPF/DKIM actually published
curl -s "https://enterno.io/api/open/dkim?q=example.com&selector=default"
7. Встроить живой результат в чужую страницу
Открытый ярус читается с любого источника, поэтому виджет статуса — это несколько строк fetch() без собственного прокси. Если нужна картинка, а не данные, есть значки.
8. Аудит списка
Для десятка хостов хватит цикла в консоли и открытого яруса. Дальше анонимный потолок становится неподходящим инструментом — берите ключ и /api/v4/batch: он прогоняет список асинхронно, вместо того чтобы вы сами выдерживали темп.
while read h; do
printf '%s\t' "$h"
curl -s "https://enterno.io/api/open/ssl?q=$h" | grep '^certificate.days_left:'
done < hosts.txt
Попробовать
Запустите запрос против вашего ключа и скопируйте готовый сниппет на любом из 5 языков.
GET /api/v4/check — Проверка HTTP-заголовков
GET /api/v4/dns — DNS-запросы
GET /api/v4/ssl — SSL/TLS-сертификат
GET /api/v4/ping — Ping + порты
GET /api/v4/ip — IP-геолокация
Аутентификация
Все запросы к API v4 требуют ключ через заголовок X-API-Key. Используйте X-Idempotency-Key для безопасных повторных запросов.
Получите API-ключ, зарегистрировав аккаунт или в личном кабинете.
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/webhooks"
Каждый ответ содержит заголовок X-Request-Id для отслеживания.
Idempotency Key
Добавьте X-Idempotency-Key: unique-id к любому запросу на запись. Enterno.io вернёт кэшированный ответ при дублировании в течение 60 секунд.
curl -X POST "https://enterno.io/api/v4/webhooks" \
-H "X-API-Key: YOUR_KEY" \
-H "X-Idempotency-Key: create-wh-001" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-app.com/hook"}'
Формат ответа
API v4 использует тот же JSON-конверт, что v3, с "api_version": "4.0" в meta.
{
"data": { ... },
"meta": {
"request_id": "a1b2c3d4e5f6a7b8c9d0e1f2",
"duration_ms": 8,
"cached": false,
"api_version": "4.0"
}
}
При ошибке:
{
"error": {
"code": "not_found",
"message": "Ресурс не найден"
},
"meta": {
"request_id": "a1b2c3d4e5f6a7b8c9d0e1f2",
"duration_ms": 2,
"api_version": "4.0"
}
}
Лимиты запросов
Информация о лимитах включена в заголовки ответа:
| Заголовок | Описание |
|---|---|
X-RateLimit-Limit | Максимум запросов в минуту |
X-RateLimit-Remaining | Оставшиеся запросы в текущем окне |
X-RateLimit-Reset | Unix timestamp сброса лимита |
Retry-After | Секунды до повтора (только при 429) |
| Тариф | Запросов/мин | Дневной лимит | Области |
|---|---|---|---|
| Бесплатно | 10 | 100 | check, dns |
| Pro | 60 | 5 000 | check, dns, ssl, ip, ping, monitors, webhook |
| Business | 120 | 50 000 | check, dns, ssl, ip, ping, monitors, webhook |
Области
Каждый API-ключ имеет набор разрешённых областей. Запрос к недоступному эндпоинту вернёт ошибку 403.
| Область | Эндпоинт | Описание |
|---|---|---|
check | /api/v4/check, /api/v4/health, /api/v4/audit-export | Проверка HTTP-заголовков + оценка здоровья |
dns | /api/v4/dns | DNS-запрос + DNSSEC |
ssl | /api/v4/ssl | Проверка SSL/TLS + детали цепочки |
ip | /api/v4/ip | Геолокация IP |
ping | /api/v4/ping | Пинг, проверка портов, трассировка |
monitors | /api/v4/monitors | CRUD мониторов + страницы статуса |
webhook | /api/v4/webhooks, /api/v4/events | CRUD вебхук-подписок и лога событий |
Webhooks — Управление подписками
Создавайте вебхук-подписки для получения HTTP POST уведомлений при изменении состояния мониторов, SSL-сертификатов или доменов.
Поддерживаемые типы событий
| Область | Описание |
|---|---|
monitor.down | Монитор упал |
monitor.up | Монитор восстановлен |
monitor.degraded | Снижение скорости монитора |
ssl.expiring | SSL-сертификат скоро истекает |
ssl.expired | SSL-сертификат истёк |
ssl.chain_changed | Изменилась цепочка SSL (издатель или отпечаток) |
domain.expiring | Домен скоро истекает |
domain.expired | Регистрация домена истекла |
visual.changed | Визуальный монитор увидел изменение |
test | Тестовое событие |
Лимиты вебхуков по тарифам
| Тариф | Макс. вебхуков | Ограничения событий |
|---|---|---|
| Бесплатно | 1 | monitor.down, monitor.up, test |
| Starter | 5 | Все события |
| Pro | 20 | Все события |
| Business | 50 | Все события |
Список вебхуков
Возвращает все вебхук-подписки аутентифицированного пользователя.
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/webhooks"
Создать вебхук
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
url | string | Да | URL назначения (требуется HTTPS) |
name | string | Нет | Название подписки (опционально) |
secret | string | Нет | HMAC-SHA256 секрет для проверки подписи (опционально) |
events | array | Нет | Типы событий для подписки (по умолчанию: все) |
curl -X POST "https://enterno.io/api/v4/webhooks" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/hooks/enterno",
"name": "Production alerts",
"events": ["monitor.down", "monitor.up", "ssl.expiring"]
}'
Ответ
{
"data": {
"id": 12,
"name": "Production alerts",
"url": "https://your-app.com/hooks/enterno",
"secret": "ent_wh_sk_***",
"events": ["monitor.down", "monitor.up", "ssl.expiring"],
"is_active": true,
"created_at": "2026-03-28T06:00:00Z"
},
"meta": {"request_id": "...", "duration_ms": 18, "api_version": "4.0"}
}
Обновить вебхук
curl -X PUT "https://enterno.io/api/v4/webhooks?id=12" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'
Удалить вебхук
curl -X DELETE "https://enterno.io/api/v4/webhooks?id=12" \
-H "X-API-Key: YOUR_KEY"
Проверка подписи webhook
Каждая доставка на ваш webhook-URL подписывается общим секретом secret. Два заголовка позволяют проверить целостность запроса и защититься от replay-атак:
| Заголовок | Значение | Назначение |
|---|---|---|
X-Enterno-Timestamp |
Unix-время (сек) в момент отправки | Отклонить если разница с локальным временем > 300 сек |
X-Enterno-Signature-V2 |
sha256=<hex> |
HMAC-SHA256(secret, timestamp + "." + body) |
X-Enterno-Signature |
sha256=<hex> |
Legacy — HMAC только по телу, без защиты от replay. Оставлен для существующих интеграций. Будет удалён 2026-07-01. |
Проверка на PHP (рекомендуется)
<?php
$secret = getenv('ENTERNO_WEBHOOK_SECRET'); // your shared secret
$ts = $_SERVER['HTTP_X_ENTERNO_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_ENTERNO_SIGNATURE_V2'] ?? '';
$body = file_get_contents('php://input');
// 1. Replay window — reject timestamps older than 5 minutes
if (abs(time() - (int)$ts) > 300) {
http_response_code(400);
exit('stale timestamp');
}
// 2. Compute expected signature
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
// 3. Timing-safe compare
if (!hash_equals($expected, $sig)) {
http_response_code(401);
exit('bad signature');
}
$payload = json_decode($body, true);
// …handle the event…
Проверка на Node.js
const crypto = require('crypto');
function verify(req, secret) {
const ts = req.headers['x-enterno-timestamp'];
const sig = req.headers['x-enterno-signature-v2'];
const body = req.rawBody; // use a raw-body parser
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300)
throw new Error('stale timestamp');
const expected =
'sha256=' + crypto.createHmac('sha256', secret)
.update(ts + '.' + body)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig)))
throw new Error('bad signature');
}
Окно миграции: старый X-Enterno-Signature (без timestamp) продолжает отправляться параллельно с V2 до 2026-07-01. Если используете старый формат — переключайтесь на V2 до этой даты.
Тест доставки
curl -X POST "https://enterno.io/api/v4/webhooks?action=test&id=12" \
-H "X-API-Key: YOUR_KEY"
Events — История доставки
Просматривайте историю доставки вебхуков с количеством попыток, HTTP-кодами ответов и причинами ошибок.
| Имя | Тип | Описание |
|---|---|---|
webhook_id | integer | Фильтр по ID вебхука (опционально) |
event_type | string | Фильтр по типу события |
status | string | Фильтр: delivered, retrying, failed, dead, pending |
page | integer | Номер страницы (по умолчанию 1) |
per_page | integer | Элементов на странице, макс. 100 (по умолчанию 25) |
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/events?webhook_id=12&status=failed"
Ответ
{
"data": [
{
"id": 501,
"webhook_id": 12,
"event_type": "monitor.down",
"status": "delivered",
"http_status_code": 200,
"attempts": 1,
"created_at": "2026-03-28T06:05:00Z",
"delivered_at": "2026-03-28T06:05:01Z"
}
],
"meta": {
"request_id": "...",
"duration_ms": 12,
"api_version": "4.0",
"pagination": {"total": 1, "page": 1, "per_page": 25, "pages": 1}
}
}
Check — Проверка HTTP-заголовков
Получение HTTP-заголовков ответа с детальной разбивкой времени (DNS, подключение, TLS, TTFB).
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
url | string | Да | URL для проверки |
method | string | Нет | GET, HEAD, POST (default: GET) |
follow | string | Нет | 0/1 (default: 1) |
timeout | integer | Нет | 1-30 (default: 15) |
ua | string | Нет | Пользовательский User-Agent |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/check.php?url=https://example.com"
Ответ
{
"data": {
"url": "https://example.com",
"final_url": "https://example.com/",
"method": "GET",
"code": 200,
"http_version": "HTTP/2",
"ip": "93.184.216.34",
"headers": [...],
"timing": {"dns_ms":12,"connect_ms":45,"tls_ms":78,"ttfb_ms":120,"transfer_ms":142,"redirect_ms":0,"redirect_count":0},
"elapsed_ms": 142
},
"meta": {"request_id":"req_01...","duration_ms":150,"cached":false,"api_version":"4.0"}
}
DNS — DNS-запрос
Получение DNS-записей с опциональной проверкой DNSSEC.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
domain | string | Да | Доменное имя |
types | string | Нет | Через запятую: A,AAAA,MX,NS,TXT,CNAME,SOA |
dnssec | string | Нет | 1 для проверки DNSSEC |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/dns.php?domain=example.com&dnssec=1"
SSL — Проверка SSL/TLS
Проверка SSL-сертификата с детальной информацией о цепочке.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
host | string | Да | Имя хоста |
port | integer | Нет | Порт (по умолчанию 443) |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/ssl.php?host=example.com"
IP — Геолокация
Определение местоположения, провайдера и организации по IP-адресу или домену.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
host | string | Да | IP-адрес или домен |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/ip.php?host=8.8.8.8"
Ping — Пинг, порты и трассировка
Пинг хоста, проверка портов или трассировка маршрута.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
host | string | Да | Хост или IP |
action | string | Нет | ping, ports, traceroute (default: ping) |
count | integer | Нет | Количество пингов 1-10 (по умолчанию 4) |
ports | string | Нет | Порты через запятую (для action=ports) |
max_hops | integer | Нет | Макс. хопов 1-30 (для action=traceroute) |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/ping.php?host=example.com&action=traceroute"
Health — Оценка здоровья сайта
Комплексный анализ здоровья сайта: заголовки безопасности (30 баллов), SSL/TLS (25 баллов), производительность (25 баллов), лучшие практики (20 баллов). Возвращает оценку 0-100 с грейдом от A+ до F.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
url | string | Да | URL для анализа |
Пример
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/health.php?url=example.com"
Возвращает score 0–100, буквенную оценку A+–F, разбивку по категориям (Security Headers / SSL / Performance / Best Practices) и отсортированные рекомендации. Кэшируется 2 минуты на URL.
Monitors — CRUD
Создание, чтение, обновление и удаление мониторов аптайма через API.
Список мониторов
| Имя | Тип | Описание |
|---|---|---|
page | integer | Номер страницы (по умолчанию 1) |
per_page | integer | Элементов на странице, макс. 100 (по умолчанию 25) |
status | string | Фильтр: up, down, unknown |
Получить монитор
Возвращает детали монитора с 20 последними проверками.
Создать монитор
curl -X POST "https://enterno.io/api/v4/monitors.php" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: create-mon-example-001" \
-d '{
"url": "https://example.com",
"check_type": "http",
"interval_minutes": 5,
"expected_code": 200,
"notify_email": true
}'
Обновить монитор
curl -X PUT "https://enterno.io/api/v4/monitors.php?id=5" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"interval_minutes": 10, "is_active": false}'
Удалить монитор
curl -X DELETE "https://enterno.io/api/v4/monitors.php?id=5" \
-H "X-API-Key: YOUR_KEY"
Batch — асинхронная проверка списка URL
Отправьте до 100 URL одним запросом (лимит зависит от плана: free→5, starter→20, pro→50, business→100). Сразу возвращается job_id — статус опрашивается отдельно.
Отправить пакет
curl -X POST "https://enterno.io/api/v4/batch.php" \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": ["https://example.com", "https://example.org"],
"type": "check"
}'
{
"data": {
"job_id": "bq_01ARZ3...",
"status": "pending",
"type": "check",
"total": 2,
"poll_url": "/api/v4/batch.php?job_id=bq_01ARZ3...",
"invalid_urls": []
},
"meta": {"request_id":"req_...","duration_ms":8,"api_version":"4.0"}
}
Опросить статус
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/batch.php?job_id=bq_01ARZ3..."
Status — Публичная страница статуса
Получение данных страницы статуса в JSON. Аутентификация не требуется при указании slug.
Пример
curl "https://enterno.io/api/v4/status.php?slug=my-company"
Ответ
{
"data": {
"title": "My Company Status",
"slug": "my-company",
"overall_status": "operational",
"monitors_total": 5,
"monitors_down": 0,
"monitors": [
{"id": 1, "name": "example.com", "status": "up", "response_time_ms": 120}
],
"recent_incidents": []
},
"meta": {"request_id":"req_...","duration_ms":15,"cached":false,"api_version":"4.0"}
}
Все остальные инструменты
Выше — эндпоинты с рукописными обработчиками. Все остальные диагностические инструменты сайта отвечают по адресу /api/v4/<tool>: та же аутентификация, тот же конверт, те же лимиты. Внутри выполняется тот же код, что и на странице инструмента, поэтому результаты не могут разойтись.
curl -H "X-API-Key: YOUR_KEY" \
"https://enterno.io/api/v4/cookie?url=https://example.com"
# what this key may call, and what it may not
curl -H "X-API-Key: YOUR_KEY" "https://enterno.io/api/v4/tools"
/api/v4/tools отвечает применительно к спросившему ключу: у каждой строки есть признак allowed по его scope, поэтому клиент, строящий меню, знает, что вернёт 403, до того как это предложит.
Инструменты и scope
| Эндпоинт | Параметр | Scope | Описание |
|---|---|---|---|
/api/v4/cookie |
url |
check |
Cookie flags and trackers |
/api/v4/cors |
url + origin |
check |
CORS policy |
/api/v4/csp |
url |
check |
Content-Security-Policy grade |
/api/v4/http-status |
url |
check |
Status code and timing |
/api/v4/redirects |
url + max, ua |
check |
Redirect chain |
/api/v4/protocol |
url |
check |
HTTP version and TLS negotiation |
/api/v4/mixed-content |
url |
check |
Mixed content on an HTTPS page |
/api/v4/schema |
url |
check |
Structured data |
/api/v4/robots |
domain + test_url |
check |
robots.txt rules |
/api/v4/tech-detect |
url |
check |
Technology fingerprint |
/api/v4/og-preview |
url |
check |
Open Graph and social preview |
/api/v4/cms |
url |
check |
CMS detection |
/api/v4/url-expand |
url |
check |
Resolve a short link |
/api/v4/resolve-url |
url |
check |
Resolve a URL to its final target |
/api/v4/wayback |
url |
check |
Wayback Machine history |
/api/v4/security |
url |
check |
Security headers grade |
/api/v4/seo-audit |
url |
check |
On-page SEO audit |
/api/v4/ai-check |
domain |
check |
AI readiness |
/api/v4/carbon |
url |
check |
Carbon footprint estimate |
/api/v4/performance |
url |
check |
Performance metrics |
/api/v4/pagespeed |
url + strategy |
check |
PageSpeed |
/api/v4/mx |
domain |
dns |
Mail exchangers |
/api/v4/dkim |
domain + selector |
dns |
DKIM public key |
/api/v4/email-check |
domain |
dns |
SPF, DKIM and DMARC |
/api/v4/email-header |
headers |
dns |
Parse raw email headers |
/api/v4/propagation |
domain + type |
dns |
DNS propagation across resolvers |
/api/v4/smtp-test |
target + port |
dns |
SMTP banner and STARTTLS |
/api/v4/whois |
host |
dns |
Domain registration |
/api/v4/asn |
query |
ip |
ASN and network owner |
/api/v4/reverse-ip |
ip |
ip |
Domains sharing an address |
/api/v4/traceroute |
host |
ping |
Network route |
Scope — из набора, который ключи уже носят, а не по одному на инструмент: ключ, выданный на check, вызовет cookie и csp без перевыпуска. Соответствие идёт по тому, что инструмент читает, а не по тому, что он сообщает: анализатор CSP забирает страницу по HTTP, поэтому у него check, как бы секьюрити-образно ни выглядел его вывод.
Перебора портов, перечисления поддоменов и проверок на вредонос здесь нет. Ключ называет, кто звонит, но не подтверждает, что хост принадлежит звонящему, — а важно именно это разрешение. Эти возможности живут в продуктах с гейтом владения.
MCP — для AI-агентов
Те же инструменты, но по протоколу Model Context Protocol: агент в Claude Desktop, Cursor или Zed вызывает их сам, без написания HTTP-кода. Внутри тот же обработчик, что и у REST-эндпоинтов выше и у страниц инструментов, — три входа, одна реализация, разойтись в результате они не могут.
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"check_ssl","arguments":{"host":"example.com"}}}
Инструментов: 43 — все REST-инструменты выше плюс запросы к платформе. tools/list отдаёт актуальный набор со схемами аргументов, а готовые сниппеты конфига для каждого агента — на странице MCP-сервера.
Агент вообще без ключа не в тупике: /api/open/ выше ключа не требует, отвечает обычным текстом и объявлен в нашей карточке агента навыком open-tools.
Аудит-выгрузка (подписанная)
GET /api/v4/audit-export — возвращает подписанный (HMAC-SHA256) снимок для комплаенса: по монитору, по шаренной проверке или по всему тенанту. Scope check. Тариф «Капитан».
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
type | string | да | monitor | check | tenant |
id | string | для monitor/check | id монитора (int) или шаренной проверки; для tenant не нужен |
page, per_page | int | нет | пагинация, только tenant (per_page ≤ 200) |
Ответ — подписанный конверт:
{
"data": {
"data": { /* каноничные данные */ },
"sig": { "v":1, "alg":"HMAC-SHA256", "kid":"e1", "ts":1718000000, "value":"<hex>" }
},
"meta": { "request_id":"req_...", "api_version":"4.0" }
}
Проверка: реканонизировать data и заново посчитать HMAC от ${ts}.${canonical} с общим секретом. Эталонный верификатор: cli/verify-report.php.
Коды ошибок
| HTTP код | Код ошибки | Описание |
|---|---|---|
400 | missing_parameter | Отсутствуют или некорректны параметры |
401 | auth_required | Отсутствует API-ключ |
401 | invalid_api_key | Неверный или неактивный API-ключ |
403 | insufficient_scope | Ключ не имеет нужной области доступа |
404 | not_found | Ресурс не найден |
405 | method_not_allowed | HTTP-метод не разрешён |
409 | conflict | Идемпотентный запрос уже выполняется |
429 | rate_limit_exceeded | Превышен лимит |
429 | daily_limit_exceeded | Превышен дневной лимит запросов |
Переход со старых версий
Полная пошаговая инструкция — /docs/api-v4-migration.md. Краткая карта ниже.
| Откуда | В v4 | Описание |
|---|---|---|
/api/v1/{check,dns,ssl,ip,ping}.php | /api/v4/{check,dns,ssl,ip,ping}.php | Плоский JSON → обёртка {data,meta}. Заголовок авторизации не меняется. |
/api/v2/{check,dns,ssl,ip,ping}.php | /api/v4/{check,dns,ssl,ip,ping}.php | {ok,data,meta} → {data,meta}. Формат ошибок меняется на {error:{code,message}}. |
/api/v3/* | /api/v4/* | Контракт идентичен — замените /v3/ на /v4/. |
| Настройка вебхуков (только UI) | /api/v4/webhooks | Программное управление вебхуками — только v4. |
| Лог доставки (только UI) | /api/v4/events | История доставки вебхуков с пагинацией и фильтрами. |
График: v1 и v2 возвращают 410 Gone после 2026-10-01. v3 заморожен (новых фич не будет), дата sunset не установлена — мигрируйте при удобном случае. Каждый ответ v1/v2 уже содержит заголовки Deprecation и Sunset (F2.2 / M-08).
Heartbeat / dead-man's switch
Токен-эндпоинт для cron-задач и скриптов — пинг раз в интервал. Если пинг не пришёл вовремя, монитор переходит в down и запускает алерты (как HTTP/SSL/DNS мониторы). API-ключ не нужен — токен в URL является авторизацией.
Токен выдаётся при создании heartbeat-монитора в кабинете. Вставьте URL в свой cron:
# every 10 minutes
*/10 * * * * curl -fsS https://enterno.io/api/heartbeat/YOUR_TOKEN > /dev/null
Ответ
{"status":"ok","next_ping_expected":1745197200}
Rate-limit: 30 req/мин/IP (через getClientIp()). Отвечает {"status":"ok", ...} для валидных активных токенов; для неактивных/неизвестных — та же форма ответа (защита от enumeration).
Webhook-приёмники — проверка нашей подписи
При отправке вебхуков (monitor.down, ssl.expiring и т.д.) каждый POST включает три заголовка, чтобы вы могли проверить подпись и защититься от replay:
| Заголовок | Описание |
|---|---|
X-Enterno-Event | Тип события: monitor.down, monitor.up, monitor.degraded, ssl.expiring, ssl.expired, ssl.chain_changed, domain.expiring, domain.expired, visual.changed, test. |
X-Enterno-Timestamp | Unix-timestamp отправки. Отклоните, если abs(now − ts) > 300 с (replay-guard). |
X-Enterno-Signature-V2 | HMAC-SHA256 от "{timestamp}.{raw_body}". Префикс sha256=. |
X-Enterno-Signature (legacy) | HMAC-SHA256 только от body — отключается 2026-07-01. Переходите на V2. |
PHP
$raw = file_get_contents(\'php://input\');
$ts = (int) ($_SERVER[\'HTTP_X_ENTERNO_TIMESTAMP\'] ?? 0);
$sig = $_SERVER[\'HTTP_X_ENTERNO_SIGNATURE_V2\'] ?? \'\';
// 1. replay guard
if (abs(time() - $ts) > 300) { http_response_code(401); exit(\'stale\'); }
// 2. verify signature (timing-safe)
$expected = \'sha256=\' . hash_hmac(\'sha256\', $ts . \'.\' . $raw, $webhookSecret);
if (!hash_equals($expected, $sig)) { http_response_code(401); exit(\'bad sig\'); }
// 3. process event
$event = json_decode($raw, true);
// ... your logic
http_response_code(200);
Node.js
const crypto = require(\'crypto\');
const secret = process.env.ENTERNO_WEBHOOK_SECRET;
app.post(\'/webhook\', express.raw({ type: \'application/json\' }), (req, res) => {
const ts = parseInt(req.get(\'X-Enterno-Timestamp\') || \'0\', 10);
const sig = req.get(\'X-Enterno-Signature-V2\') || \'\';
if (Math.abs(Date.now() / 1000 - ts) > 300) return res.status(401).send(\'stale\');
const expected = \'sha256=\' + crypto.createHmac(\'sha256\', secret)
.update(ts + \'.\' + req.body.toString())
.digest(\'hex\');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
return res.status(401).send(\'bad sig\');
}
const event = JSON.parse(req.body.toString());
// ... your logic
res.status(200).send();
});