Skip to content
EN

API Enterno.io

Программный доступ ко всем инструментам enterno.io: HTTP-заголовки, DNS, SSL, пинг, IP-геолокация, оценка здоровья, мониторы и страницы статуса. REST API с ответами в формате JSON.

API v1 и v2 будут отключены 2026-10-01 — перейдите на v4 до этой даты. Пошаговая инструкция: migration guide. v3 заморожен, но поддерживается; v4 — текущая версия.
Три пути сходятся в одно ядро: открытый пунктир без замка, линия через ключ и линия через узел протокола. От ядра связи расходятся к отдельным инструментам.

Открытый API — без ключа и регистрации

Один GET, ответ обычным текстом. Вставьте в терминал, в браузер, в CI-скрипт или в таблицу — работает сразу, читать перед этим ничего не нужно и регистрироваться тоже. API с ключом ниже умеет больше; этот — тот, что можно попробовать за пять секунд.

GET /api/open/<tool>?q=<target> без аутентификации
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 языков.

Хранится в sessionStorage этой вкладки. Закрытие вкладки — ключ очищается.

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-ResetUnix timestamp сброса лимита
Retry-AfterСекунды до повтора (только при 429)
Тариф Запросов/мин Дневной лимит Области
Бесплатно10100check, dns
Pro605 000check, dns, ssl, ip, ping, monitors, webhook
Business12050 000check, dns, ssl, ip, ping, monitors, webhook

Области

Каждый API-ключ имеет набор разрешённых областей. Запрос к недоступному эндпоинту вернёт ошибку 403.

Область Эндпоинт Описание
check/api/v4/check, /api/v4/health, /api/v4/audit-exportПроверка HTTP-заголовков + оценка здоровья
dns/api/v4/dnsDNS-запрос + DNSSEC
ssl/api/v4/sslПроверка SSL/TLS + детали цепочки
ip/api/v4/ipГеолокация IP
ping/api/v4/pingПинг, проверка портов, трассировка
monitors/api/v4/monitorsCRUD мониторов + страницы статуса
webhook/api/v4/webhooks, /api/v4/eventsCRUD вебхук-подписок и лога событий

Webhooks — Управление подписками

Создавайте вебхук-подписки для получения HTTP POST уведомлений при изменении состояния мониторов, SSL-сертификатов или доменов.

Поддерживаемые типы событий

ОбластьОписание
monitor.downМонитор упал
monitor.upМонитор восстановлен
monitor.degradedСнижение скорости монитора
ssl.expiringSSL-сертификат скоро истекает
ssl.expiredSSL-сертификат истёк
ssl.chain_changedИзменилась цепочка SSL (издатель или отпечаток)
domain.expiringДомен скоро истекает
domain.expiredРегистрация домена истекла
visual.changedВизуальный монитор увидел изменение
testТестовое событие

Лимиты вебхуков по тарифам

Тариф Макс. вебхуков Ограничения событий
Бесплатно1monitor.down, monitor.up, test
Starter5Все события
Pro20Все события
Business50Все события

Список вебхуков

GET /api/v4/webhooks scope: webhook

Возвращает все вебхук-подписки аутентифицированного пользователя.

curl -H "X-API-Key: YOUR_KEY" \
  "https://enterno.io/api/v4/webhooks"

Создать вебхук

POST /api/v4/webhooks scope: webhook
ИмяТипОбязательныйОписание
urlstringДаURL назначения (требуется HTTPS)
namestringНетНазвание подписки (опционально)
secretstringНетHMAC-SHA256 секрет для проверки подписи (опционально)
eventsarrayНетТипы событий для подписки (по умолчанию: все)
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"}
}

Обновить вебхук

PUT /api/v4/webhooks?id=N scope: webhook
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}'

Удалить вебхук

DELETE /api/v4/webhooks?id=N scope: webhook
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 до этой даты.

Тест доставки

POST /api/v4/webhooks?action=test&id=N scope: webhook
curl -X POST "https://enterno.io/api/v4/webhooks?action=test&id=12" \
  -H "X-API-Key: YOUR_KEY"

Events — История доставки

Просматривайте историю доставки вебхуков с количеством попыток, HTTP-кодами ответов и причинами ошибок.

GET /api/v4/events scope: webhook
ИмяТипОписание
webhook_idintegerФильтр по ID вебхука (опционально)
event_typestringФильтр по типу события
statusstringФильтр: delivered, retrying, failed, dead, pending
pageintegerНомер страницы (по умолчанию 1)
per_pageintegerЭлементов на странице, макс. 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).

