PDF
Розділ: Файли заказів (API)

Файли заказів через API

Як виробнику надсилати дистрибʼютору файли заказів через API ApexSFA і забирати файл-відповідь: формати XML, CSV, JSON, статуси, повтори.

Виробник (або мережа, що працює через виробника) надсилає дистрибʼютору замовлення файлом — так, як вивантажує їх зі своєї облікової системи. ApexSFA сам розпізнає формат файлу, створює з кожного документа файлу заявку, а коли менеджер дистрибʼютора опрацював усі заявки файлу, готує файл-відповідь зі станом кожного документа: «Опрацьовано», «Редаговано», «Відхилено» або «Помилка».

Увесь обмін — чотири виклики:

МетодШляхЩо робить
POST/api/v1/exchange/order-filesПокласти файл заказів
GET/api/v1/exchange/order-filesСтатуси останніх 100 файлів цього токена
GET/api/v1/exchange/order-files/{id}Статус одного файлу
GET/api/v1/exchange/order-files/{id}/responseЗабрати файл-відповідь (409, поки не все опрацьовано)

Базова адреса — https://api.apexsfa.com/api/v1. Ті самі файли можна класти й через SFTP — див. 5. SFTP.

4.1. Життєвий цикл файлу

POST ──▶ received ──┬──▶ failed      жоден шаблон не розпізнав файл або не створено жодної заявки
                    └──▶ parsed ───▶ completed   усі заявки опрацьовані, файл-відповідь готовий
statusЗначення
receivedФайл прийнято, ще розбирається. Проміжний стан — у відповідях API зазвичай не трапляється.
failedФайл не розпізнано жодним шаблоном або з нього не створено жодної заявки. Причина — у полі error. Файл-відповіді не буде.
parsedЗаявки створено, вони чекають на менеджера. response_ready = false.
completedУсі заявки файлу опрацьовані, файл-відповідь готовий. response_ready = true.

Як заявка проходить шлях усередині ApexSFA:

  1. Кожен документ файлу стає окремою заявкою.
  2. Якщо точку доставки й усі товари документа впізнано — заявка одразу стає «Новою» і чекає на менеджера.
  3. Якщо якийсь товар не впізнано — заявка зберігається чернеткою з позначкою «Неповні дані»; менеджер добирає номенклатуру вручну.
  4. Якщо точку не впізнано — заявка створюється чернеткою зі статусом «Потребує обробки»; менеджер підставляє точку вручну (вибір запамʼятовується для наступних файлів).
  5. Якщо в документі взагалі немає коду точки доставки — заявка не створюється, документ отримує стан «Помилка».
  6. Менеджер погоджує, редагує або відхиляє заявки.
  7. Щойно опрацьовані всі заявки файлу — status стає completed і генерується файл-відповідь.

Примітка. Стан файлу оновлюється в момент вашого запиту GET. Вебхука про готовність файл-відповіді немає — використовуйте опитування, див. 4.11.

4.2. Автентифікація

Заголовок Authorization: Bearer asfa_… — API-токен, який видає команда ApexSFA на запит дистрибʼютора, див. 2.1.

Один токен — один виробник. Кожен токен бачить лише файли, завантажені цим самим токеном (GET чужого файлу → 404). Токен привʼязаний до виробника в довіднику дистрибʼютора, тому:

  • спершу пробується шаблон розбору, вказаний у картці цього виробника;
  • заявки привʼязуються до цього виробника (склад відвантаження — з його картки);
  • реквізити постачальника у файлі не обовʼязкові.
СитуаціяКодerror.message
Немає заголовка або він не Bearer …401Bearer API token required
Токен не знайдено401Invalid API token
Токен відкликано401Token is revoked
Минув строк дії401Token has expired
У токена немає прав на файли заказів403Token scope 'exchange:orders' required
Перевищено ліміт запитів токена429Rate limit exceeded: 100/min

4.3. POST /api/v1/exchange/order-files — покласти файл

Файл можна передати двома способами.

A. multipart/form-data, поле file:

