WisyLink Блог

APICLIавтоматизацияразработчикамконструктор сайтов с ИИ

API для создания сайтов с ИИ: генерация сайтов из кода

API для создания сайтов WisyLink: создавайте, обновляйте и выводите список размещённых сайтов из кода — загрузите файлы, отправьте описание и получите адрес.

11 мин. чтение
API для создания сайтов с ИИ: генерация сайтов из кода

API WisyLink позволяет создавать и обновлять размещённые сайты из кода. Загрузите справочные файлы, отправьте сообщение обычным языком в POST /chat — и агент соберёт сайт и разместит его по собственному адресу на wisylink.com. Чтобы изменить сайт, отправьте новое сообщение с тем же id ссылки. Запросы к API расходуют тот же 5-часовой и недельный лимит вашего тарифа.

  • Несколько REST-эндпоинтов покрывают весь жизненный цикл: загрузка файлов, создание или продолжение сайта через POST /chat, проверка статуса, список и удаление сайтов.
  • POST /chat общается с Wisy — тем же ассистентом, что и в приложении, поэтому в ответ может прийти вопрос, а не сборка. Проверьте status, прежде чем начинать опрос.
  • API-ключи создаются на сайте, и у каждого есть собственный лимит расходов — до $10 в день, неделю или месяц — поверх лимитов вашего тарифа.
  • npm-пакет @wisylink/cli оборачивает те же эндпоинты в утилиту командной строки и Node-клиент.
  • Свой домен и ключи сервисов (Stripe, почта) настраиваются в веб- или мобильном приложении; публичный API их не охватывает.

Что можно автоматизировать

API — это тот же чат, только без окна чата. Каждый вызов POST /chat — это сообщение для Wisy; когда задача понятна, ИИ-агент сборки пишет веб-приложение с серверным рендерингом и публикует его по адресу https://<id>.wisylink.com, добавляя сохранение данных, аккаунты или загрузку файлов, если этого требует описание. Параметров для шаблона, темы или типа страницы нет. Всё о сайте — от разделов и текстов до функций и стиля — передаётся в сообщении, так же как это описал бы человек. (Общие принципы мы разбирали в статье о том, что такое ИИ-конструктор приложений.)

Базовый URL — https://api.wisylink.com. Аутентификация — через заголовок x-api-key: <key> или Authorization: Bearer <key>. JSON-эндпоинты принимают Content-Type: application/json, а время указывается в миллисекундах Unix-эпохи.

Эндпоинты API WisyLink
ЭндпоинтМетодНазначениеКлючевые поля
/filesPOSTНачать загрузку файлана входе name, на выходе id
/files/chunksPOSTЗагрузить байты файла, не больше 4 МБ за запросid и last=true в последней части; тело — сырые двоичные данные
/files/:idGETПолучить метаданные файлаcontent_type, name, size
/files/:idDELETEУдалить файлОн также убирается из file_ids всех ссылок
/chatPOSTСоздать сайт (без id) или продолжить работу над ним (с id)message, до 10 file_ids; возвращает id, url, status, answer
/linksGETСписок ваших сайтов, сначала новыеpage, limit (от 1 до 100); items, total_pages, has_next
/links/:idGETПолучить данные одного сайтаstatus, url, file_ids
/links/:idDELETEУдалить сайт и его справочные файлыВозвращает {"ok": true}

Чего публичный API не делает: не задаёт ключи, нужные сайту для платежей или почты (владелец вставляет их в разделе «Интеграции»), не подключает свой домен, не читает и не записывает сохранённые данные сайта и не экспортирует исходный код.

Как получить API-ключ и задать лимит расходов

  1. Войдите на wisylink.com. Ключи создаются только на сайте, в мобильных приложениях этого нет.
  2. Откройте раздел «API-ключи» в настройках аккаунта и нажмите «Сгенерировать ключ».
  3. Назовите ключ по месту, где он будет работать, например «acme-landing-pages-ci», чтобы знать, что сломается, если вы его отзовёте.
  4. Задайте окно и лимит. Выберите день, неделю или месяц и лимит расходов в долларах — до $10 на окно. Окна считаются по суткам UTC, по неделе с понедельника или по календарному месяцу.
  5. Сразу скопируйте ключ. Он показывается один раз. Сохраните его в менеджере секретов или в секретах CI, например как WISYLINK_API_KEY.

