Перейти к содержанию

Медиафайлы

Эндпоинты для управления медиафайлами, прикреплёнными к страницам, и медиафайлами уровня сайта, их метаданными в .meta.yaml, ручным порядком папок медиафайлов сайта и файлами, сохранёнными полями схем с типом «файл». Для чтения нужно api.media.read, а для любых изменений — api.media.write. Медиафайлы страницы также подчиняются собственным правилам доступа страницы, поэтому страница, которая запрещает вам чтение или обновление, возвращает 403. Миниатюры публичны.

Список медиафайлов страницы

GET /pages/{route}/media

Выводит все медиафайлы страницы с необязательной фильтрацией и сортировкой по метаданным.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
filter string Нет Фильтр по метаданным в виде field:operator:value (или field:value). Можно повторять через filter[]=. Операторы: == != > >= < <= in contains.
sort string Нет Поле метаданных (или встроенное filename/size/modified), по которому сортировать
order string Нет Направление сортировки: asc (по умолчанию) или desc

Ответ

{"data": [{"filename": "photo.jpg", "url": "/user/pages/01.blog/photo.jpg", "type": "image/jpeg", "size": 245000, "alt": "Sunset over the bay", "dimensions": {"width": 1920, "height": 1080}, "thumbnail_url": "/api/v1/thumbnails/3f2a9c1e4b5d6a7f8e9d0c1b2a394857.jpg", "modified": "2026-09-01T10:15:00+00:00"}]}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.media.read или правила самой страницы запрещают чтение
404 Страница не найдена
422 Неверный параметр filter/sort

Фильтрация и сортировка по метаданным

Если у ваших медиафайлов есть метаданные в сопутствующих файлах .meta.yaml, список можно фильтровать и сортировать по этим значениям, а не загружать весь набор. Это повторяет методы запросов коллекций Twig, но привязано к схеме метаданных, настроенной в разделе Плагины → API → Метаданные медиафайлов (plugins.api.media_metadata.fields).

Фильтр

Каждое условие filter имеет вид field:operator:value. Повторяйте его через filter[]=, чтобы применить несколько условий (они объединяются по И):

GET /pages/blog/media?filter=rating:>=:3&filter[]=tags:contains:sunset

Доступные операторы: ==, !=, >, >=, <, <=, in и contains. Оператор можно опустить (filter=copyright:Jane Doe) — тогда он выводится из типа поля: contains для поля tags, == в остальных случаях. Для оператора in укажите набор через запятую: filter=rating:in:4,5.

Сортировка

GET /pages/blog/media?sort=rating&order=desc

sort принимает любое настроенное поле метаданных, а также встроенные ключи filename, size и modified. order — это asc (по умолчанию) или desc; медиафайлы без поля сортировки всегда идут последними. (dir принимается как псевдоним order.)

Правила и ограничения

  • Привязка к схеме. Фильтровать и сортировать можно только по полям, определённым в media_metadata.fields; неизвестные поля игнорируются. Поле tags принимает только in/contains.
  • Валидация. Неизвестный оператор, некорректное условие, неверное поле sort или больше 10 условий filter возвращают 422. Фильтрация использует существующее разрешение api.media.read и не раскрывает значений метаданных, которые вызывающая сторона и так не могла прочитать.
  • Ограничение. Не более 10 условий filter на запрос.

Загрузка медиафайлов страницы

POST /pages/{route}/media