curl -X POST "https://api.apexsfa.com/api/v1/exchange/order-files" \
  -H "Authorization: Bearer $APEX_TOKEN" \
  -F "file=@orders_2026-10-27.xml"

B. Сире тіло запиту (будь-який Content-Type, крім multipart/form-data), імʼя файлу — у query-параметрі filename:

curl
curl -X POST "https://api.apexsfa.com/api/v1/exchange/order-files?filename=orders_2026-10-27.json" \
  -H "Authorization: Bearer $APEX_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@orders_2026-10-27.json"
ПараметрДеТипОбовʼязковийОпис
filemultipart-полефайлтак (варіант A)Вміст файлу заказів. Імʼя файлу береться з multipart.
тіло запитуbodyбайтитак (варіант B)Вміст файлу як є.
filenamequerystringніІмʼя файлу для варіанта B. За замовчуванням orders.xml. До 300 символів.

Імʼя файлу й Content-Type не впливають на вибір шаблону — формат визначається за вмістом (див. 4.7). Імʼя файлу видно менеджеру й використовується в назві файлу-відповіді.

Відповідь 201 Created (і для нового файлу, і для повтору того самого файлу — див. duplicate):

JSON
{
  "id": "3f2a9c1e-7b4d-4e2a-9f10-5c6d7e8f9a01",
  "filename": "orders_2026-10-27.xml",
  "template": "<ключ шаблону>",
  "status": "parsed",
  "error": null,
  "documents": 1,
  "orders_created": 1,
  "duplicates_skipped": 0,
  "unmatched_lines": 0,
  "response_ready": false,
  "uploaded_at": "2026-10-27T07:21:43.512345+00:00",
  "duplicate": false
}

Файл, який не вдалося розпізнати, теж повертає 201, але зі status: "failed" і поясненням у error («Файл не розпізнано жодним шаблоном розбору (…)»).

Поля відповіді (спільні для всіх ендпоінтів статусу)

ПолеТипОпис
idUUIDІдентифікатор файлу. Зберігайте — по ньому статус і відповідь.
filenamestringІмʼя файлу, як його прийнято.
templatestring | nullТехнічний ключ шаблону, яким розпізнано файл; null, якщо не розпізнано. Логіку будуйте на status, а не на значенні ключа.
statusstringreceived / parsed / completed / failed.
errorstring | nullПояснення українською: чому failed, скільки документів «без точки», «Нових замовлень немає: усі N документів уже завантажували раніше» тощо. Може бути заповнене й при parsed.
documentsintСкільки документів знайдено у файлі.
orders_createdintСкільки заявок створено.
duplicates_skippedintСкільки документів пропущено як уже завантажені раніше (див. 4.9).
unmatched_linesintСкільки рядків товарів не вдалося впізнати (заявки з ними — чернетки).
response_readybooltrue — файл-відповідь готовий.
uploaded_atstringМомент прийому файлу, ISO 8601, UTC.
duplicateboolЛише в POST. true — точно такий самий файл (байт у байт) уже приймали; повернуто наявний файл, нічого нового не створено.

4.4. GET /api/v1/exchange/order-files — статуси своїх файлів

Повертає останні 100 файлів, завантажених цим токеном через API, від найновіших: {"data": [ … ]} з полями з 4.3 (без duplicate). Пагінації й фільтрів немає. Файли, покладені через SFTP, у цьому списку не зʼявляються.

4.5. GET /api/v1/exchange/order-files/{id} — статус одного файлу

Відповідь — один обʼєкт з полями з 4.3 (без duplicate), не загорнутий у data.

КодКоли
200Ок
404 File not foundФайлу з таким id немає, або його завантажено іншим токеном

4.6. GET /api/v1/exchange/order-files/{id}/response — забрати файл-відповідь

curl -OJ "https://api.apexsfa.com/api/v1/exchange/order-files/3f2a9c1e-7b4d-4e2a-9f10-5c6d7e8f9a01/response" \
  -H "Authorization: Bearer $APEX_TOKEN"