Лимит ключа — это предохранитель, а не ваш тариф. Каждый запрос ещё и расходует скользящие 5-часовое и недельное окна вашего аккаунта — те же, что у чата на сайте и в мобильном приложении. Расход считается по объёму ИИ-работы, которую запускает запрос, включая чтение ваших справочных файлов. Лимит проверяется перед каждым запросом, а расход записывается после него, поэтому последний запрос в окне может немного превысить лимит. Отзыв ключа сразу удаляет его, и всё, что им ещё пользуется, получает 401.

Можно ли пользоваться API на бесплатном тарифе? Да. На Community действуют те же правила, что и в приложении: одна сборка за 5-часовое окно, а сайты работают 30 дней и ещё неделю остаются помеченными на удаление. Этого достаточно, чтобы сделать прототип интеграции; для клиентских проектов и пакетной работы платный тариф даёт больший лимит, параллельные сборки и ссылки, которые работают, пока действует подписка.

Загрузка справочных файлов по частям

Справочные файлы — это всё, что агент должен прочитать или разместить на сайте: брендбук, логотип, фото товаров, прайс-лист. Поддерживаются JPEG, PNG, WebP, GIF, HEIC, SVG, MP3, MP4, PDF, XLSX, DOCX, CSV, TXT, JSON и HTML, до 25 МБ каждый. Настоящий тип определяется по содержимому файла, а пустые файлы отклоняются.

Загрузка занимает два вызова. Сначала создайте файл и сохраните полученный id:

curl -s -X POST https://api.wisylink.com/files -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"name":"brand-guide.pdf"}'

Затем отправьте содержимое. Файл размером до 4 МБ уходит одним запросом с last=true:

curl -s -X POST "https://api.wisylink.com/files/chunks?id=$FILE_ID&last=true" -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/octet-stream" --data-binary @brand-guide.pdf

Файлы побольше разрежьте (split -b 4m brand-guide.pdf part_), отправьте части по порядку на тот же id и добавьте last=true только к последней: этот вызов завершает загрузку и запускает обработку файла. Загрузка должна завершиться за 15 минут, иначе сессия истекает. В Node разбиение на части берёт на себя клиент, о котором речь ниже.

Создание сайта через POST /chat и ожидание адреса

Отправка описания

Чтобы начать новый сайт, не передавайте id. Сообщение может быть длиной до 5000 символов — этого хватает на полноценное техзадание: цель, аудитория, разделы, реальные тексты, функции, стиль и язык. Закончите его фразой «остальное выберите на своё усмотрение», чтобы повысить шанс, что сборка начнётся с первого вызова. Замените FILE_ID на id из вашей загрузки.

curl -s -X POST https://api.wisylink.com/chat -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"message":"Сделайте одностраничный сайт для «Эмбер», обжарщика спешелти-кофе в Казани. Разделы: главный экран, три моносорта с ценами, форма оптовой заявки с сохранением в админку, часы работы, ссылка на карту. Цвета и шрифты возьмите из приложенного брендбука. Остальное выберите на своё усмотрение.","file_ids":["FILE_ID"]}'

Тот же вызов из Node через fetch:

const res = await fetch("https://api.wisylink.com/chat", { method: "POST", headers: { "x-api-key": process.env.WISYLINK_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ message: brief, file_ids: [fileId] }) }); let link = await res.json();

Для нового сайта ответ приходит с кодом 201 и полями id, url, status, answer, created_at и updated_at. Сохраните id: по нему вы позже будете менять, читать или удалять сайт. Считайте его непрозрачной строкой и не проверяйте формат.

Проверьте статус перед опросом

