---
title: "Завершить загрузку файла складского импорта"
method: POST
path: "/api/v1/stock/upload-sessions/{id}/finish"
tags: ["Stock imports"]
---

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

`POST /api/v1/stock/upload-sessions/{id}/finish`

## Request

- Base URL: `https://erp.akeda.ru`
- URL: `https://erp.akeda.ru/api/v1/stock/upload-sessions/{id}/finish`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://erp.akeda.ru/oauth2/authorize`, token URL `https://erp.akeda.ru/oauth2/token`, scopes: `akeda:delegate`)

Проверяет, что файл лёг по выданному адресу: размер, контрольную сумму (если заявлена) и антивирус; подменённый после проверки файл отклоняется, заражённый удаляется и прогоном не становится. Затем разбирает таблицу и заводит прогон импорта (import) со статусом uploaded и номером сессии — дальше stockInspectImport, stockUpdateImportMapping, stockPreviewImport и stockApplyImport. Повтор возвращает тот же прогон. 409 transfer.not_uploaded — байтов ещё нет; 422 transfer.infected — найдена угроза, файл удалён; 503 transfer.scanner_unavailable — антивирус недоступен, повторите позже.

## Response `200`

Сессия и заведённый прогон

- StockUploadFinishResult: Итог завершения сессии склада: сессия и заведённый прогон импорта.
  - `session` TransferSession, required: Сессия загрузки файла по подписанному адресу хранилища. Ключи хранилища наружу не отдаются.
    - `id` string, uuid, required
    - `owner_type` string, required
    - `owner_id` string
    - `name` string, required
    - `mime_type` string, required
    - `size_bytes` integer, required
    - `sha256` string
    - `attributes` object
    - `status` 'pending' | 'processing' | 'attached' | 'failed' | 'expired', required
    - `failure` 'infected' | 'size' | 'checksum' | 'storage' | 'owner' | 'aborted' | 'expired'
    - `failure_detail` string
    - `scan_status` 'pending' | 'clean' | 'infected' | 'skipped'
    - `scan_verdict` string
    - `published_ref` string: Номер строки, заведённой по файлу; у почты — id загрузки для upload_ids
    - `expires_at` string, date-time, required
    - `created_at` string, date-time, required
    - `completed_at` string, date-time
    - `upload` TransferInstructions: Как передать байты. Выдаётся один раз, при открытии сессии.
      - `mode` 'post' | 'parts' | 'api', required: post — один multipart POST; parts — PUT каждой части; api — PUT через этот API с авторизацией
      - `url` string
      - `method` string
      - `fields` object: Поля формы для POST; файл идёт после них последним полем
      - `file_field` string: Имя поля формы для файла
      - `headers` object
      - `part_bytes` integer
      - `part_count` integer
      - `direct_urls` object: Подписанный адрес каждой части по её номеру, начиная с 1
      - `requires_authorization` boolean, required: true — адрес требует токен API, агенту по MCP этот путь недоступен
      - `max_bytes` integer, required
      - `expires_at` string, date-time, required
  - `import` StockImportRun
    - `id` string, uuid, required
    - `kind` 'initial_stock' | 'inventory_count' | 'document_items' | 'reorder_rules' | 'kit_specs' | 'agent_report_lines', required: Вид складской ЗАГРУЗКИ. Выгрузка шире, у неё свой перечень StockExportKind. agent_report_lines — строки отчёта комиссионера для формы отчёта в «Документах»; прогон только проверяет строки и находит товары, apply его не применяет
    - `format` 'xlsx' | 'xls' | 'ods' | 'csv' | 'tsv', required
    - `status` 'uploaded' | 'mapped' | 'previewed' | 'applied' | 'cancelled', required: cancelled — загрузка отменена целиком (stockCancelImport); бывает только у initial_stock
    - `mode` 'create_only' | 'upsert' | 'replace', required: Режим загрузки: create_only — initial_stock, kit_specs и agent_report_lines; upsert — добавить строки, строки с ID строки обновить (меняются только присланные колонки, __CLEAR__ очищает поле); replace — только document_items, строки файла заменяют все строки черновика
    - `target_document_id` string, uuid
    - `source_name` string, required
    - `source_sha256` string, required
    - `source_size` integer, required
    - `mapping` StockImportMappingState, required
      - `sheet_name` string, required
      - `header_row` integer, required
      - `columns` object, required
      - `defaults` object: Значение поля для всех строк, где колонки нет или ячейка пуста
      - `filter` StockImportRowFilter
        - `column` string, required: Заголовок колонки файла
        - `values` string[], required: Значения, строки с которыми загружаются; регистр не важен
      - `value_map` object: Замены значений файла, которых нет в справочнике: поле (warehouse, company, product, condition) → значение ячейки → идентификатор склада, юрлица или товара либо код состояния. Одно решение действует на все строки с этим значением
    - `schema_version` 'stock-v1', required
    - `revision` integer, required
    - `preview_token` string
    - `diff` StockImportDiff[]
      - `row` integer, required
      - `action` 'create' | 'update' | 'unchanged', required: initial_stock всегда create; document_items — create для новой строки и в режиме replace, update или unchanged для строки по ID строки; inventory_count — update или unchanged по товару снимка; reorder_rules — create для нового ключа, update или unchanged для существующего правила; kit_specs — create, update (новая версия состава) или unchanged. unchanged применение пропускает
      - `target_id` string, uuid
      - `label` string: Товар строки словами («артикул — название») после поиска; не найден — значение ячейки
      - `changes` object
      - `before` object: Только у update: прежние значения полей, которые строка изменит (стало — в changes)
    - `issues` CoreProductImportIssue[]
      - `sheet` string, required
      - `row` integer, required
      - `column` string, required
      - `code` string, required
      - `severity` 'warning' | 'error', required
      - `value` string
      - `message` string, required
      - `hint` string
      - `params` object: Сведения замечания для текста на другом языке (складская загрузка): documents и date у повторной загрузки, candidate у ненайденного артикула с ведущими нулями, column у несопоставленной колонки
    - `created_count` integer, required
    - `updated_count` integer, required
    - `unchanged_count` integer, required
    - `warning_count` integer, required
    - `error_count` integer, required
    - `created_by` integer
    - `created_at` string, date-time, required
    - `previewed_at` string, date-time
    - `applied_at` string, date-time
    - `cancelled_at` string, date-time
    - `documents` StockImportDocument[], required: Документы, которые создала загрузка. Заполняется у применённой загрузки initial_stock; у остальных видов и у загрузок, сделанных до появления связи, список пуст
      - `id` string, uuid, required
      - `number` string
      - `status` 'draft' | 'posted' | 'cancelled'
      - `date` string, date
      - `company_id` string, uuid
      - `warehouse_id` string, uuid
      - `warehouse_name` string
      - `is_marked_deleted` boolean, required
    - `source_columns` string[]
    - `source_sheets` CoreProductImportSheet[]
      - `name` string, required
    - `target_fields` CoreProductImportField[]
      - `key` string, required
      - `label` string, required
      - `required` boolean, required
      - `type` string, required
    - `source_values` object: Различающиеся значения колонок файла с небольшим набором значений (не больше 30): из них выбирается отбор строк — машина, склад
    - `target_document_type` string: Вид черновика, в который грузятся строки (document_items с target_document_id); target_fields — колонки этого вида
    - `source_samples` object: До трёх различающихся примеров значений каждой колонки файла
    - `source_filled` object: Число заполненных ячеек каждой колонки файла: заполненная колонка без решения (поле или «-» — не загружать) даёт ошибку column_not_decided

## Other responses

- `400`: Некорректный запрос или нарушение бизнес-правила
- `401`: Сессия, ключ или кабинет не подтверждены
- `404`: Запись не найдена или не видима текущему пользователю
- `409`: Конфликт версии, идемпотентности или бизнес-состояния
- `410`: Сессия передачи файла истекла
- `422`: Запрос разобран, но бизнес-значение недопустимо
- `503`: Внешний банк, справочник или контур подключений временно недоступен

---

[API](https://skmtc.dev/akeda/apis/akeda-erp-client-api.md) · [All operations](https://skmtc.dev/akeda/apis/akeda-erp-client-api/llms.txt) · [OpenAPI document](https://skmtc.dev/akeda/apis/akeda-erp-client-api/revisions/a99574d597cc?raw)