GET POST /api/v4/check.php область: check

Параметры

ИмяТипОбязательныйОписание
urlstringДаURL для проверки
methodstringНетGET, HEAD, POST (default: GET)
followstringНет0/1 (default: 1)
timeoutintegerНет1-30 (default: 15)
uastringНетПользовательский 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.

GET POST /api/v4/dns.php Scope: dns

Параметры

ИмяТипОбязательныйОписание
domainstringДаДоменное имя
typesstringНетЧерез запятую: A,AAAA,MX,NS,TXT,CNAME,SOA
dnssecstringНет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-сертификата с детальной информацией о цепочке.

GET POST /api/v4/ssl.php Scope: ssl

Параметры

ИмяТипОбязательныйОписание
hoststringДаИмя хоста
portintegerНетПорт (по умолчанию 443)

Пример

curl -H "X-API-Key: YOUR_KEY" \
  "https://enterno.io/api/v4/ssl.php?host=example.com"

IP — Геолокация

Определение местоположения, провайдера и организации по IP-адресу или домену.

GET POST /api/v4/ip.php Scope: ip

Параметры

ИмяТипОбязательныйОписание
hoststringДаIP-адрес или домен

Пример

curl -H "X-API-Key: YOUR_KEY" \
  "https://enterno.io/api/v4/ip.php?host=8.8.8.8"

Ping — Пинг, порты и трассировка

Пинг хоста, проверка портов или трассировка маршрута.

GET POST /api/v4/ping.php Scope: ping

Параметры

ИмяТипОбязательныйОписание
hoststringДаХост или IP
actionstringНетping, ports, traceroute (default: ping)
countintegerНетКоличество пингов 1-10 (по умолчанию 4)
portsstringНетПорты через запятую (для action=ports)
max_hopsintegerНетМакс. хопов 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.

GET POST /api/v4/health.php область: check

Параметры

ИмяТипОбязательныйОписание
urlstringДа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.

Список мониторов

GET /api/v4/monitors.php область: monitors
ИмяТипОписание
pageintegerНомер страницы (по умолчанию 1)
per_pageintegerЭлементов на странице, макс. 100 (по умолчанию 25)
statusstringФильтр: up, down, unknown

Получить монитор

GET /api/v4/monitors.php?id=N

Возвращает детали монитора с 20 последними проверками.

Создать монитор

POST /api/v4/monitors.php
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
  }'

Обновить монитор

PUT /api/v4/monitors.php?id=N
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}'

Удалить монитор

DELETE /api/v4/monitors.php?id=N
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 — статус опрашивается отдельно.

Отправить пакет

POST /api/v4/batch.php область: check
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"}
}

Опросить статус

GET /api/v4/batch.php?job_id=JOB_ID
curl -H "X-API-Key: YOUR_KEY" \
  "https://enterno.io/api/v4/batch.php?job_id=bq_01ARZ3..."

Status — Публичная страница статуса

Получение данных страницы статуса в JSON. Аутентификация не требуется при указании slug.

GET /api/v4/status.php?slug=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>: та же аутентификация, тот же конверт, те же лимиты. Внутри выполняется тот же код, что и на странице инструмента, поэтому результаты не могут разойтись.

GET POST /api/v4/<tool> нужен X-API-Key
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-эндпоинтов выше и у страниц инструментов, — три входа, одна реализация, разойтись в результате они не могут.

POST /mcp JSON-RPC 2.0 · Authorization: Bearer
{"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. Тариф «Капитан».

ИмяТипОбязательныйОписание
typestringдаmonitor | check | tenant
idstringдля monitor/checkid монитора (int) или шаренной проверки; для tenant не нужен
page, per_pageintнетпагинация, только 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 код Код ошибки Описание
400missing_parameterОтсутствуют или некорректны параметры
401auth_requiredОтсутствует API-ключ
401invalid_api_keyНеверный или неактивный API-ключ
403insufficient_scopeКлюч не имеет нужной области доступа
404not_foundРесурс не найден
405method_not_allowedHTTP-метод не разрешён
409conflictИдемпотентный запрос уже выполняется
429rate_limit_exceededПревышен лимит
429daily_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 является авторизацией.

GET POST HEAD /api/heartbeat/<TOKEN> публичный

Токен выдаётся при создании 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-TimestampUnix-timestamp отправки. Отклоните, если abs(now − ts) > 300 с (replay-guard).
X-Enterno-Signature-V2HMAC-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();
});