Поле status в ответе POST /chat показывает, началась ли сборка на самом деле:

building или queued
Сборка идёт или ждёт свободного места (queued пока нет в списке справочника, но он встречается). Начинайте опрос. У нового сайта по адресу url открывается страница «идёт сборка», пока не завершится первая сборка.
idle у нового сайта
Сборка не началась. Вместо неё Wisy ответил, и в answer обычно один короткий вопрос, например какой платёжный сервис использовать. Ответьте новым вызовом POST /chat с тем же id.
completed или aborted сразу после продолжения
У существующего сайта статус показывает результат последней сборки. Если он не сменился на building, на ваше сообщение пришёл ответ, а не сборка; прочитайте answer.

Опрашивайте, пока сборка не завершится

Вебхуков нет, поэтому опрашивайте GET /links/:id. Сборка длится минуты, а не секунды, так что раза в 15–30 секунд вполне достаточно. Считайте любой статус, кроме completed, aborted и idle, признаком того, что работа ещё идёт: так цикл не сломается, если появится новый промежуточный статус:

const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); while (!["completed", "aborted", "idle"].includes(link.status)) { await sleep(20000); link = await (await fetch(`https://api.wisylink.com/links/${link.id}`, { headers: { "x-api-key": process.env.WISYLINK_API_KEY } })).json(); }

Когда status равен completed, в url — ваш работающий сайт. aborted означает, что сборка остановилась, не завершившись; уже работающий сайт сохраняет предыдущую версию, а новое сообщение запускает ещё одну попытку. Если позже к сайту подключат свой домен, url будет возвращать этот домен. Полный отчёт о сборке, включая пометку, что сайт ждёт ключей Stripe или почты, есть в чате этой ссылки в веб-приложении.

Продолжение, список и удаление ссылок

Чтобы изменить сайт, отправьте только новую инструкцию и его id вместо LINK_ID; история разговора хранится на сервере, а на продолжение приходит ответ 200:

curl -s -X POST https://api.wisylink.com/chat -H "x-api-key: $WISYLINK_API_KEY" -H "Content-Type: application/json" -d '{"id":"LINK_ID","message":"Добавьте вторую точку: ул. Баумана, 12, ежедневно с 7:00 до 15:00."}'

Затем опрашивайте статус так же, как раньше. Каждое изменение — новая сборка: неудачная оставляет в работе последнюю удачную версию, а удачная публикуется сразу после завершения, поэтому проверяйте сайт после каждого изменения. Дождитесь окончания одной сборки, прежде чем отправлять следующее изменение, если только новое сообщение не исправляет текущую сборку.

Чтобы получить список сайтов, листайте GET /links?page=1&limit=100, пока has_next не станет false. Чтобы удалить сайт, вызовите DELETE /links/:id: он удаляет сайт и прикреплённые к нему справочные файлы. Свой домен, если он был подключён, остаётся в аккаунте и готов для другого сайта.

CLI и Node-клиент

Пакет @wisylink/cli (лицензия MIT, Node 18.17 или новее) сопоставляет команды с эндпоинтами выше один к одному, поэтому это самый быстрый способ управлять WisyLink из скрипта оболочки или задачи CI:

  • npm i -g @wisylink/cli, затем export WISYLINK_API_KEY=... или флаг --api-key в каждой команде.
  • wisylink files upload ./brand-guide.pdf загружает файл частями по 4 МБ автоматически.
  • wisylink chat --message "Сделайте лендинг для кофейни «Эмбер»." --file-id FILE_ID создаёт сайт.
  • wisylink links list --page 1 --limit 50 выводит список ваших сайтов.

Команды печатают JSON, поэтому id или url легко достать через jq. --timeout принимает от 1000 до 120 000 миллисекунд; увеличьте его для chat, которая ждёт ответа Wisy.

Тот же пакет экспортирует Node-клиент: import { CreateWisyLinkClient } from "@wisylink/cli"; const client = CreateWisyLinkClient({ apiKey: process.env.WISYLINK_API_KEY }); const file = await client.uploadFile("./brand-guide.pdf"); const link = await client.chat({ message: brief, fileIds: [file.id] });

