API и эндпоинты
Site Connector Protocol v1.0 · OpenAPI docs/openapi/site-connector-v1.yaml · Partner Admin API v1 northbound к агенту
Агент не говорит на диалектах Woo/Shopify/Bitrix. CMS-плагин или ваш бэкенд реализуют единый southbound-контракт. Ниже — версии, auth, эндпоинты с примерами запросов и ответов.
Версии
| Контракт | Версия | Где смотреть |
|---|---|---|
| Site Connector Protocol | 1.0 (contractVersion) | Поле в GET /health; OpenAPI info.version = "1.0" |
| Partner Admin API | v1 | Префикс пути /v1/partner/projects/:projectId/… |
Breaking-изменения southbound → новая major в пути/контракте (например v2). Пока агент ждёт ровно contractVersion: "1.0". Legacy-ответ { "ok": true, "version": "1.0" } принимается как алиас.
Site Connector — базовый URL и auth
Рекомендуемый суффикс: https://your-site.example/seo-agent/v1
Авторизация сервер↔сервер (ключ не в браузер / Embed):
Authorization: Bearer <connector-key> # или X-Api-Key: <connector-key> # кабинет агента также использует x-seo-agent-key: sea_...
Опционально на мутациях: Idempotency-Key, dry-run X-Dry-Run: 1.
Ошибки (общая форма)
{
"error": {
"code": "FORBIDDEN_CAPABILITY | VALIDATION | NOT_FOUND | RATE_LIMIT",
"message": "Human-readable detail"
}
}Обязательный минимум (L1 observe + meta)
/healthcontract 1.0Жив ли bridge и какая версия контракта.
Ответ 200
{
"ok": true,
"contractVersion": "1.0",
"platformVersion": "wp-plugin/1.2.0",
"detail": "optional"
}/capabilitiesОбъявляйте только то, что реально работает — иначе миссии уйдут в failed. L2/Tilda не должны светить write-capabilities без поддержки.
Enum: listUrls, getPage, updateSeoMeta, upsertContent, upsertFile, publish, createRedirect, sitemapRegen, rollback, healthcheck.
resourceKinds: page | post | product | category.
Ответ 200
{
"capabilities": [
"listUrls",
"getPage",
"updateSeoMeta",
"upsertContent",
"publish",
"createRedirect",
"sitemapRegen",
"rollback",
"healthcheck"
],
"resourceKinds": ["page", "post", "product"]
}/urls?cursor=&limit=100Список индексируемых ресурсов. Пагинация через next_cursor (nullable).
Ответ 200
{
"items": [
{
"id": "page_1",
"url": "https://example.com/a",
"kind": "page",
"locale": "ru",
"updatedAt": "2026-08-16T12:00:00.000Z"
},
{
"id": "product:12",
"url": "https://example.com/p/12",
"kind": "product"
}
],
"next_cursor": null
}/pages/{id} · GET/pages?url=Карточка ресурса. Обязательны id, url, seo. commerce — только для магазинов; цены как decimal-строки «как на сайте».
Ответ 200
{
"id": "product:12",
"url": "https://example.com/p/12",
"kind": "product",
"locale": "ru",
"seo": {
"title": "Тормозные колодки BP-1",
"description": "Оригинал, доставка по РФ",
"canonical": "https://example.com/p/12",
"robots": "index,follow",
"h1": "Тормозные колодки"
},
"content": {
"format": "html",
"body": "<p>…</p>"
},
"commerce": {
"offer": {
"source": "connector",
"name": "Brake pads",
"price": "1990.00",
"priceCurrency": "RUB",
"availability": "InStock",
"sku": "BP-1",
"fetchedAt": "2026-08-16T12:00:00.000Z"
}
},
"locked": false
}/pages/{id}/seoLive SEO-поля (title / description / canonical / robots / h1). Тело — частичный SeoMeta. Без capability updateSeoMeta проект остаётся observe-only. Контент тела страницы — через POST /contents, не сюда.
Запрос
PATCH /pages/product:12/seo
Content-Type: application/json
{
"title": "Тормозные колодки BP-1 — купить",
"description": "Доставка по РФ, гарантия"
}Ответ 200
{
"ok": true,
"diff": {
"before": {
"title": "Тормозные колодки BP-1",
"description": "Оригинал, доставка по РФ",
"canonical": "https://example.com/p/12",
"robots": "index,follow",
"h1": "Тормозные колодки"
},
"after": {
"title": "Тормозные колодки BP-1 — купить",
"description": "Доставка по РФ, гарантия",
"canonical": "https://example.com/p/12",
"robots": "index,follow",
"h1": "Тормозные колодки"
}
}
}/contentsUpsert черновика/контента. L1 обязан поддерживать status: "draft". Запись цены/остатков — вне scope v1.0.
Запрос (предпочтительный)
{
"url": "https://example.com/blog/new",
"locale": "ru",
"title": "Как выбрать колодки",
"body_html": "<p>…</p>",
"status": "draft"
}Алиас (старые GenericHttp-клиенты)
{
"url": "https://example.com/blog/new",
"title": "Как выбрать колодки",
"status": "draft",
"content": { "format": "html", "body": "<p>…</p>" }
}Ответ 200
{
"ok": true,
"id": "post:88",
"url": "https://example.com/blog/new",
"status": "draft"
}SHOULD-эндпоинты (по возможности)
| Метод | Путь | Назначение |
|---|---|---|
| POST | /redirects | { "from", "to", "code" } |
| PUT | /robots | текст robots.txt |
| POST | /sitemap/regen | пересборка sitemap |
| POST | /actions/dry-run / /actions/apply | generic dry-run / apply |
| POST | /actions/{id}/rollback | откат |
| GET | /pages/{id}/preview | URL превью |
Partner Admin API (v1)
Northbound: ваша админка → SEO Agent. База: https://<seo-agent-host>/v1/partner/projects/{projectId}/…
Auth: заголовок x-seo-agent-key: sea_… (проектный ключ партнёра).
/v1/partner/projects/{projectId}/embed-sessionКороткоживущий URL для iframe Центра управления (Embed Kit).
Запрос
POST /v1/partner/projects/prj_01H…/embed-session
x-seo-agent-key: sea_live_…
Content-Type: application/json
{}Ответ 200 (поля могут дополняться; TTL из EMBED_SSO_TTL_SEC, по умолчанию ~1800 с)
{
"url": "https://52525.ru/aita/app/embed?token=eyJ…",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"expiresIn": 1800
}Остальные Partner-методы (stats, keywords, webhooks, badges) — в инженерной доке репозитория; публичный минимум для встройки — embed-session + Site Connector на стороне сайта.
Beacon collect (счётчик сайта)
Публичный эндпоинт для first-party аналитики. Ключ bea_… выпускается в кабинете (Подключение → Счётчик сайта). Не путать с Partner API sea_…. Подробнее: документация beacon.
/v1/collectПриём pageview-событий со страниц сайта. CORS *, ответ 202 Accepted. Worker агрегирует в журнал для AI-советника.
POST /v1/collect
X-Seo-Beacon-Key: bea_live_…
Content-Type: application/json
{
"projectId": "prj_…",
"visitorId": "v_…",
"sessionId": "s_…",
"events": [
{
"name": "pageview",
"path": "/catalog",
"title": "Каталог",
"referrer": "https://yandex.ru/…"
}
]
}Сниппет для сайта (без ручного вызова API): …/embed/seo-beacon.js с атрибутами data-project, data-key, data-api.
/projects/{projectId}/beaconСтатус счётчика и шаблон сниппета (JWT кабинета). Ключ полностью возвращается только при POST …/beacon/regenerate.
Соответствие port → HTTP
| Port | HTTP |
|---|---|
healthcheck | GET /health |
capabilities | GET /capabilities |
listUrls | GET /urls |
getPage | GET /pages/{id} |
updateSeoMeta | PATCH /pages/{id}/seo |
upsertContent | POST /contents |
Типовой сценарий
- Поднять
/healthсcontractVersion: "1.0"и/capabilitiesна staging. - В кабинете: проект → Подключение → Generic HTTP (baseUrl + секрет).
- «Проверить связь» в UI.
- Ручной
PATCH …/seoна одной странице → смотритеdiff. - Включить авто meta-теги только после проверки. CMS-гайды: коннекторы, старт, Embed Kit.