Загружает файл(ы) на страницу через данные multipart-формы.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
file file Да Загружаемый файл (multipart/form-data). Подходит любое имя поля, включая имена вложенных массивов, например files[]; в одном запросе можно отправить несколько файлов.
random_name boolean Нет Заменить имя файла случайным, сохранив расширение (по умолчанию: false)
avoid_overwriting boolean Нет Добавить префикс с отметкой времени вместо замены существующего файла с тем же именем (по умолчанию: false)
accept string Нет Список разрешённых расширений через запятую (.pdf, *.jpg) или шаблонов MIME (image/*)
filesize number Нет Максимальный размер для поля в МБ. Может только уменьшить предел 64 МБ.

Ответ

{"data": [{"filename": "photo.jpg", "url": "/user/pages/01.blog/photo.jpg", "type": "image/jpeg", "size": 245000, "dimensions": {"width": 1920, "height": 1080}, "thumbnail_url": "/api/v1/thumbnails/3f2a9c1e4b5d6a7f8e9d0c1b2a394857.jpg", "modified": "2026-09-01T10:15:00+00:00"}]}

Коды ответов

Код Описание
201 Файл загружен
401 Не авторизован
403 Нет разрешения api.media.write или правила самой страницы запрещают обновление
404 Страница не найдена
422 Ошибка валидации (нет файла, неверное имя или тип файла, либо файл слишком большой)

Отправляйте файл запросом multipart/form-data, а не JSON. Заголовок Content-Type должен иметь значение multipart/form-data.

Ответ перечисляет все медиафайлы страницы после загрузки, а не только новые файлы, а заголовок Location указывает на коллекцию медиафайлов страницы. Размер каждого файла ограничен 64 МБ. У файла должно быть расширение, и ни одна разделённая точками часть его имени не должна входить в security.uploads_dangerous_extensions (поэтому shell.php.jpg отклоняется). Содержимое SVG санируется при поступлении.

Необязательные поля формы random_name, avoid_overwriting, accept и filesize применяют настройки загрузки поля схемы с типом «файл» поверх этих проверок.


Удаление медиафайла страницы

DELETE /pages/{route}/media/{filename}

Удаляет медиафайл со страницы.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
filename string Да Имя удаляемого медиафайла

Коды ответов

Код Описание
204 Файл удалён
401 Не авторизован
403 Нет разрешения api.media.write или правила самой страницы запрещают обновление
404 Страница или файл не найдены
422 Неверное имя файла (начинается с точки или содержит ..)

Удаляет файл и его сопутствующий файл .meta.yaml, если он есть. Варианты файла для retina (name@2x.jpg, name@3x.jpg и т. д.) и их сопутствующие файлы тоже удаляются, поэтому изображение, сохранённое только как вариант retina, всё равно можно удалить по базовому имени.


Список медиафайлов сайта

GET /media

Выводит медиафайлы и папки уровня сайта с постраничной разбивкой, просмотром подпапок, поиском, фильтрацией по типу, а также фильтрацией и сортировкой по метаданным.

Параметры

Имя Тип Обязательный Описание
page integer Нет Номер страницы для постраничной разбивки (по умолчанию: 1)
per_page integer Нет Число результатов на странице (по умолчанию: 20, максимум: 1000, оба значения настраиваются)
path string Нет Путь подпапки относительно корневой директории медиафайлов
search string Нет Рекурсивный поиск по имени файла без учёта регистра во всех подпапках. Нельзя сочетать с filter или sort.
type string Нет Фильтр по типу медиафайла: image, video, audio или document (всё, что не image, video или audio)
filter string Нет Фильтр по метаданным в виде field:operator:value (или field:value). Можно повторять через filter[]=, до 10 условий. Те же правила, что и для медиафайлов страницы.
sort string Нет Поле метаданных (или встроенное filename/size/modified), по которому сортировать. Переопределяет ручной порядок папки.
order string Нет Направление сортировки: asc (по умолчанию) или desc

Ответ

{"data": [{"filename": "hero.jpg", "path": "blog", "url": "/user/media/blog/hero.jpg", "type": "image/jpeg", "size": 184320, "dimensions": {"width": 1600, "height": 900}, "thumbnail_url": "/api/v1/thumbnails/3f2a9c1e4b5d6a7f8e9d0c1b2a394857.jpg", "modified": "2026-09-01T10:15:00+00:00"}], "meta": {"pagination": {"page": 1, "per_page": 20, "total": 1, "total_pages": 1}, "path": "blog", "folders": [{"name": "2026", "path": "blog/2026", "children_count": 0, "file_count": 4}], "ordered": false}, "links": {"self": "/api/v1/media?page=1&per_page=20"}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.media.read
422 Неверный путь, search вместе с filter или sort, либо неверный параметр filter/sort

Возвращает медиафайлы и папки из директории user/media. Поддерживает просмотр подпапок через параметр path, рекурсивный поиск через search, фильтрацию по типу файла через type и фильтрацию с сортировкой по метаданным .meta.yaml через filter, sort и order (синтаксис фильтра см. в разделе Список медиафайлов страницы). Ответ содержит массив folders в объекте meta со списком непосредственных подпапок текущего пути, а meta.ordered сообщает, есть ли у папки сохранённый ручной порядок.

Файлы идут в сохранённом ручном порядке папки (см. Задание порядка медиафайлов), если он есть, иначе — в естественном порядке имён. Сопутствующие файлы .meta.yaml и файл порядка media_order.yaml никогда не попадают в список — ни при просмотре папки, ни в результатах поиска.

Для несуществующей папки возвращается пустой список, при этом meta.pagination повторяет запрошенные page и per_page, а meta.ordered отсутствует. В режиме поиска meta.path пуст, meta.folders пуст, meta.search содержит поисковый запрос, а meta.ordered отсутствует.


Загрузка медиафайлов сайта

POST /media

Загружает файлы в директорию медиафайлов уровня сайта.

Параметры

Имя Тип Обязательный Описание
path string Нет Параметр запроса: путь подпапки для загрузки (создаётся автоматически, если не существует)
file file Да Загружаемый файл (multipart/form-data). Подходит любое имя поля, включая имена вложенных массивов, например files[]; в одном запросе можно отправить несколько файлов.
random_name boolean Нет Заменить имя файла случайным, сохранив расширение (по умолчанию: false)
avoid_overwriting boolean Нет Добавить префикс с отметкой времени вместо замены существующего файла с тем же именем (по умолчанию: false)
accept string Нет Список разрешённых расширений через запятую (.pdf, *.jpg) или шаблонов MIME (image/*)
filesize number Нет Максимальный размер для поля в МБ. Может только уменьшить предел 64 МБ.

Ответ

{"data": [{"filename": "hero.jpg", "path": "blog", "url": "/user/media/blog/hero.jpg", "type": "image/jpeg", "size": 184320, "dimensions": {"width": 1600, "height": 900}, "thumbnail_url": "/api/v1/thumbnails/3f2a9c1e4b5d6a7f8e9d0c1b2a394857.jpg", "modified": "2026-09-01T10:15:00+00:00"}]}

Коды ответов

Код Описание
201 Файлы успешно загружены
401 Не авторизован
403 Нет разрешения api.media.write
422 Ошибка валидации (нет файла, неверный путь, имя или тип файла, либо файл слишком большой)

Загружает один или несколько файлов в директорию user/media. Используйте параметр запроса path, чтобы загрузить в подпапку. Тело запроса должно быть в формате multipart/form-data с полем file. Максимальный размер загрузки на файл — 64 МБ.

Ответ перечисляет только файлы, сохранённые этим запросом. У файла должно быть расширение, и ни одна разделённая точками часть его имени не должна входить в security.uploads_dangerous_extensions. Содержимое SVG санируется при поступлении. Без avoid_overwriting файл с тем же именем заменяется. Ошибка 422 останавливает запрос на этом файле, а ранее сохранённые файлы остаются.


Удаление медиафайла сайта

DELETE /media/{filename}

Удаляет медиафайл уровня сайта.

Параметры

Имя Тип Обязательный Описание
filename string Да Имя удаляемого медиафайла. Может содержать путь подпапки (например, blog/hero.jpg).

Коды ответов

Код Описание
204 Файл удалён
401 Не авторизован
403 Нет разрешения api.media.write
404 Файл не найден
422 Неверное имя файла (сегмент пути пуст, начинается с точки или равен ..)

Удаляет файл и его сопутствующий файл .meta.yaml (если есть) из директории user/media и исключает его из ручного порядка папки. Параметр filename поддерживает пути подпапок.


Создание папки медиафайлов

POST /media/folders

Создаёт новую папку в директории медиафайлов уровня сайта.

Запрос

{
  "path": "blog/2026"
}

Ответ

{"data": {"name": "2026", "path": "blog/2026", "children_count": 0, "file_count": 0}}

Коды ответов

Код Описание
201 Папка создана
401 Не авторизован
403 Нет разрешения api.media.write
422 Ошибка валидации или папка уже существует

Создаёт новую папку в user/media. Родительские папки создаются автоматически. Тело запроса должно содержать свойство path с относительным путём создаваемой папки. Ни один сегмент пути не может начинаться с точки или быть ... Заголовок Location указывает на список содержимого новой папки (/media?path=...).


Удаление папки медиафайлов

DELETE /media/folders/{path}

Удаляет пустую папку из папки медиафайлов уровня сайта.

Параметры

Имя Тип Обязательный Описание
path string Да Путь папки относительно корня медиафайлов

Коды ответов

Код Описание
204 Папка удалена
401 Не авторизован
403 Нет разрешения api.media.write
404 Папка не найдена
422 Папка не пуста или путь неверен

Удаляет пустую папку из директории user/media. В папке не должно быть файлов и подпапок, включая скрытые файлы, сопутствующие файлы .meta.yaml и файл порядка media_order.yaml.


Переименование медиафайла сайта

POST /media/rename

Переименовывает или перемещает файл в директории медиафайлов уровня сайта.

Запрос

{
  "from": "blog/hero.jpg",
  "to": "blog/banner.jpg"
}

Ответ

{"data": {"filename": "banner.jpg", "path": "blog", "url": "/user/media/blog/banner.jpg", "type": "image/jpeg", "size": 184320, "dimensions": {"width": 1600, "height": 900}, "thumbnail_url": "/api/v1/thumbnails/3f2a9c1e4b5d6a7f8e9d0c1b2a394857.jpg", "modified": "2026-09-01T10:15:00+00:00"}}

Коды ответов

Код Описание
200 Файл переименован
401 Не авторизован
403 Нет разрешения api.media.write
404 Исходный файл не найден
422 Ошибка валидации или место назначения уже занято

Переименовывает файл или перемещает его в другую папку внутри user/media. from и to — относительные пути. Целевая папка при необходимости создаётся автоматически. Сопутствующий файл .meta.yaml тоже перемещается, а ручной порядок папок сохраняется согласованным. Ответ — файл на новом месте.

Новое имя очищается перед использованием: пробелы заменяются дефисом, символы, кроме букв, цифр, ., _ и -, удаляются, а расширение исходного файла сохраняется всегда (любое расширение, указанное в to, заменяется). Так, {"from": "hero.jpg", "to": "My Banner.png"} даёт My-Banner.jpg. Если очищенное имя совпадает с исходным, ничего не меняется и файл возвращается как есть. Очищенное имя, в котором не осталось букв и цифр, возвращает 422.


Переименование папки медиафайлов

POST /media/folders/rename

Переименовывает папку в директории медиафайлов уровня сайта.

Запрос

{
  "from": "blog/old-name",
  "to": "blog/new-name"
}

Ответ

{"data": {"name": "new-name", "path": "blog/new-name", "children_count": 2, "file_count": 14}}

Коды ответов

Код Описание
200 Папка переименована
401 Не авторизован
403 Нет разрешения api.media.write
404 Исходная папка не найдена
422 Ошибка валидации или место назначения уже занято

Переименовывает папку внутри user/media. Всё содержимое папки сохраняется. from и to — относительные пути от корня медиафайлов.

Ответ содержит реальные значения children_count (подпапки) и file_count (медиафайлы, без учёта сопутствующих файлов и файла порядка) переименованной папки — те же счётчики, что сообщает список содержимого папки, поэтому клиент может обновить запись, не запрашивая список заново.


Отдача миниатюры

GET /thumbnails/{file}

Отдаёт кэшированную миниатюру изображения, созданную службой миниатюр API. Этот эндпоинт публичный и не требует аутентификации. Имена файлов миниатюр — это хеши, создаваемые при сериализации медиафайлов; Admin2 использует URL, встроенные в ответы с медиафайлами (thumbnail_url или avatar_url пользователя), а не запрашивает миниатюры по пути. Ответы приходят с Cache-Control: public, max-age=31536000, immutable, поэтому их можно безопасно кэшировать на год.

Параметры

Имя Тип Обязательный Описание
file string Да Имя файла миниатюры (только базовое имя).

Коды ответов

Код Описание
200 Миниатюра отдана.
404 Миниатюра не найдена в кэше.

Миниатюры хранятся в cache://api/thumbnails/. Они создаются при сериализации изображения в ответе с медиафайлами и никогда — этим эндпоинтом, поэтому ещё не кэшированная миниатюра (например, после очистки кэша) возвращает 404, пока список медиафайлов, содержащий её, не будет запрошен снова.


Получение метаданных медиафайла страницы

GET /pages/{route}/media/{filename}/meta

Читает редактируемые метаданные медиафайла страницы, хранящиеся в его сопутствующем файле .meta.yaml.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
filename string Да Имя медиафайла

Ответ

{"data": {"filename": "photo.jpg", "has_meta": true, "fields": [{"key": "alt", "label": "Alt Text", "type": "text", "value": "Sunset over the bay"}, {"key": "title", "label": "Title", "type": "text", "value": ""}, {"key": "caption", "label": "Caption", "type": "textarea", "value": ""}, {"key": "description", "label": "Description", "type": "textarea", "value": ""}, {"key": "tags", "label": "Tags", "type": "tags", "value": ["beach", "summer"]}], "extra": {"width": 1920, "height": 1080}}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.media.read или правила самой страницы запрещают чтение
404 Страница или файл не найдены
422 Неверное имя файла (начинается с точки или содержит ..)

Возвращает по одной записи в fields для каждого редактируемого поля, настроенного в разделе Плагины → API → Метаданные медиафайлов (plugins.api.media_metadata.fields), с текущим значением. Если ничего не настроено, по умолчанию используются alt, title, caption, description и tags. Значение поля text или textarea — строка (пустая, если не задано), а значение поля tags — список строк.

Любые другие ключи, хранящиеся в сопутствующем файле (данные EXIF, размеры, сведения о загрузке), возвращаются как данные только для чтения в extra. has_meta сообщает, существует ли сопутствующий файл вообще.


Обновление метаданных медиафайла страницы

PATCH /pages/{route}/media/{filename}/meta

Сохраняет редактируемые метаданные медиафайла страницы.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
filename string Да Имя медиафайла

Запрос

{
  "fields": {
    "alt": "Sunset over the bay",
    "tags": ["beach", "summer"]
  }
}

Ответ

{"data": {"filename": "photo.jpg", "has_meta": true, "fields": [{"key": "alt", "label": "Alt Text", "type": "text", "value": "Sunset over the bay"}, {"key": "title", "label": "Title", "type": "text", "value": ""}, {"key": "caption", "label": "Caption", "type": "textarea", "value": ""}, {"key": "description", "label": "Description", "type": "textarea", "value": ""}, {"key": "tags", "label": "Tags", "type": "tags", "value": ["beach", "summer"]}], "extra": {"width": 1920, "height": 1080}}}

Коды ответов

Код Описание
200 Метаданные сохранены
401 Не авторизован
403 Нет разрешения api.media.write или правила самой страницы запрещают обновление
404 Страница или файл не найдены
422 Неверное имя файла или значение, не являющееся простым текстом

Передавайте значения в объекте fields или в виде простого отображения ключей полей на значения. Меняются только настроенные поля, присутствующие в запросе, а пустое значение (пустая строка или пустой список для поля tags) удаляет это поле. Ключи, которые не настроены, игнорируются, а все остальные ключи, уже имеющиеся в сопутствующем файле, сохраняются. Ответ — обновлённые метаданные в том же формате, что и в разделе Получение метаданных медиафайла страницы.

Значения выводятся в атрибуты <img> на сайте, поэтому они очищаются при сохранении: HTML-теги и управляющие символы удаляются, пробелы в однострочных полях схлопываются, а каждое значение обрезается до plugins.api.media_metadata.max_length символов (по умолчанию 2000). Значение tags может быть списком строк или одной строкой через запятую; дубликаты и пустые значения отбрасываются, сохраняется не более 50 тегов. Зарезервированные ключи, которыми управляет сам Grav (width, height, mime, size, filesize, modified, upload, type), здесь записать нельзя.

Если удалены все ключи, сопутствующий файл удаляется.


Удаление метаданных медиафайла страницы

DELETE /pages/{route}/media/{filename}/meta

Очищает редактируемые метаданные медиафайла страницы.

Параметры

Имя Тип Обязательный Описание
route string Да Маршрут страницы
filename string Да Имя медиафайла

Коды ответов

Код Описание
204 Метаданные очищены
401 Не авторизован
403 Нет разрешения api.media.write или правила самой страницы запрещают обновление
404 Страница или файл не найдены
422 Неверное имя файла (начинается с точки или содержит ..)

Удаляет все настроенные поля метаданных из сопутствующего файла .meta.yaml этого файла. Другие ключи, например данные EXIF или размеры, сохраняются, а сопутствующий файл удаляется только тогда, когда в нём больше ничего не остаётся. Сам медиафайл не затрагивается.


Отдача исходного медиафайла сайта

GET /media/raw/{path}

Передаёт байты медиафайла уровня сайта, который веб-сервер не отдаёт напрямую.

Параметры

Имя Тип Обязательный Описание
path string Да Путь файла относительно корня медиафайлов. Может содержать / (например, photos/beach.jpg).

Коды ответов

Код Описание
200 Байты файла с определённым типом MIME в Content-Type
401 Не авторизован
403 Нет разрешения api.media.read
404 Файл не найден или не является отдаваемым типом медиафайла
422 Неверный путь (сегмент начинается с точки или равен ..)

Списки медиафайлов обычно дают каждому файлу прямой статический URL. Когда папка медиафайлов сайта находится там, откуда веб-сервер отказывается отдавать файлы, например в папке user/env/<host>/media при мультисайте (поставляемые с Grav конфигурации .htaccess и nginx запрещают user/env, user/config и user/accounts), url в списке указывает сюда.

Отдаются только изображения, видео, аудио, шрифты и PDF. Любой другой тип файла возвращает 404, поэтому этот маршрут нельзя использовать для чтения исходных файлов или файлов конфигурации. Ответ отправляется с inline, Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; sandbox и X-Content-Type-Options: nosniff, поэтому загруженный SVG не может выполнить скрипт при прямом открытии, а также с Cache-Control: private, max-age=600.

Поскольку элемент <img> в браузере не может отправить заголовок аутентификации, этот маршрут принимает cookie сессии самого сайта, а также JWT, переданный параметром запроса ?token=.


Получение метаданных медиафайла сайта

GET /media/meta

Читает редактируемые метаданные медиафайла уровня сайта, хранящиеся в его сопутствующем файле .meta.yaml.

Параметры

Имя Тип Обязательный Описание
path string Да Параметр запроса: путь файла относительно корня медиафайлов (например, blog/hero.jpg)

Ответ

{"data": {"filename": "hero.jpg", "has_meta": true, "fields": [{"key": "alt", "label": "Alt Text", "type": "text", "value": "Sunset over the bay"}, {"key": "title", "label": "Title", "type": "text", "value": ""}, {"key": "caption", "label": "Caption", "type": "textarea", "value": ""}, {"key": "description", "label": "Description", "type": "textarea", "value": ""}, {"key": "tags", "label": "Tags", "type": "tags", "value": ["beach", "summer"]}], "extra": {"width": 1920, "height": 1080}}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.media.read
404 Файл не найден
422 path отсутствует или неверен

Файл адресуется параметром запроса path, а не в URL, потому что пути медиафайлов сайта содержат косые черты. Ответ такой же, как в разделе Получение метаданных медиафайла страницы: по одной записи на каждое настроенное поле в fields, другие ключи сопутствующего файла в extra, а has_meta сообщает, существует ли сопутствующий файл. filename — базовое имя файла.


Обновление метаданных медиафайла сайта

PATCH /media/meta

Сохраняет редактируемые метаданные медиафайла уровня сайта.

Параметры

Имя Тип Обязательный Описание
path string Да Параметр запроса: путь файла относительно корня медиафайлов (например, blog/hero.jpg)

Запрос

{
  "fields": {
    "alt": "Sunset over the bay",
    "tags": ["beach", "summer"]
  }
}

Ответ

{"data": {"filename": "hero.jpg", "has_meta": true, "fields": [{"key": "alt", "label": "Alt Text", "type": "text", "value": "Sunset over the bay"}, {"key": "title", "label": "Title", "type": "text", "value": ""}, {"key": "caption", "label": "Caption", "type": "textarea", "value": ""}, {"key": "description", "label": "Description", "type": "textarea", "value": ""}, {"key": "tags", "label": "Tags", "type": "tags", "value": ["beach", "summer"]}], "extra": {"width": 1920, "height": 1080}}}

Коды ответов

Код Описание
200 Метаданные сохранены
401 Не авторизован
403 Нет разрешения api.media.write
404 Файл не найден
422 path отсутствует или неверен, либо значение не является простым текстом

Работает так же, как Обновление метаданных медиафайла страницы: меняются только настроенные поля, присутствующие в запросе, пустое значение удаляет поле, другие ключи сопутствующего файла сохраняются, а значения очищаются при сохранении. Ответ — обновлённые метаданные. Чтобы применить одинаковые значения к нескольким файлам за один запрос, используйте Пакетное обновление метаданных медиафайлов сайта.


Удаление метаданных медиафайла сайта

DELETE /media/meta

Очищает редактируемые метаданные медиафайла уровня сайта.

Параметры

Имя Тип Обязательный Описание
path string Да Параметр запроса: путь файла относительно корня медиафайлов (например, blog/hero.jpg)

Коды ответов

Код Описание
204 Метаданные очищены
401 Не авторизован
403 Нет разрешения api.media.write
404 Файл не найден
422 path отсутствует или неверен

Удаляет все настроенные поля метаданных из сопутствующего файла .meta.yaml этого файла. Другие ключи сохраняются, а сопутствующий файл удаляется только тогда, когда в нём больше ничего не остаётся. Сам медиафайл не затрагивается.


Пакетное обновление метаданных медиафайлов сайта

POST /media/batch/meta

Применяет одинаковые поля метаданных к нескольким медиафайлам уровня сайта сразу.

Запрос

{
  "files": ["photos/beach.jpg", "photos/dunes.jpg"],
  "fields": {
    "tags": ["beach", "summer"]
  }
}

Ответ

{"data": {"results": [{"path": "photos/beach.jpg", "status": "success"}, {"path": "photos/missing.jpg", "status": "error", "message": "Media file not found."}], "total": 2, "successful": 1, "failed": 1}}

Коды ответов

Код Описание
200 Результаты по каждому файлу (проверяйте каждый status)
401 Не авторизован
403 Нет разрешения api.media.write
422 Отсутствует files или fields, files пуст или не является списком, fields не является объектом, либо слишком много файлов

files перечисляет пути относительно корня медиафайлов, а fields сопоставляет ключи полей метаданных значениям. В каждый файл записываются только настроенные поля, присутствующие в fields, поэтому пакет, задающий только tags, не трогает собственные alt и title каждого файла. Пустое значение (пустая строка или пустой список для поля tags) удаляет это поле. Значения очищаются так же, как в разделе Обновление метаданных медиафайла сайта.

Каждый файл обрабатывается отдельно: неверный путь или отсутствующий файл попадает в results со status: error и message, а остальная часть пакета всё равно выполняется. Число файлов ограничено plugins.api.batch.max_items (по умолчанию 50).


Задание порядка медиафайлов

POST /media/order

Сохраняет ручной порядок файлов в директории медиафайлов уровня сайта.

Запрос

{
  "path": "photos",
  "order": ["dunes.jpg", "beach.jpg", "sunset.jpg"]
}

Коды ответов

Код Описание
204 Порядок сохранён
401 Не авторизован
403 Нет разрешения api.media.write
404 Папка не найдена
422 Отсутствует массив order или неверен path

path — папка относительно корня медиафайлов; не указывайте его для корневой папки. order перечисляет имена файлов в нужном порядке. Записи сокращаются до базовых имён файлов, пустые значения отбрасываются. Пустой order удаляет сохранённый порядок.

Порядок хранится в файле media_order.yaml внутри папки, и Список медиафайлов сайта применяет его при выводе содержимого этой папки. Файлы, которых нет в сохранённом порядке (например, новые загрузки), идут после упорядоченных. Сам файл порядка никогда не появляется в списках и результатах поиска и поддерживается в актуальном состоянии при удалении, переименовании или перемещении файла.


Загрузка файла для схемы

POST /blueprint-upload

Загружает файл для поля схемы с type: file (логотип темы, ресурс плагина, аватар) и сохраняет его в папку, указанную в destination этого поля.

Параметры

Имя Тип Обязательный Описание
file file Да Загружаемый файл (multipart/form-data). Подходит любое имя поля, и в одном запросе можно отправить несколько файлов.
destination string Да Значение destination поля схемы: поток Grav (theme://images/logo, user://media), токен self@:subpath, разрешаемый относительно scope, или обычный путь относительно user/
scope string Нет Владелец схемы, используемый для разрешения адресов self@:: plugins/<slug>, themes/<slug>, pages/<route> или users/<username>
field string Нет Полное имя поля схемы, к которому относится загрузка (custom_css, header.stylesheet). Вместе со scope сервер находит allow_extensions поля в самой схеме.
random_name boolean Нет Заменить имя файла случайным, сохранив расширение (по умолчанию: false)
avoid_overwriting boolean Нет Добавить префикс с отметкой времени вместо замены существующего файла с тем же именем (по умолчанию: false)
accept string Нет Список разрешённых расширений через запятую (.pdf, *.jpg) или шаблонов MIME (image/*)
filesize number Нет Максимальный размер для поля в МБ. Может только уменьшить предел 64 МБ.

Ответ

{"data": [{"name": "logo.png", "path": "user/themes/quark/images/logo/logo.png", "size": 20480, "type": "image/png", "url": "https://example.com/user/themes/quark/images/logo/logo.png"}]}

Коды ответов

Код Описание
201 Файлы сохранены
401 Не авторизован
403 Нет разрешения api.media.write, цель находится в user/config/ или user/env/*/config/, либо используется область users/<username> другого аккаунта без api.users.write
422 Отсутствует destination, нет файла, небезопасный путь или отклонённые имя, тип либо размер файла

Это повторяет taskFilesUpload классической админки и используется Admin2 для полей схем с типом «файл», у которых задан destination. Отправляйте как multipart/form-data. Абсолютные пути и сегменты .. в destination отклоняются.

Ответ перечисляет каждый сохранённый файл. path — логический путь под user/, построенный из destination и scope, а не разрешённый путь на диске, поэтому он работает и через символически связанные папки тем или плагинов. Передайте его в Удаление файла схемы, чтобы удалить файл.

Правила для файлов:

  • Размер каждого файла ограничен 64 МБ, а собственный filesize поля может только уменьшить этот предел.
  • Ни одна разделённая точками часть имени не должна входить в security.uploads_dangerous_extensions, поэтому shell.php.jpg отклоняется.
  • Файлы конфигурации и данных (yaml, yml, json, twig, env, neon, lock) отклоняются везде, куда бы они ни попали. Содержимое страниц (md, markdown) и таблицы стилей (css, scss, sass, less) тоже отклоняются, если только поле, указанное в field, не разрешает их через allow_extensions в схеме, которой принадлежит scope, и загрузка идёт в собственный destination этого поля.
  • Загрузки в user/accounts/ могут быть только изображениями (jpg, jpeg, png, gif, webp, svg, avif, bmp, ico), так как Grav читает эту папку как хранилище учётных записей.
  • Загрузки, которые попадают в user/config/ или user/env/*/config/, отклоняются с кодом 403.
  • Файлы SVG санируются после сохранения.

Для адреса self@: с областью users/<username> вашего собственного аккаунта нужно только api.media.write. Для другого аккаунта дополнительно нужно api.users.write (или права суперпользователя).


Удаление файла схемы

DELETE /blueprint-upload

Удаляет файл, сохранённый полем схемы с типом «файл», а также его сопутствующий файл .meta.yaml, если он есть.

Параметры

Имя Тип Обязательный Описание
path string Да Логический путь файла относительно папки user (префикс user/ необязателен)
scope string Нет Владелец схемы поля: plugins/<slug>, themes/<slug>, pages/<route> или users/<username>. Нужен только вместе с field.
field string Нет Полное имя поля схемы, которому принадлежит файл. Вместе со scope позволяет allow_extensions поля разрешить удаление собственных файлов.

Запрос

{
  "path": "user/themes/quark/images/logo/logo.png"
}

Коды ответов

Код Описание
204 Файл удалён или уже отсутствовал
401 Не авторизован
403 Нет разрешения api.media.write, цель находится в user/config/ или user/env/*/config/, файл в user/accounts/ не является изображением, либо это файл другого аккаунта без api.users.write
422 Отсутствует path, в нём есть обход пути или нулевые байты, отклонён тип файла, либо цель не является обычным файлом

path — логический путь, который вернула загрузка, относительно папки user; префикс user/ необязателен. .. и нулевые байты отклоняются.

Действуют те же правила расширений, что и в разделе Загрузка файла для схемы, поэтому через этот эндпоинт нельзя удалить файлы конфигурации, а также содержимое страниц (.md, .markdown) и таблицы стилей (.css, .scss, .sass, .less), если только field и scope не указывают поле, схема которого разрешает их через allow_extensions, и файл находится в собственной папке этого поля. В user/accounts/ можно удалять только файлы изображений, а без api.users.write (или прав суперпользователя) — только собственный аватар, то есть файл, на который указывает поле avatar вашего аккаунта.

Вызов идемпотентен: файл, которого больше нет, возвращает 204.