Два замечания о версиях на момент npm-релиза 0.2.1. Во-первых, команды и методы клиента, принимающие id ссылки (chat --link-id, links get, links delete, а в Node — linkId, getLink, deleteLink), проверяют id по старому формату и отклоняют текущие, поэтому продолжайте, читайте и удаляйте сайты через HTTP, как показано выше. Во-вторых, документация CLI (на английском) уже описывает более новый релиз со входом через браузер (wisylink login), интерактивным чатом с ходом сборки в реальном времени и флагом --json; выполните wisylink --version, чтобы узнать, какая версия у вас.

Лимиты, ошибки и хорошие практики

Ошибки возвращаются в виде JSON с кодом в поле error. Вот те, которые стоит обрабатывать отдельно:

429 limit_reached
5-часовое или недельное окно вашего тарифа исчерпано (reason равен 5h_limit или weekly_limit). Запланируйте повтор на момент reset_at (в миллисекундах эпохи), а не повторяйте запрос в цикле.
429 credit_limit_exceeded
Этот ключ исчерпал собственный лимит расходов. Ошибка возможна на любом эндпоинте; дождитесь resets_at или поднимите лимит (до $10) на сайте.
429 build_concurrency_limit
Для вашего тарифа запущено слишком много сборок. Дождитесь завершения одной из них и отправьте следующую.
429 rate_limited
Слишком много запросов за короткое время. Сделайте паузу и повторите.
400 bad_request
Некорректный JSON, пустое сообщение или сообщение длиннее 5000 символов либо несуществующие id файлов (они перечислены в missing_file_ids). Учтите, что используются только первые 10 file_ids; лишние отбрасываются без ошибки.
401, 404, 500 chat_unavailable
Ключ отсутствует или отозван; ссылка или файл вам не принадлежат; Wisy временно недоступен — стоит один раз повторить запрос после паузы.

Привычки, которые экономят деньги и нервы:

  • Храните ключи на сервере. Никогда не вставляйте ключ в код браузера или приложения. Заведите по ключу на каждого клиента или конвейер, чтобы у каждого был свой лимит и его можно было отозвать отдельно.
  • Не повторяйте POST /chat вслепую. Этот вызов не идемпотентен: запрос, который на вашей стороне завершился по таймауту, мог всё же создать сайт или запустить сборку. Прежде чем отправлять его снова, проверьте GET /links (новые идут первыми) и задайте клиентский таймаут не меньше минуты.
  • Ставьте пакетные задачи в очередь. Запускайте одновременно столько сборок, сколько позволяет тариф, а build_concurrency_limit воспринимайте как сигнал подождать.
  • Проверяйте перед публикацией. Результат работы ИИ может содержать ошибки. Откройте каждый сайт, проверьте формы и прочитайте тексты, прежде чем их увидит клиент или публика; по условиям WisyLink проверка и тестирование — ваша ответственность.

Примеры: лендинги, микросайты, внутренние инструменты

Лендинги для клиентов агентства. Держите шаблон описания с полями для названия клиента, оффера, разделов и тона, заполняйте его из CRM и прикрепляйте логотип и брендбук клиента как файлы. Каждая кампания становится отдельным сайтом, правки клиента — следующими сообщениями, а отдельный ключ на клиента разделяет расходы. Когда страницу одобрят, подключите домен клиента в разделе «Домены» на любом тарифе; платный тариф сохранит сайт в сети после первых 30 бесплатных дней. Разобранный пример самой страницы — в статье о том, как сделать лендинг с листом ожидания с помощью ИИ.

Микросайты для каждого мероприятия. Одна строка в таблице на мероприятие (название, дата, площадка, вместимость) превращается в отдельный сайт регистрации, который создаёт скрипт, сохраняя полученный id рядом со строкой. Что писать в каждом описании, показывает статья о том, как создать страницу регистрации на мероприятие с ИИ. После мероприятия удалите сайт или оставьте его как архив на платном тарифе.

