Документация · Интеграции

HTTP API v1

Авторизация и справочник HTTP-эндпоинтов Gensite для агентов и серверных интеграций.

HTTP API v1 позволяет зарегистрировать аккаунт, получить токен, читать и менять проекты, страницы, блоки и тему без браузерной сессии.

Базовый URL продакшена:

https://gensite.ru/api/v1

Машинный контракт (OpenAPI 3.1) — подключайте его, а не корень сайта:

https://gensite.ru/api/v1/openapi.json
https://gensite.ru/openapi.json
https://gensite.ru/.well-known/openapi.json

Каталог операций без спецификации: GET https://gensite.ru/api/v1.

Не вызывайте GET /projects или GET /api/projects на https://gensite.ru — эти пути отдают HTML фронтенда Next.js, а не JSON. Правильный список проектов: GET /api/v1/projects.

Для AI-клиентов с поддержкой MCP предпочтителен удалённый MCP Gensite: https://gensite.ru/api/mcp и https://gensite.ru/.well-known/mcp.json. HTTP API нужен для собственных серверных интеграций и клиентов без MCP.

Общие правила

  • Запросы с телом отправляйте с Content-Type: application/json.
  • Защищённые эндпоинты требуют Authorization: Bearer <accessToken>.
  • Ответы имеют формат JSON.
  • В успешных ответах присутствует "success": true.
  • В ответах с ошибкой присутствуют "success": false и строка error.
  • Не передавайте токен в query-параметрах или URL.
  • Не храните email, пароль или токен в клиентском публичном коде.

Токен доступа

Токен начинается с gs1. и действует 30 дней. Он подписан сервером и привязан к ID и email пользователя.

Получить токен можно двумя способами:

  1. В кабинете Настройки → MCP для AI → Выпустить токен — удобно для подключения MCP.
  2. Через POST /login с email и паролем — удобно для серверной интеграции.

После истечения API отвечает 401 с ошибкой Срок токена истёк. Выполните логин повторно или выпустите новый токен в кабинете.

Выпуск нового токена не отзывает старые токены. Если токен раскрыт, сообщите администратору. Без ротации серверного секрета он остаётся действительным до конца своего 30-дневного срока.

Регистрация

POST /api/v1/register
Content-Type: application/json

Тело:

{
  "email": "agent@example.com",
  "password": "надёжный-пароль",
  "name": "AI-агент",
  "inviteToken": "токен или полная ссылка приглашения"
}

Поля:

  • email — обязательный email нового пользователя;
  • password — обязательный пароль, минимум 6 символов;
  • name — необязательное имя;
  • inviteToken — токен приглашения или полная ссылка вида https://gensite.ru/register?invite=….

Если на проде включена регистрация только по приглашениям, inviteToken обязателен. Приглашение может быть привязано к конкретному email, иметь срок действия и использоваться только один раз.

Успех: HTTP 201.

{
  "success": true
}

Ошибка валидации или приглашения: HTTP 400.

{
  "success": false,
  "error": "Текст ошибки"
}

Регистрация не выдаёт API-токен автоматически. После неё вызовите /login.

Вход

POST /api/v1/login
Content-Type: application/json

Тело:

{
  "email": "agent@example.com",
  "password": "надёжный-пароль"
}

Успешный ответ:

{
  "success": true,
  "accessToken": "gs1.…",
  "user": {
    "id": "user_id",
    "email": "agent@example.com",
    "name": "AI-агент"
  }
}

Неверный email или пароль: HTTP 401. Ответ намеренно не сообщает, существует ли пользователь.

Пример:

curl https://gensite.ru/api/v1/login \
  -H 'Content-Type: application/json' \
  --data '{"email":"agent@example.com","password":"ваш-пароль"}'

Список проектов

GET /api/v1/projects
Authorization: Bearer gs1.…

Успешный ответ:

{
  "success": true,
  "projects": [
    {
      "id": "project_id",
      "title": "Лендинг клиента",
      "slug": "landing-klienta",
      "publishedAt": null,
      "editorPath": "/editor/landing-klienta",
      "editorUrl": "https://gensite.ru/editor/landing-klienta"
    }
  ]
}

В список входят собственные проекты, проекты с выданным пользователю доступом и общие проекты без владельца. publishedAt: null означает черновик.

Один проект

GET /api/v1/projects/{id}
Authorization: Bearer gs1.…

{id} — id или slug. Ответ: { success, project } в том же формате, что элемент списка.

Удаление проекта

DELETE /api/v1/projects/{id}
Authorization: Bearer gs1.…

Удаляет проект целиком. Только владелец. Действие необратимо.

Пример:

curl https://gensite.ru/api/v1/projects \
  -H 'Authorization: Bearer gs1.…'

Создание проекта

POST /api/v1/projects
Authorization: Bearer gs1.…
Content-Type: application/json

Тело:

{
  "title": "Сайт студии Север",
  "clientName": "Студия Север",
  "description": "Корпоративный лендинг"
}

Поля:

  • title — обязательная непустая строка;
  • clientName — необязательная строка;
  • description — необязательная строка.

Успех: HTTP 201.

