## Список операций загрузки

`GET /v1/disk/uploads`

Возвращает операции загрузки файлов на Диск Битрикс24, созданные в [контексте ключа](/docs/disk/uploads-reserve#известные-особенности): незавершённые или недавно завершённые. Помогает восстановить потерянный идентификатор операции и найти записи с неизвестным результатом.

## Параметры

| Параметр | Тип | Обяз. | По умолч. | Описание |
|----------|-----|:-----:|-----------|----------|
| `filter` (query) | string | да | — | `pending` — операции в работе: `phase` равен `prepared` или `submitting`, либо `application` равен `unknown`. `recent` — завершённые операции с `application` равным `applied` или `not_applied`, созданные не раньше 90 дней назад |
| `limit` (query) | number | нет | `50` | Записей на страницу, целое от `1` до `100` |
| `cursor` (query) | string | нет | — | Значение `nextCursor` из прошлого ответа. В первом запросе не передаётся |

Других параметров запрос не принимает: неизвестный параметр даёт `400 INVALID_PARAMS`.

Записи идут от старых к новым. Пока в ответе `hasMore: true`, запрашивайте следующую страницу с `cursor`, равным `nextCursor`, и тем же `filter`.

## Примеры

### curl — личный ключ

```bash
curl "https://vibecode.bitrix24.tech/v1/disk/uploads?filter=recent&limit=2" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth-приложение

```bash
curl "https://vibecode.bitrix24.tech/v1/disk/uploads?filter=recent&limit=2" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — личный ключ

```javascript
const items = []
let cursor
do {
  const params = new URLSearchParams({ filter: 'recent', limit: '2' })
  if (cursor) params.set('cursor', cursor)
  const res = await fetch(`https://vibecode.bitrix24.tech/v1/disk/uploads?${params}`, {
    headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  })
  const { success, data, error } = await res.json()
  if (!success) throw new Error(error.code)
  items.push(...data.items)
  cursor = data.hasMore ? data.nextCursor : undefined
} while (cursor)

console.log(items.map(item => `${item.intentSummary.effectiveFilename}: ${item.application}`))
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/disk/uploads?filter=recent&limit=2', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { success, data, error } = await res.json()
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | `true` при успешном чтении |
| `data.items` | array | Операции страницы. Пустой массив, если под `filter` ничего не попало |
| `data.items[].operationId` | string | Идентификатор операции. Подробности: [`GET /v1/disk/uploads/:operationId`](/docs/disk/uploads-get) |
| `data.items[].phase` | string | Этап операции: `prepared`, `submitting` или `settled` |
| `data.items[].application` | string | Результат записи: `applied`, `not_applied` или `unknown` |
| `data.items[].verification` | string | Результат последней сверки с текущим файлом: `matched`, `superseded` или `unavailable` |
| `data.items[].intentSummary.mode` | string | Режим из резерва: `create` или `version` |
| `data.items[].intentSummary.targetId` | string | ID папки при `create` или ID файла при `version` |
| `data.items[].intentSummary.effectiveFilename` | string | Имя файла из резерва |
| `data.items[].intentSummary.contentSize` | string | Размер файла в байтах |
| `data.items[].intentSummary.intentHash` | string | `intentHash` операции — нужен для [`POST /v1/disk/uploads`](/docs/disk/uploads) |
| `data.items[].priorOperationId` | string | Прошлая операция, от которой зарезервирована эта. Приходит у операций с `lineage.kind` равным `successor` или `retry` |
| `data.hasMore` | boolean | `true`, если есть следующая страница |
| `data.nextCursor` | string | Курсор следующей страницы. Приходит при `hasMore: true` |

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

