Работа с файлами
Файлы в HRlink загружаются отдельно от документов и заявлений. После загрузки API возвращает fileId, который клиент передаёт в методы создания документов, заявлений или других объектов.
Что получится в конце
Интеграция сможет загрузить файл, сохранить fileId, передать его в документ или заявление и скачать файл обратно по fileId или одноразовому токену.
Когда использовать
Используйте эту страницу, когда интеграция загружает файлы в HRlink, скачивает архивы или разбирает ошибки multipart/form-data.
Что нужно заранее
| Что нужно | Где получить |
|---|---|
tenantHost | Адрес тенантаTenant Экземпляр системы HRlink на отдельном домене (например, company.hr-link.ru). Внутри одного тенанта может быть несколько пространств клиентов. HRlink |
| Токен | Аутентификация |
| Файл | На стороне интеграции |
documentId или applicationId для архива | Из сценария работы с документом или заявлением |
Какие методы используются
| Сценарий | Метод |
|---|---|
| Загрузить файл | Загрузить файл |
| Скачать файл по токену | Скачать файл по токену |
| Скачать публичный файл | Скачать публичный файл |
| Скачать большой одноразовый файл | Скачать одноразовый большой файл по токену |
Типовые сценарии
Загрузить файл
- Подготовьте
multipart/form-dataзапрос. - Вызовите Загрузить файл.
- Сохраните
idиз ответа и передайте его какfileIdв следующем запросе.
Скачать файл по одноразовому токену
- Запросите архив документа или заявления.
- Возьмите ссылку из заголовка
Location. - Вызовите Скачать файл по токену до истечения 5 минут.
Скачать файл по fileId
- Возьмите
fileIdиз объекта документа, заявления или ответа загрузки. - Вызовите Скачать публичный файл.
Ограничения и ошибки
- Файлы передаются только через
multipart/form-data, не через JSON или base64. - Максимальный размер файла — 100 МБ.
- У файлов нет
externalId, поэтому интеграция должна хранитьfileId. - Одноразовый токен скачивания действует 5 минут и срабатывает один раз.
- Последний boundary в
multipart/form-dataдолжен заканчиваться на--.
Загрузка файлов
Endpoint
POST /api/v1/files
Content-Type: multipart/form-data
Подробная спецификация: Загрузить файл.
Правила загрузки
- Формат: только
multipart/form-data(не raw JSON!) - Максимальный размер файла — 100 МБ (см. Ограничения)
- Поле файла может иметь любое имя (например,
file,image,document) - В одном запросе передавайте несколько файлов — давайте полям разные имена, чтобы сопоставить возвращённые идентификаторы с конкретными файлами
- Один загруженный файл используйте для нескольких документов — передавайте один и тот же
idфайла в разные вызовы создания документов
Запрещённые форматы
Сервер блокирует загрузку файлов с опасными расширениями.
Полный список запрещённых расширений
.exe, .com, .msi, .bat, .cmd, .sh, .bash, .py, .pl, .rb, .vbs, .js, .wsf, .php, .jar, .class, .dll, .sys, .bin, .run, .app, .apk, .ps1, .html, .htm, .mhtml, .mht, .shtml, .cpl, .msh, .scpt, .pyc, .psm1, .ksh, .zsh, .csh, .deb, .rpm, .dmg, .pkg, .iso, .htaccess, .desktop, .lnk
Все остальные форматы допустимы. Сервер проверяет последние два расширения в имени файла — например, отклонит document.pdf.exe.
Загрузить можно файл с любым расширением, но HRlink сконвертирует в PDF/A только файлы с расширениями: pdf, doc, docx, xls, xlsx, rtf, jpeg, jpg, bmp, png, tiff. Подробнее — в разделе Конвертация в PDF/A.
Примеры загрузки
- User-Api-Token
- Master-Api-Token
- curl
- PowerShell
- HTTP
curl -X POST "https://{tenantHost}/api/v1/files" \
-H "Accept: application/json" \
-H "User-Api-Token: {token}" \
-F "file=@/path/to/document.pdf"
Invoke-RestMethod `
-Method POST `
-Uri "https://{tenantHost}/api/v1/files" `
-Headers @{
"Accept" = "application/json"
"User-Api-Token" = "{token}"
} `
-Form @{
file = Get-Item "/path/to/document.pdf"
}
POST /api/v1/files HTTP/1.1
Host: {tenantHost}
Accept: application/json
User-Api-Token: {token}
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf
{бинарные данные файла}
------Boundary--
- curl
- PowerShell
- HTTP
curl -X POST "https://{tenantHost}/api/v1/files" \
-H "Accept: application/json" \
-H "Master-Api-Token: {masterToken}" \
-H "Impersonated-User-Id: {userId}" \
-H "Impersonated-User-Id-Type: HR_LINK_ID" \
-F "file=@/path/to/document.pdf"
Invoke-RestMethod `
-Method POST `
-Uri "https://{tenantHost}/api/v1/files" `
-Headers @{
"Accept" = "application/json"
"Master-Api-Token" = "{masterToken}"
"Impersonated-User-Id" = "{userId}"
"Impersonated-User-Id-Type" = "HR_LINK_ID"
} `
-Form @{
file = Get-Item "/path/to/document.pdf"
}
POST /api/v1/files HTTP/1.1
Host: {tenantHost}
Accept: application/json
Master-Api-Token: {masterToken}
Impersonated-User-Id: {userId}
Impersonated-User-Id-Type: HR_LINK_ID
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf
{бинарные данные файла}
------Boundary--
Ответ
{
"result": true,
"files": [
{
"id": "4d64b869-7a7e-4c2b-95aa-7498e97e023b",
"creatorId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"name": "document.pdf",
"createdDate": "2024-09-30T18:04:10.441842Z"
}
]
}
Сохраните id и передавайте его в поле fileId при создании документов.
У файлов нет поля externalId, в отличие от сотрудников, юрлиц и других сущностей (см. Идентификаторы). multipart/form-data не позволяет передать отдельные метаданные для каждого файла, поэтому при загрузке нескольких файлов в одном запросе нельзя надёжно связать внешний идентификаторexternalId Внешний идентификатор сущности — произвольная строка, задаваемая интегратором при создании. Связывает сущность HRlink с записью во внешней системе (1С, SAP и др.) без хранения маппинга UUID. с конкретным файлом. Сохраняйте возвращённые id на своей стороне.
Скачивание файлов
В API HRlink есть два способа скачать файл:
- По одноразовому токену — например, для скачивания архивов документов и заявлений (подписанный файл + откреплённые подписи в ZIP)
- Напрямую по идентификатору — для скачивания публичного файла по
fileId
Способ 1. Скачивание по одноразовому токену
Подробная спецификация: Скачать файл (по токену).
Сервер выдаёт одноразовый токен скачивания при запросе архива документа или заявления. Методы архива возвращают 303 See Other с заголовком Location — ссылка вида:
https://{tenantHost}/api/v1/files?token={downloadToken}
Ограничения токена скачивания:
- Токен действует 5 минут с момента выдачи
- Токен одноразовый — после первого использования сервер его отзывает
- Токен привязан к пользователю, который запросил скачивание. Другой пользователь им воспользоваться не сможет
Пример:
- curl
- PowerShell
- HTTP
# 1. Запросить архив документа (получить ссылку с токеном)
curl -v -X GET "https://{tenantHost}/api/v1/clients/{clientId}/documents/{documentId}/archive" \
-H "User-Api-Token: {token}"
# В ответе будет 303 с заголовком Location:
# Location: https://{tenantHost}/api/v1/files?token=a3f1b2c4-...
# 2. Скачать файл по полученной ссылке
curl -X GET "https://{tenantHost}/api/v1/files?token=a3f1b2c4-..." \
-o archive.zip
# 1. Запросить архив документа (получить ссылку с токеном)
$response = Invoke-WebRequest `
-Method GET `
-Uri "https://{tenantHost}/api/v1/clients/{clientId}/documents/{documentId}/archive" `
-Headers @{
"User-Api-Token" = "{token}"
} `
-MaximumRedirection 0 `
-Verbose
# В ответе будет 303 с заголовком Location:
$downloadUrl = $response.Headers["Location"]
# 2. Скачать файл по полученной ссылке
Invoke-RestMethod `
-Method GET `
-Uri $downloadUrl `
-OutFile "archive.zip"
GET /api/v1/clients/{clientId}/documents/{documentId}/archive HTTP/1.1
Host: {tenantHost}
User-Api-Token: {token}
# Ответ: 303 See Other
# Location: https://{tenantHost}/api/v1/files?token=a3f1b2c4-...
GET /api/v1/files?token=a3f1b2c4-... HTTP/1.1
Host: {tenantHost}
Способ 2. Скачивание напрямую по идентификатору файла
Подробная спецификация: Скачать публичный файл.
Скачайте файл напрямую по идентификатору — для этого передайте пользовательский или мастер-токенMaster-Api-Token Мастер-токен для M2M-интеграций. Позволяет выполнять запросы от имени любого пользователя системы через заголовки Impersonated-User-Id. Получается через ESA с помощью сертификата интегратора..
- curl
- PowerShell
- HTTP
curl -X GET "https://{tenantHost}/api/v1/files/{fileId}" \
-H "User-Api-Token: {token}" \
-o downloaded_file.pdf
Invoke-RestMethod `
-Method GET `
-Uri "https://{tenantHost}/api/v1/files/{fileId}" `
-Headers @{
"User-Api-Token" = "{token}"
} `
-OutFile "downloaded_file.pdf"
GET /api/v1/files/{fileId} HTTP/1.1
Host: {tenantHost}
User-Api-Token: {token}
Ответ: бинарный файл (application/octet-stream).
Типичные ошибки при загрузке
Повреждение файлов
Самая частая проблема при интеграции: файл загружается, но конвертация в PDF/A завершается ошибкой.
Причины:
- Клиент неправильно формирует
multipart/form-dataзапрос - Клиентская система повреждает двоичные данные при передаче
- Клиент неправильно кодирует содержимое файла
Как диагностировать:
- Загрузите тот же файл через UI HRlink
- Если через UI файл загружается без ошибок — проблема в формировании запроса на стороне клиента
- Проверьте
boundaryв multipart-запросе
Правильная структура multipart-запроса (RFC 2046):
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf
{бинарные данные файла}
------Boundary--
Последний boundary обязательно должен заканчиваться на --. Без него сервер вернёт ошибку Unexpected end of input.
Файл передан как raw JSON
Неправильно — такой запрос не работает:
{
"file": "base64-encoded-content"
}
API не принимает файлы в base64 или любом другом формате внутри JSON. Передавайте файлы только через multipart/form-data.
Недопустимое расширение файла
Если расширение файла входит в список запрещённых — сервер вернёт ошибку 400.
Решение: перед отправкой сконвертируйте файл в допустимый формат — например, в PDF.