vvall
В панель

API

API позволяет читать и изменять файлы сайтов из скриптов и ИИ-агентов. Создайте токен в панели и выберите доступные ему сайты.

Токен также позволяет управлять публичным доступом по ключу. Этот ключ не ограничивает чтение и запись через API: Bearer-токен проверяется независимо, в пределах выбранных сайтов. Карантин, блокировки и отзыв токена сохраняют действие.

Публичный доступ по ключу

GET /sites/{id}/access?path=docs возвращает собственный и действующий режим доступа, источник наследования и настройку родителя. Хеш/ключ не раскрываются. Пустой path означает весь сайт.

# Закрыть папку со случайным ключом просмотра
curl -X PUT -H "Authorization: Bearer $API_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"path":"docs","mode":"key","generate":true}' \
  'https://vvall.ru/api/v1/sites/1/access'

# Явное публичное исключение внутри закрытой папки
curl -X PUT -H "Authorization: Bearer $API_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"path":"docs/public.html","mode":"public"}' \
  'https://vvall.ru/api/v1/sites/1/access'

# Удалить собственное правило папки, вернув наследование
curl -X DELETE -H "Authorization: Bearer $API_TOKEN" \
  'https://vvall.ru/api/v1/sites/1/access?path=docs'

PUT принимает path, mode (inherit/public/key), необязательные key, generate или revoke. generate:true возвращает generated_key один раз; сохраните его безопасно. Для собственного ключа передайте key (12–256 символов). При сохранении существующего режима key без нового значения прежний ключ сохраняется; revoke:true отзывает посетителей. DELETE корня делает сайт открытым, DELETE вложенного объекта возвращает наследование, которое тоже может быть закрытым. Обычные GET/PUT /file продолжают работать без ключа просмотра.

Скачать спецификацию OpenAPI 3.1

Быстрый старт

Базовый адрес: https://vvall.ru/api/v1. Передавайте токен в заголовке Authorization. Каждый токен даёт чтение и запись; права администратора токенам не передаются.

Authorization: Bearer vv_…

В примерах ниже переменная API_TOKEN содержит ваш токен. Никому его не публикуйте и не добавляйте в HTML-файлы сайта.

# Доступные сайты
curl -H "Authorization: Bearer $API_TOKEN" \
  https://vvall.ru/api/v1/sites

# Содержимое корневой папки сайта с ID 1
curl -H "Authorization: Bearer $API_TOKEN" \
  https://vvall.ru/api/v1/sites/1/files

# Скачать файл и получить ETag для защиты от перезаписи
curl -D headers.txt -H "Authorization: Bearer $API_TOKEN" \
  'https://vvall.ru/api/v1/sites/1/file?path=index.html' -o index.html

# Создать новый файл (при существующем имени вернётся 409)
curl -X PUT -H "Authorization: Bearer $API_TOKEN" \
  -H 'Content-Type: application/octet-stream' --data-binary @index.html \
  'https://vvall.ru/api/v1/sites/1/file?path=new.html'

# Сохранить существующий файл; ETag берётся из GET
curl -X PUT -H "Authorization: Bearer $API_TOKEN" \
  -H 'If-Match: "ETAG_ИЗ_GET"' --data-binary @index.html \
  'https://vvall.ru/api/v1/sites/1/file?path=index.html&overwrite=1'

# Загрузить и распаковать ZIP в папку проекта
curl -H "Authorization: Bearer $API_TOKEN" \
  -F 'file=@site.zip' -F 'path=project' \
  https://vvall.ru/api/v1/sites/1/upload

Примеры ответов JSON

GET /sites возвращает канонический публичный url каждого доступного сайта. При блокировке URL сохраняется, но публичный доступ закрыт.

{"sites":[{"id":1,"slug":"example","title":"Мой сайт","blocked_at":null,"url":"https://example.vvall.ru/"}]}

GET /sites/1/files?path=pages:

{"entries":[{"id":42,"site_id":1,"path":"pages/index.html","kind":"file","size":34,"state":"live","etag":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}]}

POST /sites/1/directories с JSON {"path":"pages"}:

{"ok":true}

PUT /sites/1/file?path=pages%2Findex.html с исходным HTML в теле запроса создаёт файл; для замены добавьте overwrite=1 и передайте предыдущий ETag в If-Match. Ответ:

{"entry":{"id":42,"site_id":1,"path":"pages/index.html","kind":"file","size":34,"state":"live","etag":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}

Ответы файлов могут содержать дополнительные поля. GET /file возвращает байты файла, а не JSON. ETag в примерах условный; используйте значение реального ответа. Публичная ссылка на файл строится из url сайта и пути с URL-кодированием каждого сегмента.

Методы

МетодПуть после /sites/{site}Действие
GET/files?path=assetsСодержимое папки
GET / HEAD/file?path=index.htmlБайты файла / заголовки
PUT/file?path=index.htmlСоздать; overwrite=1 для замены
DELETE/file?path=assetsПереместить в корзину
POST/directoriesJSON: {"path":"assets/images"}
POST/copy или /moveJSON: {"path":"a.html","to":"folder/b.html"}
POST/uploadmultipart: file, path, overwrite
GET/archive?path=assetsZIP папки; пустой path — весь сайт
GET/trashСписок объектов корзины
POST/restore или /purgeJSON: {"batch":"trash_batch из списка"}
POST/optimizeJSON: path, width, height, quality, replace

Пути и ограничения

Пути относительные, в UTF-8: assets/main.css. Начальный слеш, обратный слеш, скрытые и служебные файлы запрещены. Для query-параметров используйте URL-кодирование. Сохраняйте точный регистр родительских папок. PHP и другие серверные скрипты запрещены, в том числе внутри ZIP. Разрешены HTML, XML, JS, CSS, JSON, TXT, карты исходников, SVG, растровые изображения и шрифты.

Один файл — до 25 МиБ. ZIP — до 2000 записей, с проверкой размера после распаковки. Квота общая для всех сайтов аккаунта, включая карантин и корзину. Копирование учитывается в квоте.

Для ИИ-агента

  1. Получите список доступных сайтов через GET /sites и список файлов нужного сайта.
  2. Прочитайте исходный файл через GET /file и запомните ETag.
  3. Измените его и отправьте PUT с overwrite=1 и If-Match.
  4. При 409 прочитайте свежую версию и согласуйте изменения. Не повторяйте запись с удалённым If-Match автоматически.
  5. После успешной записи изменение уже опубликовано. Отдельного deploy-метода нет.

Ошибки и модерация

{"error":{"message":"Недостаточно места…","status":413}}

401 — токен недействителен; 403 — операция запрещена; 404 — объект не найден или недоступен токену; 409 — конфликт пути или ETag; 413 — квота или размер; 415 — формат; 422 — некорректные данные; 429 — слишком много запросов.

Карантин доступен владельцу для чтения, скачивания и удаления. Перемещать, копировать или перезаписывать такие файлы нельзя. Восстановление из корзины сохраняет карантин. При блокировке аккаунта или сайта API также работает только на чтение. Через 30 дней блокировки аккаунта доступ закрывается, а файлы удаляются планировщиком. Управление сайтами, токенами и модерацией через этот API отсутствует.

CORS не включён. API предназначен для серверных инструментов и агентов; не храните токены в публичном JavaScript сайта.