# Загрузки

> Эндпоинты загрузки материалов в Slicer API — создать загрузку, отправить файл целиком, по частям или по одноразовой ссылке, импорт по адресу, статус и отмена.

Источник: https://docs.slicer.media/api/reference/uploads/

Загрузка — видео, фото или аудио, из которого собирается монтаж. Сначала загрузка создаётся (`createUpload`), затем файл отправляется одним из способов, после проверки статус становится `ready`. Как выбрать способ и обработать ошибки — в руководстве [Загрузка файлов](https://docs.slicer.media/api/uploads/).

## Начать загрузку

`POST /v1/uploads`

- **Области доступа:** `projects:write`
- **Лимит:** обычный

Возвращает загрузку и одноразовую ссылку `uploadUrl`. Дальше — `PUT` всего файла на `uploadUrl` (без токена) или на `/v1/uploads/{id}/content`, либо части по 8 МиБ на `/v1/uploads/{id}/parts/{n}` и `complete`.

### Тело запроса `CreateUploadRequest`

| Поле | Тип | Описание |
| --- | --- | --- |
| `fileName` _(обязательное)_ | `string` | Имя файла с расширением: по нему определяется вид — ≤ 255 |
| `size` _(обязательное)_ | `integer` | Размер файла, байт — ≥ 1 |
| `mimeType` | `string` | — ≤ 128 |
| `purpose` | `string` | `source` (по умолчанию) — материал монтажа — `source` · `media` · `music` |

### Запрос

**curl**

```bash
curl -X POST "https://api.slicer.media/v1/uploads" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fileName":"interview.mp4","size":104857600}'
```

**JavaScript**

```js
const response = await fetch('https://api.slicer.media/v1/uploads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "fileName": "interview.mp4",
    "size": 104857600
  }),
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://api.slicer.media/v1/uploads",
    headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}"},
    json={
        "fileName": "interview.mp4",
        "size": 104857600,
    },
)
body = response.json()
```

### Ответ

**Поля ответа: `CreatedUpload` (3)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `upload` _(обязательное)_ | `Upload` |     |
| `uploadUrl` _(обязательное)_ | `string (uri)` | Одноразовая ссылка: `PUT` всего файла без токена (≤ 1 ч, только запись) |
| `uploadUrlExpiresAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "upload": {
      "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
      "fileName": "interview.mp4",
      "purpose": "source",
      "origin": "client",
      "sizeBytes": 104857600,
      "status": "uploading",
      "partSize": 104857600,
      "partCount": 13,
      "uploadedParts": [
        1
      ],
      "progress": 0.5,
      "media": {
        "kind": null,
        "durationSec": null,
        "width": null,
        "height": null,
        "hasAudio": null
      },
      "error": "string",
      "createdAt": "2026-10-16T09:30:00Z"
    },
    "uploadUrl": "https://api.slicer.media/v1/…",
    "uploadUrlExpiresAt": "2026-10-16T09:30:00Z"
  }
}
```

## Загрузить файл по одноразовой ссылке

`PUT /v1/upload-links/{secret}`

- **Области доступа:** без токена
- **Лимит:** обычный

Без токена: разрешение — секрет в адресе. Только запись, один файл, ≤ 1 ч. `curl -T video.mp4 <uploadUrl>`

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `secret` _(обязательное)_ | `string` |     |

### Тело запроса

Байты файла (`application/octet-stream`).

### Запрос

**curl**

```bash
curl -X PUT "https://api.slicer.media/v1/upload-links/upl_…" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @video.mp4
```

**JavaScript**

```js
import { readFile } from 'node:fs/promises';

const response = await fetch('https://api.slicer.media/v1/upload-links/upl_…', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/octet-stream',
  },
  body: await readFile('video.mp4'),
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import requests

with open("video.mp4", "rb") as file:
    response = requests.put(
        "https://api.slicer.media/v1/upload-links/upl_…",
        headers={"Content-Type": "application/octet-stream"},
        data=file,
    )
body = response.json()
```

### Ответ

**Поля ответа: `Upload` (18)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "fileName": "interview.mp4",
    "purpose": "source",
    "origin": "client",
    "sizeBytes": 104857600,
    "status": "uploading",
    "partSize": 104857600,
    "partCount": 13,
    "uploadedParts": [
      1
    ],
    "progress": 0.5,
    "media": {
      "kind": "video",
      "durationSec": 42.5,
      "width": 1,
      "height": 1,
      "hasAudio": true
    },
    "error": "string",
    "createdAt": "2026-10-16T09:30:00Z"
  }
}
```

## Загрузить файл целиком

`PUT /v1/uploads/{id}/content`

- **Области доступа:** `projects:write`
- **Лимит:** обычный

Тело — байты файла, `Content-Length` равен заявленному размеру. Загрузка завершается сама.

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |

### Тело запроса

Байты файла (`application/octet-stream`).

### Запрос

**curl**

```bash
curl -X PUT "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @video.mp4
```

**JavaScript**

```js
import { readFile } from 'node:fs/promises';