{
  "success": true,
  "project": {
    "id": "project_id",
    "title": "Сайт студии Север",
    "slug": "sait-studii-sever",
    "editorPath": "/editor/sait-studii-sever"
  }
}

Проект создаётся в статусе черновика, принадлежит пользователю из Bearer-токена и не содержит блоков. Полный URL редактора строится как https://gensite.ru + editorPath.

Пример:

curl https://gensite.ru/api/v1/projects \
  -X POST \
  -H 'Authorization: Bearer gs1.…' \
  -H 'Content-Type: application/json' \
  --data '{
    "title":"Сайт студии Север",
    "clientName":"Студия Север",
    "description":"Корпоративный лендинг"
  }'

Перед созданием рекомендуется получить список проектов и проверить возможные дубликаты. Повторяйте POST после сетевой ошибки осторожно: запрос не поддерживает ключ идемпотентности.

Справочник блоков

GET /api/v1/blocks

Эндпоинт публичный и не требует токена. Для AI смотрите families, не только плоский blocks.

{
  "success": true,
  "note": "Блок — готовая секция лендинга. family — вид секции, type — макет редактора…",
  "recommendedPageOrder": ["header", "menu", "cover", "promo", "catalog"],
  "families": [
    {
      "family": "cover",
      "label": "Обложка",
      "stream": "main",
      "purpose": "Первый экран оффера: заголовок, текст, кнопки, широкое изображение.",
      "whenToUse": "Стартовый блок лендинга.",
          "variants": [
            {
              "type": "cover__cover_1",
              "label": "Обложка",
              "layout": "Заголовок, текст, две кнопки и широкое изображение",
              "fields": ["title", "description", "ctaFill.text", "ctaFill.href.value", "image.url"]
            }
          ]
    }
  ],
  "blocks": [
    {
      "type": "cover__cover_1",
      "label": "Обложка",
      "description": "Заголовок, текст, две кнопки и широкое изображение",
      "category": "cover",
      "categoryLabel": "Обложка"
    }
  ]
}

Поля family / category — ключ семейства в конструкторе (cover, form, faq). type — конкретный макет (cover__cover_1). variants[].fields — ключи контента этого макета для POST /api/v1/projects/{id}/blocks и PATCH /api/v1/blocks/{blockId}. Поле blocks — плоский список тех же макетов для совместимости.

Текущий аккаунт

GET /api/v1/me
Authorization: Bearer gs1.…

Ответ: { success, user: { id, email, name } }.

Страницы

GET    /api/v1/projects/{id}/pages
POST   /api/v1/projects/{id}/pages
PUT    /api/v1/projects/{id}/pages
PATCH  /api/v1/projects/{id}/pages/{pageId}
DELETE /api/v1/projects/{id}/pages/{pageId}

POST требует slug и title. Необязательно: metaTitle, metaDescription, ogImage. PUT принимает { "pageIds": ["…"] } — все id обычных страниц в нужном порядке.

Блоки проекта

GET    /api/v1/projects/{id}/blocks
GET    /api/v1/projects/{id}/blocks?pageId=
POST   /api/v1/projects/{id}/blocks
PUT    /api/v1/projects/{id}/blocks
PATCH  /api/v1/blocks/{blockId}
DELETE /api/v1/blocks/{blockId}

POST требует type из справочника. Необязательно: pageId / pageSlug, position, fields, sharedAcrossPages. Без pageId блок добавляется на главную.

PUT принимает { "blockIds": ["…"], "pageId": "…" } — все id выбранной страницы сверху вниз.

PATCH принимает fields и/или sharedAcrossPages.

Тема

GET   /api/v1/projects/{id}/theme
PATCH /api/v1/projects/{id}/theme

PATCH меняет только переданные поля. null сбрасывает поле. Цвета — hex (#0f172a).

Коды ответа

  • 200 — чтение или вход выполнены;
  • 201 — аккаунт, проект, страница или блок созданы;
  • 400 — некорректный JSON, поля или бизнес-правило;
  • 401 — отсутствует, повреждён или истёк Bearer-токен; либо неверны данные входа;
  • 403 — нет прав на изменение или удаление;
  • 404 — проект, страница или блок не найдены;
  • 500 — внутренняя ошибка при загрузке проектов.

Точный текст ошибки находится в поле error. Клиент не должен определять тип ошибки только по русскому тексту — сначала используйте HTTP-статус.

Безопасность

  • Используйте API только по HTTPS.
  • Храните токен в секретах серверной среды или защищённом MCP-конфиге.
  • Не выводите токен в логи и ответы агента.
  • Не передавайте пользователю пароль в промпте, если достаточно токена из кабинета.
  • Перед созданием проекта проверяйте текущий аккаунт через MCP whoami или поле user ответа /login.
  • Если пользователь удалён, ранее выданный токен перестаёт давать доступ, даже пока его срок не истёк.

Ограничения текущей версии

Загрузка файлов, кастомный домен и шаблоны блога через публичный API пока не реализованы — их делает человек в редакторе. Публикация доступна только через MCP (publish_project). Остальные операции конструктора (проекты, страницы, блоки, тема) доступны и по HTTP, и через MCP.