Фотографии и документы акта
Все операции. Авторизация. Запросы и повторы.
Все пути в этом файле дополняют /api/v1 на домене организации.
Описание и ограничения
Поля и коллекция
| Публичное поле | Формат и доступ |
|---|---|
id |
целое, только чтение |
act_id |
целое, только чтение; задаётся путём |
kind |
attachment, входное поле/только чтение |
filename |
безопасное имя без пути, только чтение |
mime_type |
проверенный MIME, только чтение |
size |
целое число байтов, только чтение |
created_at |
ISO 8601 с поясом, только чтение |
version |
непрозрачная строка, только чтение |
download_url |
относительный путь на том же домене организации, только чтение |
file |
ровно один файл, входное поле |
client_filename |
необязательное имя файла, входное поле |
kind=attachment используется для фотографий и документов акта. Подпись согласования не входит в этот ресурс: её нельзя загрузить, скачать или удалить через эти методы. Допустимые поля загрузки перечислены ниже.
Доступ и выборка
Нужны act_media:read для чтения и act_media:write для записи, доступ к акту и права «Акты приёма оборудования → Просмотр» или «Акты приёма оборудования → Изменение» соответственно. Загрузка также требует «Системные настройки → Загрузка вложений». Действуют общие ограничения тарифа, мастерских и типа акта. Доступ проверяется при чтении списка, карточки, скачивании, просмотре журнала и повторе запроса. Недоступный или чужой идентификатор файла возвращает 404.
Список использует общую пагинацию по курсору, sort=id/-id. Допустим только filter[kind]=attachment; других фильтров и updated_since нет. Каждый элемент содержит version, а GET JSON-карточки дополнительно возвращает отдельный ETag этого представления без скачивания файла.
show_images и show_documents управляют показом в клиентском портале. Они не заменяют авторизацию интеграции и не включаются загрузкой. Если показ в портале уже включён, новый файл попадает под существующие правила видимости акта. API не создаёт клиентскую ссылку для доступа без авторизации и не меняет согласования.
Загрузка
Content-Type — multipart/form-data с корректным boundary. Обязательны file и текстовый kind=attachment; client_filename необязателен. Если его нет, используется имя файла без пути имени части file. Итоговое имя должно быть непустым, не длиннее 255 символов, без управляющих символов и разделителей пути. Указанное явно client_filename с путём отклоняется. Имя используется для скачивания; ключ хранения назначает сервер.
Разрешены следующие MIME из существующей формы акта:
| Категория | MIME |
|---|---|
| Изображения | image/jpeg, image/png, image/gif, image/webp |
| PDF и текст | application/pdf, text/plain |
| Word | application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| Excel | application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| PowerPoint | application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation |
| Архивы | application/zip, application/x-rar-compressed, application/x-7z-compressed |
Тип определяется по содержимому и формату файла, включая документы Office. Одного расширения или присланного MIME недостаточно. Неподдерживаемый или несогласованный формат возвращает 422 FILE_TYPE_NOT_ALLOWED. Архив сохраняется без распаковки. SVG, HTML и исполняемые файлы не принимаются. Ссылка, строка base64, локальный путь или идентификатор другого файла не заменяют поле file.
Успех — 201 с JSON-карточкой и её data.version, meta.operation_id, meta.affected_resources и meta.warnings=[], без ETag. affected_resources содержит созданный act-media и изменённый acts: изменение состава вложений обновляет updated_at акта; при совпавшей секунде version может остаться прежней. Если готовность файла требует фонового восстановления, возвращается 202 по общему контракту; 201 означает, что метаданные и содержимое доступны.
{
"data": {
"id": 81,
"act_id": 301,
"kind": "attachment",
"filename": "Фото устройства.jpg",
"mime_type": "image/jpeg",
"size": 245760,
"created_at": "2026-10-30T09:00:00.000000Z",
"version": "1793782800",
"download_url": "/api/v1/acts/301/media/81/download"
},
"meta": {
"operation_id": "op-example-upload-81",
"affected_resources": [
{"type": "act-media", "id": 81, "version": "1793782800", "deleted": false},
{"type": "acts", "id": 301, "version": "1793782800", "deleted": false}
],
"warnings": []
}
}
Location у POST указывает на журнал операции по общим правилам; путь к карточке файла собирается по методу ресурса. GET карточки возвращает актуальные data и отдельный ETag представления, без operation_id принятого POST. Все ответы, включая ошибки, получают собственный X-Request-Id только в заголовке.
Скачивание и удаление
Скачивание возвращает содержимое файла с кодом 200 с проверенным Content-Type, безопасным Content-Disposition: attachment, Cache-Control: private, no-store, X-Content-Type-Options: nosniff и X-Request-Id. У бинарного успеха нет JSON-обёртки. Версию для удаления берут из data.version JSON-метаданных, не из содержимого и не из ETag. Ошибки до начала передачи имеют общий JSON-формат. Авторизация обязательна при каждом скачивании; download_url не является публичной или подписанной ссылкой для доступа без авторизации на диск. Отозванный токен не получает файл по старому URL.
Удаление принимает только {} и If-Resource-Version файла. Успех — 200, data={"id":81,"deleted":true}, operation_id и affected_resources: у act-media deleted=true, version=null; у акта новая version. Новая команда для уже отсутствующего ID получает 404, а повтор принятого удаления возвращает исходную запись об операции при сохранении текущих прав на её контекст.
Идемпотентность и восстановление
При повторе сохраняйте метод, путь, kind, итоговый client_filename, содержимое файла и условия проверки версии. Разделитель частей запроса не влияет на сравнение. Другой файл, имя или родитель с ключом уже принятой операции возвращает 409 IDEMPOTENCY_CONFLICT.
Сервер восстанавливает незавершённую загрузку после сбоя в рамках той же операции. Успешный ответ выдаётся только после готовности файла. После принятого удаления файл недоступен через API, даже если его физическое удаление ещё продолжается.
Если завершить загрузку не удалось и требуется проверка результата, операция получает состояние needs_reconciliation. Повтор с прежним ключом не создаёт другой файл. Дальнейшее состояние проверяйте в журнале операций.
Создание и удаление вложения записывают act_media.created/act_media.deleted и act.updated согласованно с итогом операции. До готовности файла событие создания не публикуется. В конверт входят только ID, секундная версия и признак удаления; для проверки текущего доступа сохраняется явная ссылка на родительский акт. Повтор запроса не создаёт новые события.
Повтор запроса не пишет второй файл и не пересоздаёт удалённое позднее вложение. Старый If-Resource-Version принятого удаления не проверяется заново до поиска записи об операции; права проверяются всегда. Неизвестный исход приводит к сверке операции, а не к повторной загрузке под новым ключом. Истечение срока хранения тела ответа не освобождает ключ.
Операции
| Метод | Путь | Назначение |
|---|---|---|
| GET | /acts/{act_id}/media |
Список метаданных файлов акта |
| POST | /acts/{act_id}/media |
Добавление одного файла, multipart/form-data |
| GET | /acts/{act_id}/media/{id} |
JSON-карточка файла с version и сильным ETag |
| GET | /acts/{act_id}/media/{id}/download |
Защищённое скачивание содержимого |
| POST | /acts/{act_id}/media/{id}/delete |
Удаление файла, JSON {} |
GET /acts/{act_id}/media
Метаданные вложений акта; подпись согласования не входит в ресурс.
Доступ. Разрешения подключения: act_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
act_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
filter[kind] |
параметр запроса | строка | нет | нет | Допустимо: "attachment" |
sort |
параметр запроса | строка | нет | нет | Допустимо: "id", "-id" |
page[size] |
параметр запроса | целое число | нет | нет | ≥ 1; ≤ 100 |
page[cursor] |
параметр запроса | строка | нет | нет | не более 8192 символов |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff \
"$API/acts/101/media" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
POST /acts/{act_id}/media
Добавить ровно одно вложение. Случайный multipart разделитель частей не меняет fingerprint.
Доступ. Разрешения подключения: act_media:write. Права сотрудника: «Акты приёма оборудования → Изменение», «Системные настройки → Загрузка вложений». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
act_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
Тело запроса
Content-Type: multipart/form-data. Тело обязательно.
| Поле | Тип | Обязательно | null | Ограничения и смысл |
|---|---|---|---|---|
kind |
строка | да | нет | Допустимо: "attachment" |
file |
строка (двоичные данные) | да | нет | Файл от 1 до 10 МиБ включительно; MIME проверяется по содержимому. |
client_filename |
строка | нет | нет | не более 255 символов |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 201 | Создано. Полная схема и пример |
| 202 | Принято, итог в журнале. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 413 | Превышен размер. Коды и формат ошибки |
| 415 | Неподдерживаемый Content-Type. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 201 | Location |
строка | |
| 202 | Location |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff --request POST \
"$API/acts/101/media" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-act-media-store:001" \
--form 'kind=attachment' \
--form 'file=@./examples/attachment.txt;type=text/plain'
GET /acts/{act_id}/media/{id}
Карточка файла с самостоятельной секундной версией и ETag представления.
Доступ. Разрешения подключения: act_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
act_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
If-None-Match |
заголовок | строка | нет | нет | — |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 304 | Представление не изменилось, без тела. Условный GET |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | ETag |
строка | |
| 304 | ETag |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff \
"$API/acts/101/media/101" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
GET /acts/{act_id}/media/{id}/download
Защищённое скачивание. В Range не поддерживается.
Доступ. Разрешения подключения: act_media:read. Права сотрудника: «Акты приёма оборудования → Просмотр». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
act_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Бинарный файл без JSON-обёртки; вложения |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | Content-Disposition |
строка | |
| 200 | X-Content-Type-Options |
строка | |
| 200 | Cache-Control |
строка | |
| 401 | Cache-Control |
строка | |
| 403 | Cache-Control |
строка | |
| 404 | Cache-Control |
строка | |
| 422 | Cache-Control |
строка | |
| 429 | Cache-Control |
строка | |
| 503 | Cache-Control |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff \
"$API/acts/101/media/101/download" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json"
POST /acts/{act_id}/media/{id}/delete
Удаление проверяет версию метаданных файла, а не версию акта.
Доступ. Разрешения подключения: act_media:write. Права сотрудника: «Акты приёма оборудования → Изменение». Дополнительно действуют доступ к записям, мастерским, модулям и условия полей из описания ресурса выше.
Параметры
| Имя | Где | Тип | Обязательно | null | Ограничения |
|---|---|---|---|---|---|
Authorization |
заголовок | строка | да | нет | Bearer <SERVICEAPP_TOKEN> |
act_id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
id |
путь | строка | да | нет | Шаблон: ^(?:[0-9]+)$ |
Idempotency-Key |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._:-]+$ |
If-Resource-Version |
заголовок | строка | да | нет | не менее 1 символов; не более 128 символов; Шаблон: ^[A-Za-z0-9._~-]+$ |
Тело запроса
Content-Type: application/json. Тело обязательно.
Тело — пустой JSON-объект {}. Другие ключи не принимаются.
Ответы
| HTTP | Назначение и схема |
|---|---|
| 200 | Успех. Полная схема и пример |
| 401 | Требуется действующий Bearer. Коды и формат ошибки |
| 403 | Недостаточно допуска. Коды и формат ошибки |
| 404 | Не найдено или недоступно. Коды и формат ошибки |
| 409 | Конфликт состояния или повтора. Коды и формат ошибки |
| 412 | Версия устарела. Коды и формат ошибки |
| 422 | Ошибка входных данных. Коды и формат ошибки |
| 428 | Нужно предусловие версии. Коды и формат ошибки |
| 429 | Лимит запросов, Retry-After. Коды и формат ошибки |
| 503 | Временно недоступно. Коды и формат ошибки |
| HTTP | Заголовок ответа | Тип | Описание |
|---|---|---|---|
| 200 | Location |
строка |
Каждый ответ содержит новый X-Request-Id в заголовке. Общие транспортные отказы и правила повтора действуют также при отказе до контроллера; см. ошибки.
У принятого POST Location и meta.operation_id указывают на журнал операции; ETag отсутствует. При повторе запроса сохраняются исходные data/meta, добавляется Idempotency-Replayed: true. Версии передавайте по назначению, указанному в описании ресурса.
Пример запроса
Запускается из каталога комплекта после настройки переменных в быстром старте. Замените демонстрационные идентификаторы 101 и UUID идентификаторами доступных записей. $RESOURCE_VERSION берётся из GET владельца версии, описанного выше. Для нового действия сохраните новый ключ; для повтора используйте прежний.
curl --silent --show-error --globoff --request POST \
"$API/acts/101/media/101/delete" \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header "Accept: application/json" \
--header "Idempotency-Key: example:v1-act-media-destroy:001" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--header "Content-Type: application/json" \
--data-binary '@examples/requests/v1.act-media.destroy.json'