КодКоли
200Тіло — файл-відповідь (формат — див. 4.8)
404 File not foundФайлу немає або він чужого токена
409 Not all orders of this file are processed yetЩе є неопрацьовані заявки (для failed-файлу відповіді не буде ніколи)

Content-Type відповіді: application/xml для XML, application/json для JSON, text/csv для CSV. Файл-відповідь генерується один раз — у момент переходу в completed — і далі віддається той самий; забирати його можна скільки завгодно разів.

4.7. Формати файлів

Шаблон визначається автоматично за вмістом: ApexSFA по черзі пробує всі шаблони, перший, що розпізнав файл, виграє. Шаблон із картки виробника пробується першим.

ФорматСтруктураКодуванняДокумент =
XML «Заказы»XML, корінь <Заказы>будь-яке, оголошене в XML-декларації (рекомендовано UTF-8)<Документ>
CSV за номером документаCSV, роздільник ;, перший рядок — шапкаWindows-1251група рядків з однаковим НомерДокумента
CSV поставкиCSV, роздільник ;, перший рядок — шапкаWindows-1251 або UTF-8 з BOMгрупа рядків з однаковим НомерЗамовлення
JSON «Замовлення» / «Накладные»JSON-обʼєктUTF-8 (з BOM чи без)елемент масиву Замовлення / Накладные

Excel (xlsx) та інші формати не підтримуються — такий файл отримає status: "failed". Потрібен свій формат — напишіть нам.

Загальні правила для всіх форматів

  • Числа: допускаються і крапка, і кома як десятковий роздільник; пробіли (зокрема нерозривні) усередині чисел ігноруються: 1 191,6, 1191.6 — коректні.
  • Коди, штрихкоди, GLN, ЄДРПОУ порівнюються без пробілів: 4 820 000 900 017 = 4820000900017.
  • Дати: YYYY-MM-DD, DD.MM.YYYY, YYYY-MM-DDTHH:MM:SS, DD.MM.YYYY HH:MM:SS. Береться лише календарна дата, час відкидається. Дата з суфіксом поясу (…Z, +02:00) не розпізнається.
  • Логічні значення: Истина / Да / true / Так → так; Ложь / Нет / false / Ні → ні.
  • Рядок товару без коду товару або без кількості пропускається.

4.7.1. XML «Заказы»

Структура: Заказы / Документы / Документ[] / Строки / Строка[]. Корінь — саме <Заказы> без простору імен. Зайві теги ігноруються (у файлі-відповіді зберігаються). Приклад: examples/order-file-example.xml.

Документ (Заказы/Документы/Документ):

Тег (шлях від Документ)ОбовʼязковийЩо це
Идентификатортак*Унікальний ідентифікатор документа (GUID). Ключ документа.
Номертак*Номер документа. Ключ документа, якщо немає Идентификатор.
ДатарекомендованоДата документа. Разом із ключем — ключ захисту від дублів.
АдресДоставки/ИдентификатортакКод точки доставки (GLN, код мережі тощо). Без нього — документ «Помилка».
АдресДоставки/АдресніАдреса точки текстом (для менеджера).
Организация/Наименование, Организация/ЕГРПОУніВиробник-постачальник.
Контрагент/Идентификатор, Контрагент/НаименованиеніКонтрагент-покупець.
Контрагент/ЕГРПОУрекомендованоЄДРПОУ покупця — по ньому визначається контрагент і перевіряється, що точка належить саме йому.
Заказ/Номер, Заказ/ДатаніНомер і дата замовлення мережі (PO). Номер потрапляє в коментар заявки.
Договор/Наименование, Договор/Номер, Договор/Дата, Договор/ТипніДоговір (довідково).
СуммаВключаетНДСніЧи суми з ПДВ.
Штрихкод, ВидОперации, Комментарий, ДатаПоставки, СамовывозніЗберігаються довідково.

* потрібен хоча б один із Идентификатор / Номер; рекомендовано обидва, ключ — не довший за 64 символи.

Рядок (Документ/Строки/Строка):

