Все проверки раздела «Инструменты» доступны не только со страницы, но и из вашей программы: тот же расчёт и тот же вид ответа. Здесь собрано всё, чтобы начать за десять минут.
Как получить ключ
- Войдите в кабинет инструментов по коду на почту.
- Ключ доступа входит в тариф «Профи». На бесплатном и «Базовом» уровне ключа нет — попытка его выпустить ответит
TOOL_KEY_NOT_ALLOWED. - В разделе «Ключи доступа» нажмите «Создать ключ» и дайте ему имя — по нему вы узнаете ключ в списке.
- Открытое значение ключа показывается один раз — в миг создания. Мы храним только его отпечаток, поэтому «показать ещё раз» не можем ни вам, ни себе. Скопируйте ключ сразу. Потеряли — отзовите старый и выпустите новый.
Ключ выглядит так: приставка tlk_ и 64 шестнадцатеричных знака. По приставке его видно в чужом журнале — не оставляйте ключ в открытом коде страницы и не кладите в хранилище кода.
Ключей на тарифе «Профи» можно держать пять. Отозванный перестаёт работать в тот же миг.
Как передать ключ
Ключ идёт заголовком Authorization со словом Bearer:
Authorization: Bearer tlk_ВАШ_КЛЮЧ
Другие способы не работают намеренно: Authorization: Basic …, пустой Bearer без значения или ключ без приставки tlk_ получат 401 TOOL_KEY_INVALID. Тихо работать гостем мы не станем — иначе вы упирались бы в гостевые пределы и читали это как случайные отказы.
Ключ работает только на том сайте, где он выдан. Тот же ключ на адресе другого сайта платформы отвечает 401 TOOL_KEY_INVALID — тем же кодом, что и выдуманный ключ.
Заголовка нет вовсе — это не ошибка: запрос проходит как гостевой, с гостевыми пределами.
Первый запрос
Одна проверка — один запрос POST. Адрес складывается из вида инструмента:
POST https://seo-gen.com.ua/api/public/tools/<kind>/run
Полный пример, который можно скопировать и запустить (подставьте свой ключ):
curl -X POST https://seo-gen.com.ua/api/public/tools/http-status-checker/run \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"target":"https://example.com/"}'
В теле запроса два поля: target — адрес, который проверяем, и необязательный options — настройки вида.
Из чего состоит ответ
Удачный ответ — 200 и два поля: data с результатом и limit с остатком объёма. В примере ниже раздел headers убран, чтобы не растягивать страницу — в живом ответе он есть.
{
"data": {
"kind": "http-status-checker",
"target": "https://example.com/",
"checkedAt": "2026-09-19T08:12:07.078Z",
"cached": false,
"verdict": "ok",
"sections": [
{
"id": "summary",
"rows": [
{ "status": 200, "final": "https://example.com/", "hops": 0, "time_ms": 95, "soft_404": "" }
],
"columns": ["status", "final", "hops", "time_ms", "soft_404"]
},
{ "id": "chain", "rows": [], "columns": ["step", "from", "to", "status", "scheme"] }
],
"notes": []
},
"limit": { "remaining": null }
}
data.kind— вид инструмента — тот же, что в адресеdata.target— адрес, который проверили;null— у вида его нетdata.checkedAt— время проверки, ISO-8601 с часовым поясомdata.cached—true— ответ взят из нашего кеша (живёт 10 минут); время при этом остаётся временем самой проверкиdata.verdict— одно слово итога — перечень нижеdata.sections— разделы результата: у каждогоid,rowsиcolumns— порядок колонокdata.notes— коды оговорок (не готовый текст): почему проверили не всё и что стоит знатьlimit.remaining— сколько проверок осталось;nullзначит «предела нет»
Если раздел показан не целиком, у него есть capped с двумя числами: сколько показано и сколько найдено.
Слова итога
ok— проверили, беды не нашлиguess— определили приблизительно: ответ держится на одной слабой уликеpartial— проверили частично — часть не состоялась по НАШЕЙ причине (наш срок, наш предел размера, нас придержали за темп). Числа «проверено N из M» стоят в сводкеwarn— есть оговоркиunknown— определить не удалось: ответ сайта разобрать не вышлоfail— нашли поломку
Виды инструментов и что им передавать
Все виды ниже работают по ключу. Столбец «Настройки» — содержимое поля options: в круглых скобках тип и значение по умолчанию, в квадратных — перечень допустимых значений.
Вид (kind) | Название | Адрес | Настройки (options) | Разделы ответа |
|---|---|---|---|---|
audit | Аудит сайта | обязателен | user_agent (select, "*") [*|Googlebot|Bingbot|YandexBot|GPTBot|ClaudeBot|PerplexityBot|Google-Extended] | summary, issues, robots_issues, sitemap_issues, hreflang_issues, sources, conflicts, plan, chain, checks, directives, meta, headings |
seo-checker | SEO-анализ страницы | обязателен | check_links (boolean, true) | summary, issues, indexability, meta, headings, content, images, links |
cms-detector | CMS Detector / Определить CMS сайта | обязателен | — | cms, signals, tech |
indexability-checker | Проверка индексируемости | обязателен | user_agent (select, "*") [*|Googlebot|Bingbot|YandexBot|GPTBot|ClaudeBot|PerplexityBot|Google-Extended]; check_targets (boolean, true) | verdict, conflicts, sources, targets, plan |
http-status-checker | Проверка кодов ответа HTTP | обязателен | check_domain_variants (boolean, false) | summary, chain, variants, headers |
redirect-checker | Проверка редиректов | обязателен | check_domain_variants (boolean, false) | summary, chain, variants, headers |
robots-checker | Проверка robots.txt | обязателен | user_agent (select, "*") [*|Googlebot|Bingbot|YandexBot|GPTBot|ClaudeBot|PerplexityBot|Google-Extended]; paths (list); custom_file (textarea) | verdict, paths, ai_bots, issues, file, health |
sitemap-checker | Проверка sitemap.xml | обязателен | check_urls (boolean, true); sample_size (number, 20) | summary, robots, issues, tree, sample, urls, searched |
robots-meta-checker | Проверка meta robots | обязателен | user_agent (select, "*") [*|Googlebot|Bingbot|YandexBot|GPTBot|ClaudeBot|PerplexityBot|Google-Extended]; with_robots_txt (boolean, true) | verdict, issues, sources, directives |
canonical-checker | Проверка canonical | обязателен | check_target (boolean, true) | summary, checks, chain |
link-extractor | Извлечение ссылок со страницы | обязателен | check_status (boolean, true); unique_only (boolean, false) | summary, links, domains, special |
link-attributes | Проверка nofollow / sponsored / ugc | обязателен | my_domain (domain); check_status (boolean, true) | page_block, summary, links, mine |
anchor-analysis | Анализ анкоров ссылок | обязателен | commercial_words (textarea) | types, anchors, words, conflicts |
meta-extractor | Извлечение метатегов | обязателен | — | summary, tags, cards, code |
hreflang-checker | Проверка hreflang | обязателен | check_return (boolean, true) | summary, alternates, reciprocal, issues |
headings-extractor | Извлечение заголовков H1–H6 | не нужен | html (textarea) | tiles, outline |
pagespeed-checker | PageSpeed / Core Web Vitals Checker | обязателен | strategy (select, "mobile") [mobile|desktop] | summary, vitals, field, opportunities |
broken-links | Проверка «битых» ссылок | обязателен | mode (select, "page") [page|site]; max_pages (number, 100); check_status (boolean, true); urls (textarea) | summary, broken, redirects, skipped |
internal-links | Проверка внутренних ссылок | обязателен | mode (select, "page") [page|site]; max_pages (number, 100); check_status (boolean, true); subdomains_internal (boolean, false); urls (textarea) | summary, links, dead_ends, orphans |
external-links | Проверка внешних ссылок | обязателен | mode (select, "page") [page|site]; max_pages (number, 100); check_status (boolean, true); subdomains_internal (boolean, false); urls (textarea) | summary, links, skipped |
sitemap-generator | Генератор sitemap.xml | не нужен | urls (textarea); alternates (boolean, true); locales (text, "uk, ru, en"); lastmod (date); changefreq (select) [|always|hourly|daily|weekly|monthly|yearly|never]; priority (number) | numbers, xml, notes, next |
json-ld-validator | Проверка JSON-LD | не нужен | code (textarea) | summary, blocks, issues |
hreflang-generator | Генератор hreflang | не нужен | versions (rows); x_default (select); format (select, "html") [html|xml|http]; site_country (country, "UA"); comments (boolean); heads (textarea) | numbers, code, checks, map |
Списки адресов и файлы
Список адресов и обход сайта идут в очередь: запрос отвечает сразу, а результат забирается по ссылке.
curl -X POST https://seo-gen.com.ua/api/public/tools/http-status-checker/batch \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"list":"https://example.com/\nhttps://example.com/nope\nне адрес"}'
В ответе 202: номер задания, ссылка на него, сколько адресов принято и перечень отклонённых строк сразу — с номером строки и причиной.
{
"data": {
"id": "537f4024-0537-4abc-b564-56dc55569538",
"url": "/api/public/tools/jobs/537f4024-0537-4abc-b564-56dc55569538",
"accepted": 2,
"rejected": [ { "code": "TARGET_INVALID", "line": 3, "value": "не адрес" } ],
"status": "queued"
},
"limit": { "remaining": 4997 }
}
Список можно прислать и файлом — multipart/form-data, поле file; подходят CSV, XLSX и TXT до 5 МБ:
curl -X POST https://seo-gen.com.ua/api/public/tools/http-status-checker/batch \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ" \
-F "file=@spisok.csv"
Ход и результат — той же ссылкой. Поле job.status проходит queued → running → done, а job.done и job.total показывают продвижение:
curl https://seo-gen.com.ua/api/public/tools/jobs/537f4024-0537-4abc-b564-56dc55569538 \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ"
Готовый результат выгружается файлом — таблицей или JSON:
curl -OJ https://seo-gen.com.ua/api/public/tools/jobs/537f4024-0537-4abc-b564-56dc55569538/export.csv \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ"
curl -OJ https://seo-gen.com.ua/api/public/tools/jobs/537f4024-0537-4abc-b564-56dc55569538/export.json \
-H "Authorization: Bearer tlk_ВАШ_КЛЮЧ"
Обход сайта — тот же маршрут, но вместо списка один адрес и options.mode = "site". Сколько страниц обойти, говорит тариф.
Что считается расходом
- Одна проверка
POST …/run— одна единица месячного объёма тарифа и одно обращение по ключу. - Список из N адресов — N единиц объёма: каждый адрес это отдельный поход к чужому сайту.
- Обход сайта — одна единица в миг постановки в очередь; сколько страниц он пройдёт, ограничивает тариф.
- Ответ из кеша (
cached: true) объём всё равно тратит: объём считает обращения, а не походы. - Отказ по пределу (
QUOTA_EXCEEDED,API_QUOTA_EXCEEDED) приходит ДО работы: считать чужой сайт и потом говорить «не положено» мы не станем. - Просмотр хода задания и выгрузка результата объём не тратят.
Отказы
Отказ — это всегда тело с двумя полями: code машинным словом и error подписью на языке запроса (язык берём из заголовка Accept-Language). Тот же код дублируется заголовком X-CMS-Error-Code.
| Код | HTTP | Что значит |
|---|---|---|
TOOL_KEY_INVALID | 401 | Ключ не подошёл: не тот, отозванный, с другого сайта или переданный не тем способом. |
TOOL_KEY_NOT_ALLOWED | 403 | Ключ есть, но тариф его больше не позволяет — подписку понизили или она кончилась. |
TOOL_KIND_UNKNOWN | 400 | Такого вида инструмента нет. |
TOOL_NOT_IMPLEMENTED | 501 | Вид объявлен, но он ещё в разработке. |
TARGET_INVALID | 422 | Адрес не передали или он не похож на адрес. |
TARGET_NOT_ALLOWED | 400 | Адрес не ведёт в открытый интернет: внутренняя или служебная сеть. За такими мы не ходим. |
TARGET_UNREACHABLE | 502 | Домен не существует или не отвечает. Это ответ О ЧУЖОМ САЙТЕ, а не наша поломка. |
TARGET_TIMEOUT | 504 | Сайт не ответил за 10 секунд. |
TARGET_TOO_BIG | 413 | Страница больше 5 МБ — дальше мы не читаем. |
TARGET_TOO_MANY_REDIRECTS | 502 | Цепочка переадресаций длиннее пяти шагов. |
OUR_BUDGET | 504 | Вышел НАШ срок на весь прогон. Это не поломка сайта. |
QUOTA_EXCEEDED | 429 | Месячный объём тарифа исчерпан. Счёт начнётся заново в следующем месяце. |
API_QUOTA_EXCEEDED | 429 | Исчерпан месячный объём обращений именно ПО КЛЮЧУ — он меньше объёма проверок. |
RATE_LIMIT_EXCEEDED | 429 | Часовой предел гостя. У ключа на оплаченном тарифе его нет — там считает месячный объём. |
BATCH_TOO_LARGE | 422 | В списке больше адресов, чем позволяет тариф. Объём за это не списан. |
BATCH_BUSY | 429 | Уже идут два задания сайта — дождитесь конца одного из них. |
FILE_UNREADABLE | 422 | Файл прочитать не удалось. Подходят CSV, XLSX и TXT. |
JOB_NOT_FOUND | 404 | Задания нет: истёк его срок (семь дней) или оно с другого сайта. |
Пределы и вежливость к чужим сайтам
Пределы тарифа «Профи»: 30 000 проверок в месяц, 5 000 обращений по ключу в месяц, 5 000 адресов в одном списке, обход до 50 000 страниц, пять ключей, история 365 дней. Сколько осталось — в поле limit.remaining каждого ответа.
Пределы вежливости к ЧУЖОМУ сайту не снимает ни один тариф — они не про того, кто платит, а про того, кого проверяют:
- не больше двух одновременных запросов к одному хосту и пауза 500 мс между ними;
- чужую страницу ждём 10 секунд, читаем первые 5 МБ, идём не больше чем по пяти переадресациям;
- на всю одиночную проверку отведено 18 секунд: не успели — ответ приходит честно частичным (
partial), а не оборванным; - представляемся именем
SeoGenCMS-Tools— по нему нас можно закрыть в своёмrobots.txt; - одновременных заданий на сайт — два.
Проверяйте чужие сайты с той же мерой, с какой хотели бы, чтобы проверяли ваш.