Первая страница `filter=recent&limit=2`:

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "operationId": "zSTFAm53NusAWc94THbRTOfbe-OIoHwlDIJTQ6E2Z7o",
        "phase": "settled",
        "application": "applied",
        "verification": "matched",
        "intentSummary": {
          "mode": "create",
          "targetId": "1",
          "effectiveFilename": "vibe-disk-docs-check.txt",
          "contentSize": "27",
          "intentHash": "3e55280c097b92721a6c58da586363f1169e7dec15990fe3fa7f44f543b8331a"
        }
      },
      {
        "operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
        "phase": "settled",
        "application": "applied",
        "verification": "superseded",
        "intentSummary": {
          "mode": "create",
          "targetId": "1",
          "effectiveFilename": "vibe-disk-docs-check-2.txt",
          "contentSize": "29",
          "intentHash": "3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498"
        }
      }
    ],
    "hasMore": true,
    "nextCursor": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU"
  }
}
```

Следующая страница с `cursor` — операция новой версии файла несёт `priorOperationId`:

```json
{
  "success": true,
  "data": {
    "items": [
      {
        "operationId": "dlbBsp01PqU2VBXjA8VigHPCXE_T01lBJgCp_gNfypY",
        "phase": "settled",
        "application": "applied",
        "verification": "matched",
        "intentSummary": {
          "mode": "version",
          "targetId": "10901",
          "effectiveFilename": "vibe-disk-docs-check-2.txt",
          "contentSize": "32",
          "intentHash": "07b6444b0eb202f1c7c11b50d5617a86790e80e6bb9d487c0e90776d1a0f0a75"
        },
        "priorOperationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU"
      },
      {
        "operationId": "QSCV6zB59O811A1pNO9HfekQdMvGifw4_E9-y1OZs48",
        "phase": "settled",
        "application": "not_applied",
        "verification": "unavailable",
        "intentSummary": {
          "mode": "version",
          "targetId": "10901",
          "effectiveFilename": "vibe-disk-docs-check-2.txt",
          "contentSize": "16",
          "intentHash": "76d560e3bf0b2bfabb85152474db537ebb08225558e37537f9ff86fbafebe0ad"
        }
      }
    ],
    "hasMore": false
  }
}
```

## Пример ответа при ошибке

400 — `limit` больше `100`:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Disk request unavailable",
    "retrySafe": false
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | Не передан `filter` или он не `pending` и не `recent`, `limit` не целое от `1` до `100`, `cursor` длиннее 512 символов, передан неизвестный параметр |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Ключ не опознан |
| 401 | `TOKEN_MISSING` | У ключа нет подключения к Битрикс24 |
| 401 | `DISK_AUTH_UNAVAILABLE` | Не удалось подтвердить пользователя Битрикс24: ключ приложения передан без `Authorization: Bearer`, сессия не принадлежит приложению ключа или ключ не поддерживается агентом Диска |
| 401 | `TOKEN_REFRESH_FAILED` | Не удалось обновить авторизацию портала для ключа. Повтор не поможет, пока ключ не авторизован заново |
| 403 | `SCOPE_DENIED` | У ключа нет скоупа `disk` |
| 403 | `DISK_ACCESS_DENIED` | Битрикс24 отказал в доступе при проверке пользователя |
| 409 | `DISK_OPERATION_CONFLICT` | `cursor` не является идентификатором операции в контексте ключа |
| 502 | `DISK_READ_UNAVAILABLE` | Битрикс24 вернул ошибку, которую Вайбкод не распознал |
| 503 | `QUERY_LIMIT_EXCEEDED` | Битрикс24 ограничил частоту запросов. Повторите позже |
| 503 | `BITRIX_TIMEOUT` | Битрикс24 не ответил вовремя |
| 503 | `QUEUE_OVERFLOW`, `QUEUE_TIMEOUT` | Очередь вызовов портала переполнена. Заголовок `Retry-After` называет паузу перед повтором |
| 503 | `RATE_LIMITED` | Портал ответил HTTP 429. Паузу перед повтором называет заголовок `Retry-After` |
| 503 | `ERROR_LOOP_DETECTED` | Повторяющиеся ошибки этого ключа на этом методе временно остановили вызовы. Паузу называет заголовок `Retry-After` |
| 503 | `user_self_deletion_pending` | Владелец ключа запросил удаление своей учётной записи — обращения к Диску остановлены |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **`verification` в списке не пересчитывается.** Поле несёт результат последней сверки. Чтобы сверить операцию с текущим файлом, запросите [`GET /v1/disk/uploads/:operationId`](/docs/disk/uploads-get).

## Смотрите также

- [Получить операцию загрузки](/docs/disk/uploads-get)
- [Зарезервировать загрузку файла на Диск](/docs/disk/uploads-reserve)
- [Загрузить содержимое файла на Диск](/docs/disk/uploads)
- [Ошибки](/docs/errors)