ТегОбовʼязковийЩо це
Номенклатура/ИдентификатортакКод товару (код або артикул у каталозі дистрибʼютора).
КоличествотакКількість.
Номенклатура/НаименованиеніНазва товару.
ШтрихкодКонтрагентарекомендованоШтрихкод товару — другий спосіб знайти товар.
АртикулКонтрагентаніАртикул — третій спосіб знайти товар.
ЦенаСНДС (або Цена)ніЦіна з ПДВ — стає ціною рядка заявки.
ЦенаБезНДС, СуммаСНДС (або Сумма), СуммаБезНДС, СуммаНДСніЦіни й суми.
КоличествоКоробок, ОКЕИніЯщики, одиниця виміру.

Блок Документ/Итоги/ВсегоСтрок у файлі-відповіді оновлюється, якщо рядки змінено.

4.7.2. CSV за номером документа

Один рядок файлу = одна позиція документа; шапка документа повторюється в кожному рядку. Колонки шукаються за назвою в шапці (порядок довільний, зайві колонки ігноруються). Приклад: examples/order-file-example.csv (Windows-1251).

КолонкаОбовʼязковаЩо це
НомерДокументатакНомер документа — ключ групування й ключ документа.
КодТоваратакКод товару.
КоличествотакКількість.
ДатаДокументарекомендованоДата документа.
GLN_ТочкиДоставкитак**GLN точки доставки — пріоритетний код точки.
КодТочкиДоставкитак**Код точки — якщо GLN порожній.
НаименованиеТочкиДоставкиніНазва або адреса точки.
ЗаказніНомер замовлення мережі (PO).
КодКонтрагента, НаименованиеКонтрагента, ЕДРПОУ_Контрагента, ИНН Контрагентані (ЄДРПОУ рекомендовано)Контрагент-покупець.
Номер_Договора, КодСкладаОтгрузки, НаименованиеСкладаОтгрузкиніДовідково.
НаименованиеТовара, ШтрихКодТовара, НазваниеЕдИзмні (штрихкод рекомендовано)Товар.
СуммаСНДС, СуммаНДСніСума рядка з ПДВ і сума ПДВ; ціна = сума / кількість.
КоличествоМестніДовідково.

** потрібна хоча б одна з колонок коду точки.

Увага. Файли цього формату надсилайте у кодуванні Windows-1251. Роздільник — ;, лапки CSV не обробляються (крапку з комою всередині значень використовувати не можна).

4.7.3. CSV поставки

Одна поставка містить багато замовлень мережі; рядок = позиція накладної. Документ (заявка) = група рядків з однаковим НомерЗамовлення. Кількість заявки — місця (ящики), цін у файлі немає.

КолонкаОбовʼязковаЩо це
НомерПоставкитак (у шапці)Номер поставки (довідково).
НомерЗамовленнятакНомер замовлення — ключ документа.
ОтримувачЗамовленняВантажоодержувачЖЛНтакGLN точки доставки.
НоменклатураАртикултакАртикул товару.
НоменклатураКількістьМісцьтакКількість місць — кількість у заявці.
ДатаНакладноїрекомендованоДата документа (якщо порожня — ДатаПоставки).
ВиробникЄДРПОУ, ОтримувачЗамовленняКонтрагентЄДРПОУрекомендованоЄДРПОУ виробника й покупця.
ДатаПоставки, НомерНакладної, НомерЗамовленняEDI, назви й адреси отримувача, НоменклатураПовнаНазва, вага й коефіцієнтиніДовідково.

Чи потрібна файл-відповідь для цього формату, узгоджуємо під час підключення.

4.7.4. JSON «Замовлення» / «Накладные»

Корінь — JSON-обʼєкт з масивом Замовлення (новіший варіант) або Накладные. Кожен елемент — документ, масив Товары — рядки. Значення можна передавати рядками (числа — з крапкою). Приклад: examples/order-file-example.json.

