#Загрузить файл
POST /v1/infra/servers/:id/upload
Записывает файл на BLACKHOLE-сервер через агент туннеля. Два варианта источника: встроенное base64-содержимое в теле запроса (до 50 МБ) или URL, с которого агент скачает файл сам (до 500 МБ). Поддерживается автоматическая распаковка архивов tar.gz / tar.bz2 / zip — формат определяется по сигнатуре файла (magic bytes) или по расширению URL.
#Параметры
| Параметр | В | Тип | Обяз. | Описание |
|---|---|---|---|---|
id |
path | string (UUID) | да | ID BLACKHOLE-сервера, status: running, blackholeStatus: CONNECTED |
#Поля запроса (body)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
path |
string | да | Путь на сервере, 1–500 символов. Для архивов — куда положить загруженный архив до распаковки |
content |
string | да (или url) |
Base64-содержимое файла. Максимум 50 МБ на тело запроса |
url |
string | да (или content) |
HTTPS-URL, откуда агент скачает файл. До 500 МБ |
mode |
string | нет | Права файла в восьмеричном формате: 0644, 0755. Применяется к файлу по пути path |
extract |
boolean | нет | Распаковать архив после загрузки. По умолчанию false. Требует content или url с архивом |
extractTo |
string | нет | Директория для распаковки (при extract: true). По умолчанию — директория из path |
Нужно передать ровно одно из: content или url.
#Примеры
#curl — личный ключ
# Загрузка файла по URL с автоматической распаковкой
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/upload \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://github.com/user/repo/archive/main.tar.gz",
"path": "/opt/app/source.tar.gz",
"extract": true,
"extractTo": "/opt/app"
}'
# Встроенное base64-содержимое — маленький файл (package.json)
CONTENT=$(echo '{"name":"my-app","version":"1.0.0"}' | base64)
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/upload \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"content\":\"$CONTENT\",\"path\":\"/opt/app/package.json\",\"mode\":\"0644\"}"
#curl — OAuth-приложение
curl -X POST https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/upload \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/config.json","path":"/etc/myapp/config.json"}'
#JavaScript — личный ключ
// Загрузка архива и распаковка
const res = await fetch(
`https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/upload`,
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://github.com/user/app/archive/main.tar.gz',
path: '/opt/app/source.tar.gz',
extract: true,
extractTo: '/opt/app',
}),
}
)
const { data } = await res.json()
console.log(`Записано ${data.size} байт по пути ${data.path}${data.extracted ? ', распаковано' : ''}`)
#JavaScript — OAuth-приложение
// Встроенное base64-содержимое — маленький конфиг
const content = Buffer.from('NODE_ENV=production\n').toString('base64')
await fetch(
`https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/upload`,
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
content,
path: '/opt/app/.env',
mode: '0600',
}),
}
)
#Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | true при успешной записи |
data.path |
string | Итоговый путь файла на сервере |
data.size |
number | Размер в байтах |
data.extracted |
boolean | true если архив был распакован после загрузки |
#Пример ответа
{
"success": true,
"data": {
"path": "/opt/app/source.tar.gz",
"size": 1048576,
"extracted": true
}
}
#Пример ответа при ошибке
403 — путь запрещён для загрузки:
{
"success": false,
"error": {
"code": "UPLOAD_PATH_DENIED",
"message": "Upload to system path is not allowed"
}
}
#Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | VALIDATION_ERROR |
Нарушена схема: одновременно content и url, либо ни одного; неверный path; тело больше 50 МБ |
| 400 | NOT_BLACKHOLE |
Сервер в режиме OPEN — Deploy API недоступен |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 401 | INVALID_API_KEY |
Неверный или просроченный API-ключ |
| 403 | UPLOAD_PATH_DENIED |
Загрузка в системные директории (/root/.ssh, /etc/passwd, /boot, …) запрещена |
| 404 | NOT_FOUND |
Сервер не существует, удалён или принадлежит другому API-ключу |
| 409 | AGENT_NOT_CONNECTED |
Агент туннеля не в статусе CONNECTED |
| 429 | RATE_LIMIT_EXCEEDED |
Превышен лимит 10 операций в минуту на сервер |
| 500 | UPLOAD_FAILED |
Ошибка записи на агенте (нехватка места, права доступа и т. п.) |
| 502 | GATEWAY_ERROR |
Gateway вернул ошибку |
Полный список общих ошибок API — Ошибки.
#Известные особенности
- Автоопределение формата архива при
extract: true. Агент определяет формат по сигнатуре файла (magic bytes, функцияdetectArchiveExt()): поддерживает.tar.gz,.zip,.tar.bz2. Формат можно не указывать явно. Для URL — агент также проверяет расширение. - macOS-архивы чистятся автоматически. Если архив содержит AppleDouble-сайдкары (
._*) или.DS_Store, агент удаляет их после распаковки — это предотвращает ложные срабатывания сканеров вроде Tailwind v4 oxide. При создании архива на macOS советуем использоватьCOPYFILE_DISABLE=1 tar -czf ...чтобы сайдкары вообще не попадали в архив. - Windows PowerShell ZIP — работает на агенте ≥ 1.2.3.
Compress-Archiveв Windows пишет ZIP с литеральными\в именах файлов. Агент с версии 1.2.3 автоматически нормализует эти пути через шагnormalize_windows_paths. Для старых версий агента используйтеtar.gz(через WSL / Git Bash) либо выкладывайте готовый tar-архив и загружайте черезurl. - Список запрещённых путей. Агент блокирует загрузку в:
/root/.ssh/(защита SSH-ключей),/boot,/etc/shadow,/etc/passwd, системные сервис-файлы. Для приложения используйте/opt/<app>/или/var/lib/<app>/. modeприменяется к архиву, не к распакованным файлам. Приextract: trueправа распакованных файлов определяются содержимым архива, аmodeзадаётся только сохранённому архиву. Если нужно изменить права внутри — сделайте через `/exec` cchmod.- Таймаут 10 минут на загрузку через
url. Для 500 МБ должно уложиться. Если источник медленный — предзагрузите архив, положите на свой CDN.
#Смотрите также
- Полный деплой — обычно быстрее, чем
upload+exec. - Выполнить команду — после загрузки можно распаковать/установить вручную.
- Логи сервиса — проверить, что сервис подхватил новые файлы.