Каталог API за RFC 9727: публікуємо /.well-known/api-catalog
Лише в 4 з 74 API-провайдерів справжній каталог RFC 9727. Опублікуйте /.well-known/api-catalog як application/linkset+json, зв'яжіть OpenAPI, перевірте в curl.

Каталог API за RFC 9727 — це один JSON-файл за адресою /.well-known/api-catalog з типом application/linkset+json, який перелічує ваші публічні API і для кожного дає посилання на машинозчитуваний опис, найчастіше на документ OpenAPI. Інструмент або ШІ-агент, який знає лише ваш домен, може запитати цей файл, піти за посиланням service-desc і зрозуміти, що можна викликати, не розбираючи сайт із документацією. RFC 9727 — документ Standards Track, опублікований у червні 2025 року (IETF RFC 9727).
У стеку готовності це крок виявлення для API. Він стоїть вище за файл OpenAPI і нижче за картки для виклику агентами зі статті про MCP, Agent Skills і A2A та використовує ту саму механіку, що й заголовки Link і sitemap: well-known URL плюс HTTP-заголовок, який на нього вказує. Публікація займає хвилин п'ятнадцять, якщо ваш файл OpenAPI уже загальнодоступний. Саме на цьому «якщо» тихо ламається більшість каталогів.
Ключові висновки
- RFC 9727 реєструє well-known URI і тип зв'язку
api-catalog. Каталог мусить (MUST) бутиapplication/linkset+jsonі посилатися на ендпоінти API; параметрprofileта посилання на OpenAPI — це SHOULD і RECOMMENDED (RFC 9727).- Каталог корисний рівно настільки, наскільки корисна ціль його
service-desc. Якщо цей URL закритий, віддає 404, HTML-сторінку чи невалідний JSON, агент нічого не дізнається.- Сторона, що публікує, SHALL відповідати і на HEAD, і на GET за
/.well-known/api-catalog, причому відповідь на HEAD несе заголовокLink. Частина роутерів відповідає лише на GET. Наш так і робив, доки я не перевірив його для цієї статті.- Впровадження поки на ранній стадії. Одна незалежна перевірка в травні 2026 року знайшла справжній каталог у 4 із 74 API-провайдерів, а 68 повернули 200 із HTML-сторінкою (API Evangelist). Це вибірка одного автора, а не перепис.
- Перевірка
api_catalogв aiSiteReady зараховується, лише якщо валідний каталог веде до валідного документа OpenAPI або JSON Schema. Проскануйте свій домен, щоб побачити, на якому кроці ланцюжок рветься.
Що визначає RFC 9727?
RFC 9727 визначає передбачуване місце, де можна спитати: «Які API публікує цей хост?» Він реєструє well-known URI api-catalog і тип зв'язку api-catalog та вимагає, щоб документ за ними був Linkset — форматом із RFC 9264. Linkset — це самостійний документ із типізованих посилань, кожне з яких має контекст (anchor), тип зв'язку і ціль.
Де живуть самі API, RFC 9727 не диктує. Розташування документа каталогу обирає сторона, що публікує, а /.well-known/api-catalog — лише зручне посилання на нього (RFC 9727, розділ 2).
Основний нормативний текст вміщається в одну таблицю.
| Вимога | Рівень | RFC 9727 |
|---|---|---|
Відповідати на HTTPS GET за /.well-known/api-catalog каталогом | SHALL | розділ 2 |
Відповідати на HTTPS HEAD заголовком Link із типом зв'язку з розділу 3 | SHALL | розділ 2 |
Публікувати каталог як application/linkset+json | MUST | розділи 4.2, 6.2 |
Додавати profile="https://www.rfc-editor.org/info/rfc9727" | SHOULD | розділ 4.2 |
| Включати гіперпосилання на ендпоінти API | MUST | розділ 4.1 |
| Додавати метадані: політики використання, версії, посилання на OpenAPI | RECOMMENDED | розділ 4.1 |
| Віддавати каталог лише через HTTPS | SHOULD | розділ 8 |
| Обмежувати частоту запитів до каталогу | RECOMMENDED | розділ 8 |
| Перевірити каталог на витоки внутрішніх чи чутливих даних | SHOULD | розділ 8 |
Два правила легко пропустити. Якщо ви вже перелічуєте свої API в іншому форматі, але хочете зайняти цей URI, ви мусите (MUST) додатково віддавати Linkset, а свій формат можете (MAY) повертати через content negotiation. І каталог може посилатися на інші каталоги через тип зв'язку api-catalog — так великий набір API ділять між доменами (розділи 4.2, 4.3 і 5.1).
Як виглядає мінімальний каталог API?
Мінімальний каталог — це один JSON-об'єкт із масивом linkset, у якому один запис про ваш API. Ось увесь обмін для одного API на example.com.
GET /.well-known/api-catalog HTTP/1.1
Host: example.com
Accept: application/linkset+json
HTTP/1.1 200 OK
Content-Type: application/linkset+json; profile="https://www.rfc-editor.org/info/rfc9727"
Cache-Control: public, max-age=3600
{
"linkset": [
{
"anchor": "https://api.example.com/v1",
"service-desc": [
{
"href": "https://api.example.com/v1/openapi.json",
"type": "application/json"
}
],
"service-doc": [
{ "href": "https://api.example.com/docs", "type": "text/html" }
],
"item": [
{ "href": "https://api.example.com/v1/orders" }
]
}
]
}
Форма — це JSON-серіалізація з RFC 9264: об'єкт верхнього рівня має єдиний член linkset, і його значення — масив, навіть якщо запис один. Кожен запис має необов'язковий anchor і по одному масиву на кожен тип зв'язку. Кожній цілі потрібен href (RFC 9264, розділ 4.2). Той самий RFC рекомендує завжди вказувати явний абсолютний anchor, щоб документ залишався зрозумілим, якщо його витягнули з HTTP-відповіді.
Усю роботу роблять назви зв'язків. service-desc веде на машинозчитуваний опис API, зазвичай файл OpenAPI, а service-doc — на документацію для людей. Обидва типи зв'язку, як і service-meta, походять із RFC 8631, а item позначає ціль, яка сама є API-членом каталогу (RFC 9727, розділ 3.1).
| Член | Що дізнається клієнт | Правило |
|---|---|---|
linkset | Набір посилань; завжди масив записів | Мусить (MUST) бути єдиним членом верхнього рівня |
anchor | Про який ресурс посилання, тут — про API | Може (MAY) бути відсутнім; не слід (SHOULD NOT) робити відносним |
service-desc | Машинозчитуваний опис, зазвичай OpenAPI | Тип зв'язку з RFC 8631 |
service-doc | Документація для людей | Тип зв'язку з RFC 8631 |
service-meta | Машинозчитувані метадані: політики, мітки | Тип зв'язку з RFC 8631 |
item | API-член каталогу, сам ендпоінт | RFC 9727, розділ 3.1 |
href | URL цілі | Мусить (MUST) бути присутнім; не слід (SHOULD NOT) робити відносним |
type | Необов'язкова підказка про тип вмісту цілі | Необов'язковий атрибут цілі |
Як перелічити кілька API і вибрати потрібні зв'язки?
Додайте по одному запису на кожен API, прив'яжіть його до базового URL цього API і вкажіть ті зв'язки, що в нього є. Повний каталог із трьох записів виглядає так. Перший API публікує все, другий віддає специфікацію і в YAML, і в JSON, а третій запис указує на каталог партнера.
{
"linkset": [
{
"anchor": "https://api.example.com/orders/v2",
"service-desc": [
{ "href": "https://api.example.com/orders/v2/openapi.json", "type": "application/json" }
],
"service-doc": [
{ "href": "https://developer.example.com/orders", "type": "text/html" }
],
"service-meta": [
{ "href": "https://developer.example.com/orders/policies.json", "type": "application/json" }
],
"status": [
{ "href": "https://api.example.com/orders/v2/health", "type": "application/json" }
],
"item": [
{ "href": "https://api.example.com/orders/v2" }
]
},
{
"anchor": "https://api.example.com/inventory/v1",
"service-desc": [
{ "href": "https://api.example.com/inventory/v1/openapi.yaml", "type": "application/yaml" },
{ "href": "https://api.example.com/inventory/v1/openapi.json", "type": "application/json" }
],
"service-doc": [
{ "href": "https://developer.example.com/inventory", "type": "text/html" }
],
"item": [
{ "href": "https://api.example.com/inventory/v1" }
]
},
{
"anchor": "https://www.example.com/.well-known/api-catalog",
"api-catalog": [
{ "href": "https://partners.example.com/.well-known/api-catalog" }
]
}
]
}
У власних прикладах RFC 9727 показано два основні патерни. В одному кожен запис прив'язано до API, і він несе service-desc, service-doc, service-meta та status. В іншому anchor — це URL каталогу, а кожен API — закладка item (RFC 9727, додаток A). Це ілюстрації, а не альтернативи, між якими треба обирати. Я їх поєдную: записи для кожного API, прив'язані до самого API, плюс посилання item, щоб вимога «посилання на ендпоінти API» виконувалася найпрямішим способом.
status — тип зв'язку для ресурсу зі статусом чи станом сервісу, він теж із RFC 8631. А service-meta беріть для всього, що машині варто знати про сервіс окрім специфікації: політик, міток.
Як клієнти знаходять /.well-known/api-catalog?
Двома способами: запитують /.well-known/api-catalog напряму або читають заголовок Link із rel="api-catalog" на сторінці, яку ви й так віддаєте. RFC 9727 допускає тип зв'язку в HTTP-заголовку, у вмісті або в обох місцях одразу, а ціллю може бути і well-known URI, і будь-який інший URI на вибір сторони, що публікує (розділ 3). Синтаксис заголовка — звичайний веб-лінкінг за RFC 8288 (RFC 8288).
Саме такий заголовок сьогодні віддає головна сторінка aiSiteReady — один зі зв'язків із чотирьох посилань виявлення. Ціль відносна, тому заголовок лишається правильним на будь-якому домені розгортання.
GET / HTTP/1.1
Host: www.ai-siteready.com
Accept: text/html
HTTP/2 200
content-type: text/html;charset=utf-8
link: </sitemap.xml>; rel="sitemap", </llms.txt>; rel="describedby", </site.webmanifest>; rel="manifest", </.well-known/api-catalog>; rel="api-catalog"
У прикладі самого RFC 9727 каталог оголошено заголовком Link та елементом a з rel="api-catalog". Наш сканер читає лише HTTP-заголовок кореневої сторінки, а не HTML-теги, тому заголовок надійніший. Синтаксис докладніше розібрано в посібнику із заголовків Link.
Як віддавати /.well-known/api-catalog?
Повертайте JSON із правильним Content-Type і на GET, і на HEAD, лише через HTTPS. Ось справжній маршрут із Nuxt-сервера aiSiteReady (Nitro), скорочений до важливих рядків. Чистий білдер збирає JSON, а обробник виставляє три заголовки, зокрема Link, якого вимагає розділ 2. Раніше цей маршрут відповідав лише на GET; до цієї вади я повернуся нижче.
// frontend/server/routes/.well-known/api-catalog.ts (фрагмент)
export default defineReadOnlyHandler((event) => {
const config = useRuntimeConfig(event);
const siteUrl = typeof config.public.siteUrl === "string" ? config.public.siteUrl : "";
setResponseHeader(event, "Content-Type", API_CATALOG_CONTENT_TYPE);
setResponseHeader(event, "Link", buildApiCatalogLinkHeader()); // </.well-known/api-catalog>; rel="api-catalog"
setResponseHeader(event, "Cache-Control", "public, max-age=3600");
return buildApiCatalog({ siteUrl });
});
defineReadOnlyHandler — наша невелика обгортка: вона запускає той самий обробник для GET і HEAD, на HEAD віддає порожнє тіло з тим Content-Length, який мав би GET, а на решту методів відповідає 405. Content-Type береться з однієї константи: media type linkset, charset=utf-8 і профіль RFC 9727. charset — наша звичка, а не вимога, сканер його приймає. Те саме на Express коротше, і Express сам відповідає на HEAD із маршруту GET (документація Express).
app.get('/.well-known/api-catalog', (req, res) => {
res
.set('Content-Type', 'application/linkset+json; profile="https://www.rfc-editor.org/info/rfc9727"')
.set('Cache-Control', 'public, max-age=3600')
.set('Link', '</.well-known/api-catalog>; rel="api-catalog"')
.send(JSON.stringify(CATALOG, null, 2));
});
Я запустив саме цей обробник локально: GET і HEAD повернули однакові заголовки. Побічний ефект: res.send() із рядковим тілом дописує до Content-Type параметр charset=utf-8, який таблиця нижче називає зайвим. RFC не показує повного обміну для HEAD; розумне прочитання розділу 2 — заголовок Link із rel="api-catalog", саме його й шле цей обробник. Ці деталі HTTP краще вирішити до релізу.
| Деталь | Що робити | Підстава |
|---|---|---|
Content-Type | application/linkset+json і параметр profile | MUST і SHOULD з розділу 4.2; RFC 9264 реєструє profile єдиним необов'язковим параметром, тож charset не потрібен (UTF-8 обов'язковий) |
GET | 200 і тіло каталогу | SHALL, розділ 2 |
HEAD | 200, ті самі заголовки, що в GET, і заголовок Link | SHALL, розділ 2; RFC 9110 каже, що сервер SHOULD слати ті самі заголовки |
Cache-Control | Короткий публічний TTL; у нас година | RFC лише радить кешування і стиснення для великих каталогів |
| CORS | Серверним агентам не потрібен; * дозволяйте, лише якщо каталог має читати браузерний код | Моя рекомендація; RFC згадує CORS лише для внутрішніх каталогів |
| TLS | Лише HTTPS | SHOULD, розділ 8 |
| Невідомі шляхи | Справжній 404, а не HTML-сторінка з 200 | Див. помилки нижче |
| Інші домени | Редиректити їхній well-known URL на канонічний каталог | RECOMMENDED, розділ 5.1 |
Як каталог пов'язаний з OpenAPI, MCP Server Card і Agent Skills?
Вони відповідають на різні запитання, і жоден не замінює інший. Каталог каже, які API існують і де лежать їхні описи. OpenAPI описує один HTTP API. MCP Server Card каже, як підключитися до MCP-сервера. Навичка (skill) пояснює, як добре користуватися вашим продуктом.
| Шар | На яке запитання відповідає | Де живе | Статус на жовтень 2026 |
|---|---|---|---|
| Каталог API | Які API публікує цей хост? | /.well-known/api-catalog | RFC 9727, червень 2025 |
| OpenAPI | Які операції та схеми має один API? | Ціль service-desc | Специфікація v3.2.1, 10 вересня 2026 |
| MCP Server Card | Як підключитися до цього MCP-сервера? | Будь-який URI на вибір сторони, що публікує | Експериментальний репозиторій |
| Agent Skills | Як агенту користуватися цим продуктом? | /.well-known/agent-skills/index.json | Discovery RFC позначено як чернетку |
OpenAPI допускає документ і в JSON, і в YAML та рекомендує називати головний документ openapi.json або openapi.yaml (OpenAPI Specification v3.2.1). Каталог на нього просто посилається.
Щодо MCP: експериментальний репозиторій Server Card у README пише, що це прототипна робота, а не прийняте чи офіційне розширення MCP, і що клієнти знаходять картки через записи AI Catalog. RFC 9727 там не згадано, тож не чекайте, що запис у api-catalog оголосить MCP-сервер (експериментальний репозиторій server-card, AI Catalog). Публікуйте картку окремо: де саме, розбирає матеріал MCP Server Card: що це і як опублікувати.
Agent Skills — ще один шар. Навичка — це тека з файлом SKILL.md з інструкціями (специфікація Agent Skills), а вебіндекс для неї поки чернетка (discovery RFC від Cloudflare). Разом вони поєднуються добре: SKILL.md самого aiSiteReady підказує агентам, де лежать файл OpenAPI, інтерактивна документація і каталог. Формат індексу показує посібник з Agent Skills.
Які помилки ламають каталог API?
Майже всі вони — той самий збій у різних формах: каталог розбирається, але нікуди не веде або порушує правила структури.
| Помилка | Що відбувається | Виправлення |
|---|---|---|
Content-Type: application/json | Порушує MUST; наша перевірка повідомляє api_catalog_not_linkset, якщо до валідної специфікації не дійшли | Віддавайте application/linkset+json із profile |
SPA-заглушка повертає HTML із 200 за цим шляхом | Парсери перечіпляються; сканування не бачить каталогу (api_catalog_missing) або повідомляє api_catalog_html_response, якщо HTML сховано під JSON-типом | Повертайте 404 на невідомі шляхи й виключіть /.well-known/ з fallback |
Ціль service-desc закрита, віддає 404 або вимагає логін | Каталог нікуди не веде | Опублікуйте специфікацію за публічним URL і перевірте без cookie |
| Зворотний проксі не пропускає шлях до специфікації | Стандартний /openapi.json FastAPI йде на фронтенд і дає 404 | Перенесіть специфікацію під шлях, який проксі пропускає |
| Об'єкт там, де потрібен масив | "service-desc": { "href": "..." } порушує RFC 9264 | Загортайте цілі кожного зв'язку в масив |
Відносний href або anchor | Посилання втрачає контекст при копіюванні; RFC 9264: SHOULD NOT | Будуйте абсолютні URL від канонічного origin |
| OpenAPI лише в YAML | Наша перевірка читає лише JSON і повідомляє api_catalog_documents_invalid_json | Публікуйте ще й openapi.json |
GET працює, HEAD дає 404 | Порушує SHALL з розділу 2 | Маршрутизуйте обидва методи |
| У специфікації чи каталозі внутрішні API | RFC просить перевірку перед розгортанням | Проведіть аудит; фреймворки часто виводять усі маршрути |
У правила про масиви є примітка, яку корисно знати. У прикладі з RFC 9727, розділ 5.1, "api-catalog": "https://..." записано простим рядком. Поданий до RFC erratum (ID 9009, статус «Reported», не підтверджений) стверджує, що там має бути масив з об'єктом посилання, як вимагає RFC 9264 (RFC Editor errata). Дотримуйтеся форми з RFC 9264.
Чого мене навчив власний каталог aiSiteReady?
Каталог був найлегшою частиною. Перевірка api_catalog уже існувала, коли я випустив власний каталог aiSiteReady; складним виявилося зробити досяжним файл, на який він посилається. Білдер лежить у frontend/src/shared/lib/seo/api-catalog.ts і видає один запис з anchor /api/v1, із service-desc на /api/v1/openapi.json, service-doc на /api/v1/docs та item на /api/v1/scans.
FastAPI за замовчуванням віддає /openapi.json і /docs. У проді наш nginx спрямовує на бекенд лише /api/* (і /health), а все інше — на фронтенд Nuxt, тож значення за замовчуванням ішли на фронтенд і давали 404. Рішенням стало перенести їх через openapi_url="/api/v1/openapi.json" і docs_url="/api/v1/docs": це змінює лише адреси, а не вміст схеми.
Змінювати nginx не довелося: наявний блок location /api/ у deploy/nginx/default.conf уже пропускає обидві адреси. Рядок Content-Security-Policy я залишив у фрагменті, бо він важливий для сторінки документації нижче.
# скорочено з deploy/nginx/default.conf
location /api/ {
add_header Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'" always;
proxy_pass http://fastapi_backend/api/;
}
Перевірка 2 жовтня 2026 року: прод віддає каталог із application/linkset+json; charset=utf-8; profile="https://www.rfc-editor.org/info/rfc9727", а специфікація за /api/v1/openapi.json повертає 200 як application/json. Старий кореневий /openapi.json повертає 404, як і задумано.
Перевіряючи власний сайт для цієї статті, я знайшов одну нову ваду, а одну відому знову повернув у свій список.
Новою вадою був HEAD. 2 жовтня 2026 року curl -I за /.well-known/api-catalog повертав 404. Файл маршруту закінчувався на .get.ts, а такий маршрут Nitro прив'язує до GET, і запасного шляху для HEAD його роутер не має; маршрути sitemap.xml і llms.txt без суфікса відповідали на HEAD кодом 200. Це порушувало SHALL з розділу 2, а наш сканер HEAD поки не перевіряє, тож сам цього не помітив. Виправлення — маршрут вище: файл без суфікса, один обробник для GET і HEAD та заголовок Link. Решта .well-known-документів отримала ту саму зміну.
Відома — сторінка документації. /api/v1/docs повертає 200, але сторінка в браузері порожня. Content-Security-Policy на відповідях /api/ починається з default-src 'none', а це блокує CDN-скрипти, потрібні Swagger UI. Наша перевірка проходить, якщо бодай один пов'язаний документ — валідний OpenAPI, тож на порожню сторінку натрапляє людина, яка переходить за service-doc. Її на момент написання не виправлено.
Як перевірити каталог за допомогою curl?
Запитайте його так, як це зробив би агент, перевірте статус і Content-Type, потім ідіть за service-desc і переконайтеся, що специфікація розбирається. Запускайте перевірку за публічним доменом, а не за localhost: більшість поломок живе в шарі проксі та CDN.
# GET: чекаємо 200 і application/linkset+json з параметром profile
curl -sS -D - -o /dev/null -H 'Accept: application/linkset+json' https://example.com/.well-known/api-catalog
# HEAD: чекаємо 200 і заголовок Link з rel="api-catalog"
curl -sSI https://example.com/.well-known/api-catalog
# Ідемо за service-desc і перевіряємо, що це схоже на OpenAPI
curl -sS https://example.com/.well-known/api-catalog | jq -r '.linkset[]."service-desc"[]?.href'
curl -sSL https://api.example.com/v1/openapi.json | jq '{openapi, title: .info.title, paths: (.paths | length)}'
Перша команда має надрукувати рядок статусу 200 і заголовок content-type: application/linkset+json; profile="https://www.rfc-editor.org/info/rfc9727". Остання — версію OpenAPI, назву API і ненульову кількість шляхів. Вбудуйте ті самі перевірки в CI, щоб деплой не міг непомітно зламати виявлення.
#!/usr/bin/env bash
set -euo pipefail
SITE="${1:?usage: check-catalog.sh https://example.com}"
CAT="$SITE/.well-known/api-catalog"
H="$(curl -sS -D - -o /dev/null -H 'Accept: application/linkset+json' "$CAT")"
grep -qiE '^HTTP/[0-9.]+ 200' <<<"$H" || { echo 'FAIL: GET is not 200'; exit 1; }
grep -qi '^content-type: application/linkset+json' <<<"$H" || { echo 'FAIL: Content-Type'; exit 1; }
grep -qi 'profile="https://www.rfc-editor.org/info/rfc9727"' <<<"$H" || echo 'WARN: no RFC 9727 profile'
HH="$(curl -sS -I "$CAT")"
grep -qiE '^HTTP/[0-9.]+ 200' <<<"$HH" || echo 'WARN: HEAD is not 200'
grep -qi '^link:.*rel="\?api-catalog' <<<"$HH" || echo 'WARN: HEAD has no Link rel=api-catalog'
curl -sS "$CAT" | jq -r '.linkset[]."service-desc"[]?.href' | while read -r SPEC; do
curl -sSfL "$SPEC" | jq -e '(.openapi|type=="string") and (.info|type=="object") and (.paths|type=="object" and length>0)' >/dev/null \
&& echo "OK: $SPEC" || { echo "FAIL: $SPEC is not valid OpenAPI JSON"; exit 1; }
done
Я запустив цей скрипт на aiSiteReady 2 жовтня 2026 року: він вивів два попередження про HEAD із вади вище, а потім OK для специфікації. На чистому сайті виводяться лише рядки OK.
Як сканувати /.well-known/api-catalog з кожним релізом?
Один раз зробити це вручну — нормально. Робити це на кожному релізі та за іншими протокольними шарами — якраз робота для сканування. Перевірка api_catalog в aiSiteReady працює всередині категорії Protocol/API. Вона запитує /.well-known/api-catalog та будь-який заголовок Link із rel="api-catalog" на кореневій сторінці — усе через SSRF-безпечний завантажувач, — а потім перевіряє до п'яти пов'язаних документів опису, починаючи із service-desc.
Каталог вважається валідним, якщо дає бодай одне посилання, а сканування окремо фіксує, чи віддано його як application/linkset+json і чи несе він профіль RFC 9727. Опис вважається валідним, якщо це документ OpenAPI із рядком версії, об'єктом info і непорожнім об'єктом paths, або JSON Schema зі структурним ключовим словом. Кожне сканування закінчується одним із чотирьох статусів.
| Статус | Коли |
|---|---|
| PASS | Валідний каталог веде бодай до одного валідного документа OpenAPI або JSON Schema |
| PARTIAL | Каталог є, але це не linkset або він веде до невалідних документів; за шляхом віддається HTML-сторінка під не-HTML типом вмісту; або заголовок Link указує на каталог, який не вдається завантажити |
| FAIL | Нічого не знайдено ні за well-known шляхом, ні в заголовку Link, або за шляхом віддається лише сторінка text/html |
| UNKNOWN | Запит заблоковано або він не вклався в таймаут; 403 і 429 потрапляють сюди, а не у FAIL |
Сьогодні формат linkset фіксується як сигнал і не впливає на PASS: каталог у звичайному JSON, який веде до валідного файлу OpenAPI, усе одно проходить. Не покладайтеся на це, бо він не відповідає стандарту. Для профілю Контентний сайт (content_site) перевірка не запускається, а в профілі API/застосунок (api_application) вона важить у 1,75 раза більше, ніж у профілі Усі перевірки (all). Усі перевірки та ваги перелічено на сторінці методології.
Вбудуйте це в рутину разом з аудитом готовності за 30 хвилин, а весь стек дивіться в матеріалі що таке готовність до ШІ-агентів. Запустіть безкоштовне сканування, щоб побачити, чи може агент пройти від вашого домену до валідного файлу OpenAPI і яке виправлення зробити першим, — англійською, українською чи російською.
Якщо коротко: опублікуйте один документ application/linkset+json за адресою /.well-known/api-catalog, пов'яжіть файл OpenAPI кожного API через service-desc, відповідайте і на GET, і на HEAD та перевірте, що специфікація загальнодоступна. Каталог, що вказує в глухий кут, гірший за його відсутність, бо виглядає завершеним.
IMozz має 20 років у розробці ПЗ, а останній рік будує продукти за допомогою LLM. Він розвиває aiSiteReady, сканер лише для читання, що перевіряє, чи може ШІ-агент прочитати й викликати сайт. Сканер серверно рендерить власний контент як робочий приклад.