const response = await fetch('https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
    'Content-Type': 'application/octet-stream',
  },
  body: await readFile('video.mp4'),
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

with open("video.mp4", "rb") as file:
    response = requests.put(
        "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content",
        headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}", "Content-Type": "application/octet-stream"},
        data=file,
    )
body = response.json()
```

### Ответ

**Поля ответа: `Upload` (18)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "fileName": "interview.mp4",
    "purpose": "source",
    "origin": "client",
    "sizeBytes": 104857600,
    "status": "uploading",
    "partSize": 104857600,
    "partCount": 13,
    "uploadedParts": [
      1
    ],
    "progress": 0.5,
    "media": {
      "kind": "video",
      "durationSec": 42.5,
      "width": 1,
      "height": 1,
      "hasAudio": true
    },
    "error": "string",
    "createdAt": "2026-10-16T09:30:00Z"
  }
}
```

## Загрузить часть

`PUT /v1/uploads/{id}/parts/{n}`

- **Области доступа:** `projects:write`
- **Лимит:** части загрузки

Части нумеруются с 1; все, кроме последней, — ровно `partSize` байт. Части можно слать параллельно и повторять.

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `n` _(обязательное)_ | `integer` | — ≥ 1 |

### Тело запроса

Байты файла (`application/octet-stream`).

### Запрос

**curl**

```bash
curl -X PUT "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @video.mp4
```

**JavaScript**

```js
import { readFile } from 'node:fs/promises';

const response = await fetch('https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
    'Content-Type': 'application/octet-stream',
  },
  body: await readFile('video.mp4'),
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

with open("video.mp4", "rb") as file:
    response = requests.put(
        "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1",
        headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}", "Content-Type": "application/octet-stream"},
        data=file,
    )
body = response.json()
```

### Ответ

**Поля ответа: `object` (2)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `part` _(обязательное)_ | `integer` |     |
| `etag` _(обязательное)_ | `string` |     |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "part": 1,
    "etag": "string"
  }
}
```

## Завершить загрузку по частям

`POST /v1/uploads/{id}/complete`

- **Области доступа:** `projects:write`
- **Лимит:** обычный

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |

### Запрос

**curl**

```bash
curl -X POST "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete" \
  -H "Authorization: Bearer $SLICER_TOKEN"
```

**JavaScript**

```js
const response = await fetch('https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
  },
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete",
    headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}"},
)
body = response.json()
```

### Ответ

**Поля ответа: `Upload` (18)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "fileName": "interview.mp4",
    "purpose": "source",
    "origin": "client",
    "sizeBytes": 104857600,
    "status": "uploading",
    "partSize": 104857600,
    "partCount": 13,
    "uploadedParts": [
      1
    ],
    "progress": 0.5,
    "media": {
      "kind": "video",
      "durationSec": 42.5,
      "width": 1,
      "height": 1,
      "hasAudio": true
    },
    "error": "string",
    "createdAt": "2026-10-16T09:30:00Z"
  }
}
```

## Загрузить файл по адресу

`POST /v1/uploads/import`

- **Области доступа:** `projects:write`
- **Лимит:** обычный

Скачивает публичный https-файл в фоне. Опрашивайте `GET /v1/uploads/{id}` или ждите вебхук `upload.ready`.

### Тело запроса `ImportUploadRequest`

| Поле | Тип | Описание |
| --- | --- | --- |
| `url` _(обязательное)_ | `string (uri)` | Публичный https-адрес файла — ≤ 2048 |
| `fileName` | `string` | Имя с расширением, если его нет в адресе — ≤ 255 |
| `purpose` | `string` | — `source` · `media` · `music` |

### Запрос

**curl**

```bash
curl -X POST "https://api.slicer.media/v1/uploads/import" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hook"}'
```

**JavaScript**