Ключ документаОбовʼязковийЩо це
Ссылкатак*Ідентифікатор документа (GUID) — ключ документа.
Номертак*Номер документа — ключ, якщо немає Ссылка.
КодТочкиGLNрекомендовано**GLN точки доставки.
АдресДоставкитак**Адреса точки текстом. Без GLN точка ідентифікується за адресою; менеджер підставляє точку один раз, далі адреса розпізнається автоматично.
ДатаОтгрузкирекомендованоДата документа; якщо порожня — ДатаЗаказаEDIN.
НомерЗаказаEDIN, ДатаЗаказаEDINніНомер і дата замовлення мережі (PO).
Организация, ЕДРПОУ_ОргніВиробник-постачальник.
Контрагент, ЕДРПОУ_Контр, ИНН_Контрні (ЄДРПОУ рекомендовано)Контрагент-покупець.
Договор, НомерДоговора, ДатаДоговора, ЦеныВклНДС, СуммаДокументаніДоговір, ознака ПДВ, сума.
ТоварытакМасив рядків.

* документ без Ссылка і без Номер пропускається. ** потрібен хоча б один із КодТочкиGLN / АдресДоставки.

Ключ рядкаОбовʼязковийЩо це
КодтакКод товару в обліку виробника — ключ рядка (товар за ним не шукається).
КоличествотакКількість.
ШтрихкодрекомендованоШтрихкод одиниці — основний спосіб знайти товар.
Артикул2рекомендованоАртикул виробника — другий спосіб знайти товар.
Артикул1, Товар, Единица, НомСтр, Ссылка, ШтрихкодЯщніДовідково.
Цена, Сумма, СуммаНДСніЦіна з ПДВ (стає ціною рядка), суми.
КоличествоЯщніКількість ящиків. Для вагових рядків (Единица = кг) на штучному товарі кількість заявки = ящики.

4.7.5. Як шукаються точка, контрагент і товар

Точка доставки (код з файлу, без пробілів) — по черзі: відповідність, яку раніше вручну обрав менеджер; коди мереж у картці точки дистрибʼютора; GLN і коди точок доставки; код точки дистрибʼютора. Якщо у файлі визначено контрагента-покупця, точка приймається лише якщо вона належить цьому контрагенту — тому передавайте ЄДРПОУ покупця.

Товар — по черзі: код рядка в кодах і артикулах каталогу дистрибʼютора (крім JSON-формату, де код — ваш власний); штрихкод одиниці або упаковки; артикули рядка в кодах товарів дистрибʼютора. Ручний вибір менеджера запамʼятовується — наступні файли з тими самими кодами розпізнаються автоматично.

4.8. Файл-відповідь

Файл-відповідь — це ваш вихідний файл, до якого для кожного документа додано стан. Формат і кодування — того самого формату.

СтанКоли
ОпрацьованоЗаявку опрацьовано, рядки (товари й кількості) збігаються з файлом.
РедагованоЗаявку опрацьовано, але рядки змінено: кількість, видалено або додано позицію.
ВідхиленоЗаявку відхилено або скасовано.
ПомилкаЗаявку не створено (немає коду точки, помилка створення).

Для документа-дубля (див. 4.9) стан береться з раніше створеної заявки.

  • XML — у кожен <Документ> додається тег <Состояние>. Для «Редаговано» <Строки> приводяться до фактичної заявки: видалені позиції прибираються, Количество змінюється, суми перераховуються, Итоги/ВсегоСтрок оновлюється. Позиції, які менеджер додав, у файл не дописуються. Приклад: examples/order-file-response-example.xml.
  • JSON (UTF-8 з BOM) — у кожен документ додається ключ "Состояние" перед "Товары"; для «Редаговано» масив Товары і СуммаДокумента приводяться до фактичної заявки. Приклад: examples/order-file-response-example.json.
  • CSV (Windows-1251, рядки через CRLF) — до шапки додається колонка Состояние, до кожного рядка — стан його документа; рядки не переписуються. Приклад: examples/order-file-response-example.csv.

4.9. Ідемпотентність і повтори

1. Той самий файл (байт у байт). Якщо такий файл уже приймали, POST повертає 201 з наявним файлом і "duplicate": true; нових заявок немає. Тому повторна відправка після мережевої помилки чи таймауту безпечна. Файл, що раніше отримав failed, при повторі обробляється заново (новий id).