Внутренняя автоматизация. Скрипт может создать первую версию внутреннего инструмента, например учёта остатков или доски согласований. Но не пересобирайте сайт ради обновления данных: попросите Wisy добавить эндпоинт, в который ваши системы будут отправлять записи, и защитить его секретом, который вы зададите в разделе «Интеграции». Записи, отправленные таким способом, видны посетителям примерно через минуту и не расходуют сборку. Подробнее об этом подходе — в статье о внутренних инструментах с ИИ.

Получите ключ и соберите первый сайт из кода

Создайте бесплатный аккаунт, сгенерируйте API-ключ с небольшим лимитом и отправьте первое описание вызовом curl, показанным выше. Держите под рукой справочник API (на английском) с подробностями по каждому полю, а когда интеграция перерастёт прототип, выберите в разделе с тарифами план с тем лимитом сборок и числом параллельных сборок, которые нужны для ваших объёмов.

ЧАВО

Часто задаваемые вопросы

Можно ли пользоваться API WisyLink бесплатно?
Да. API-ключи может создать любой аккаунт, а вызовы расходуют тот же лимит Community, что и чат: одна сборка за 5-часовое окно, а бесплатные сайты работают 30 дней и ещё неделю остаются помеченными на удаление. Этого хватит, чтобы собрать и проверить интеграцию от начала до конца. Для рабочих объёмов платный тариф увеличивает 5-часовое и недельное окна, разрешает несколько сборок одновременно и сохраняет сайты, пока действует подписка.
Как оплачивается использование API?
Отдельного счёта за API нет. Запросы расходуют скользящие 5-часовое и недельное окна вашего тарифа, а расход считается по ИИ-работе, которую запускает каждый запрос, например по рассуждениям агента и чтению ваших справочных файлов. Сама загрузка файла ничего не стоит. Кроме того, у каждого ключа может быть свой лимит в долларах, не больше $10 за день, неделю или месяц: он останавливает только этот ключ и не затрагивает остальные.
Как узнать, что сборка закончилась?
Опрашивайте GET /links/:id каждые 15–30 секунд, пока status не станет completed, а затем используйте возвращённый url. Если status сменился на aborted, сборка остановилась, а существующий сайт сохранил последнюю удачную версию. Если вызов создания вернул idle, сборка вообще не запущена: прочитайте поле answer — там обычно вопрос — и ответьте новым POST /chat с тем же id.
Можно ли подключить свой домен через API?
Через публичный API — нет. Подключите и подтвердите домен в разделе «Домены» в веб-приложении или в приложениях для iOS и Android, а затем назначьте его сайту; свой домен можно подключить на любом тарифе, в том числе бесплатном. После этого GET /links/:id возвращает ваш домен в поле url, так что скрипты, которые читают url, продолжат работать. Если своего домена ещё нет, сначала зарегистрируйте его у любого регистратора доменов.
Есть ли SDK для API WisyLink?
Пакет @wisylink/cli содержит и утилиту командной строки, и Node-клиент, который создаётся функцией CreateWisyLinkClient. Он умеет загружать файлы, создавать сайты и выводить их список. В npm-релизе 0.2.1 методы, принимающие id ссылки, отклоняют текущие id, поэтому для продолжения, чтения и удаления сайтов используйте обычные HTTP-запросы, пока это не исправят в новом релизе. Из других языков можно обращаться к REST-эндпоинтам напрямую.
Какие ошибки API нужно обрабатывать?
Как минимум: 429 limit_reached — ждать до reset_at; 429 credit_limit_exceeded — собственный лимит ключа исчерпан до resets_at; 429 build_concurrency_limit — ставить задачу в очередь, пока текущая сборка не завершится. Кроме того, делайте паузу при 429 rate_limited, один раз повторяйте запрос после 500 chat_unavailable и записывайте в лог ответы 400: обычно они указывают на слишком длинное сообщение или неверный id файла.
Поделиться
XLinkedInFacebook