```js
const response = await fetch('https://api.slicer.media/v1/uploads/import', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "url": "https://example.com/hook"
  }),
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.post(
    "https://api.slicer.media/v1/uploads/import",
    headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}"},
    json={
        "url": "https://example.com/hook",
    },
)
body = response.json()
```

### Ответ

**Поля ответа: `Upload` (18)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "fileName": "interview.mp4",
    "purpose": "source",
    "origin": "client",
    "sizeBytes": 104857600,
    "status": "uploading",
    "partSize": 104857600,
    "partCount": 13,
    "uploadedParts": [
      1
    ],
    "progress": 0.5,
    "media": {
      "kind": "video",
      "durationSec": 42.5,
      "width": 1,
      "height": 1,
      "hasAudio": true
    },
    "error": "string",
    "createdAt": "2026-10-16T09:30:00Z"
  }
}
```

## Статус загрузки

`GET /v1/uploads/{id}`

- **Области доступа:** `projects:read`
- **Лимит:** обычный

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |

### Запрос

**curl**

```bash
curl "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" \
  -H "Authorization: Bearer $SLICER_TOKEN"
```

**JavaScript**

```js
const response = await fetch('https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20', {
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
  },
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}"},
)
body = response.json()
```

### Ответ

**Поля ответа: `Upload` (18)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "fileName": "interview.mp4",
    "purpose": "source",
    "origin": "client",
    "sizeBytes": 104857600,
    "status": "uploading",
    "partSize": 104857600,
    "partCount": 13,
    "uploadedParts": [
      1
    ],
    "progress": 0.5,
    "media": {
      "kind": "video",
      "durationSec": 42.5,
      "width": 1,
      "height": 1,
      "hasAudio": true
    },
    "error": "string",
    "createdAt": "2026-10-16T09:30:00Z"
  }
}
```

## Отменить загрузку

`DELETE /v1/uploads/{id}`

- **Области доступа:** `projects:write`
- **Лимит:** обычный

### Параметры пути

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |

### Запрос

**curl**

```bash
curl -X DELETE "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" \
  -H "Authorization: Bearer $SLICER_TOKEN"
```

**JavaScript**

```js
const response = await fetch('https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.SLICER_TOKEN}`,
  },
});
const { ok, data, error } = await response.json();
```

**Python**

```python
import os
import requests

response = requests.delete(
    "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    headers={"Authorization": f"Bearer {os.environ['SLICER_TOKEN']}"},
)
body = response.json()
```

### Ответ

**Поля ответа: `object` (2)**

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `deleted` _(обязательное)_ | `boolean` |     |

Пример ответа:

```json
{
  "ok": true,
  "data": {
    "id": "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20",
    "deleted": true
  }
}
```

## Схемы

`Upload`

| Поле | Тип | Описание |
| --- | --- | --- |
| `id` _(обязательное)_ | `string (uuid)` |     |
| `fileName` _(обязательное)_ | `string` |     |
| `purpose` _(обязательное)_ | `string` | — `source` · `media` · `music` |
| `origin` _(обязательное)_ | `string` | — `client` · `import` · `server` |
| `sizeBytes` _(обязательное)_ | `integer` |     |
| `status` _(обязательное)_ | `string` | — `uploading` · `processing` · `ready` · `failed` · `aborted` |
| `partSize` _(обязательное)_ | `integer` | Размер части для `PUT …/parts/{n}`, байт (8 МиБ) |
| `partCount` _(обязательное)_ | `integer` |     |
| `uploadedParts` _(обязательное)_ | `integer[]` |     |
| `progress` _(обязательное)_ | `number \| null` | Прогресс импорта 0–1 при загрузке по адресу — 0–1 |
| `media` _(обязательное)_ | `object \| null` |     |
| `media.kind` _(обязательное)_ | `string` | — `video` · `image` · `audio` |
| `media.durationSec` _(обязательное)_ | `number` |     |
| `media.width` _(обязательное)_ | `integer` |     |
| `media.height` _(обязательное)_ | `integer` |     |
| `media.hasAudio` _(обязательное)_ | `boolean` |     |
| `error` _(обязательное)_ | `string \| null` |     |
| `createdAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |

`CreatedUpload`

| Поле | Тип | Описание |
| --- | --- | --- |
| `upload` _(обязательное)_ | `Upload` |     |
| `uploadUrl` _(обязательное)_ | `string (uri)` | Одноразовая ссылка: `PUT` всего файла без токена (≤ 1 ч, только запись) |
| `uploadUrlExpiresAt` _(обязательное)_ | `string` | Дата и время ISO 8601, UTC |