2. Той самий документ у новому файлі. Ключ — пара (ключ документа, дата документа), де ключ документа — Идентификатор/Ссылка, а якщо їх немає — Номер (НомерДокумента, НомерЗамовлення для CSV). Якщо за таким документом уже є заявка (не скасована й не відхилена), нову не створюємо: документ рахується в duplicates_skipped і у файлі-відповіді отримає стан раніше створеної заявки.

  • Виправлений документ надсилайте з новим номером/ідентифікатором або іншою датою. Змінити замовлення повторною відправкою не можна.
  • Тримайте ключ документа не довшим за 64 символи.

Файл, у якому всі документи — дублі, не вважається помилкою: status: "parsed" (а потім completed), orders_created: 0, error: "Нових замовлень немає: усі N документів уже завантажували раніше".

4.10. Помилки й ліміти

HTTPerror.messageКоли
401Bearer API token required / Invalid API token / Token is … / Token has expiredДив. 4.2
403Token scope 'exchange:orders' requiredНемає прав
404File not foundНемає файлу або він чужого токена
409Not all orders of this file are processed yetФайл-відповідь ще не готовий
413File too large (limit 20 MB)Файл понад 20 МБ
422Empty fileПорожнє тіло, або multipart без поля file
422У філії немає активних користувачів для замовлень з імпортуУ дистрибʼютора не налаштовано користувача для заявок з файлів — зверніться до дистрибʼютора
429Rate limit exceeded: N/minПеревищено ліміт токена

Помилки вмісту файлу (не розпізнано, немає точки, не впізнано товар) — це не HTTP-помилки: файл приймається з кодом 201, а проблеми видно в status, error, unmatched_lines і згодом — у стані документів у файлі-відповіді.

ЛімітЗначення
Розмір файлу20 МБ
Запитів на токен100 за 60 с (якщо не погоджено інше); без Retry-After — зачекайте до хвилини
Список файлівостанні 100

4.11. Рекомендований сценарій опитування

  1. POST файл → збережіть id. Якщо duplicate: true — файл уже був, працюйте з поверненим id. Якщо status: "failed" — виправте файл і надішліть знову.
  2. Раз на 5–15 хвилин викликайте GET /exchange/order-files (один запит покриває до 100 файлів) і шукайте файли з response_ready: true, які ви ще не забрали.
  3. Для кожного такого файлу — GET /exchange/order-files/{id}/response, збережіть файл-відповідь, позначте у себе як забраний.
  4. Файли у parsed довше доби — сигнал зʼясувати в менеджера дистрибʼютора (часто це документи «без точки» або з нерозпізнаними товарами).

Опрацювання заявок — ручна робота менеджера, тож файл-відповідь зазвичай зʼявляється за години. Частіше ніж раз на хвилину опитувати немає сенсу.

4.12. Часові пояси

  • Дати у файлі — календарні дати без поясу; час, якщо вказаний, відкидається.
  • Дата документа з файлу не стає датою заявки чи датою доставки: заявка отримує власну дату створення, а ДатаПоставки/ДатаОтгрузки зберігаються довідково.
  • uploaded_at — ISO 8601, UTC.

4.13. Часті питання

Чи можна надіслати кілька документів в одному файлі? Так — кожен стане окремою заявкою.

Файл прийнято (201), але заявок немає. Дивіться status і error: failed — формат не розпізнано; duplicates_skipped > 0 — документи вже завантажували раніше.

Що означає unmatched_lines > 0? Частину товарів не знайдено в каталозі дистрибʼютора. Заявки з ними — чернетки, менеджер добере товари вручну. Щоб уникнути — передавайте штрихкоди й артикули.

Як змінити або скасувати вже надіслане замовлення? Через API — ніяк. Зверніться до менеджера дистрибʼютора.

Файл-відповідь повертає 409 уже кілька днів. Менеджер ще не опрацював усі заявки файлу.

Чи змінюється файл-відповідь після генерації? Ні — вона генерується один раз, коли опрацьовано останню заявку.

Чи можна класти файли на SFTP замість API? Так — див. 5. SFTP.