Каталог с вашими ценами и остатками и, если разрешено, заказы. Полное описание полей и ответов — в файле спецификации openapi.yaml (OpenAPI 3.0, открывается в Swagger Editor, Postman, Insomnia), он приложен к этой инструкции.
1. Быстрый старт
Откройте мини-приложение бота → Профиль → API и создайте токен: имя, срок действия, доступ («только каталог» или «каталог и заказы») и при необходимости канал (склад + валюта, как направления в боте). Раздел виден, только если менеджер включил вам API.
Общий токен — все каналы, которые разрешил менеджер. Узкий — один выбранный канал: витрина и заказы только по этому складу и валюте.
Токен показывается один раз. Сохраните его в секретном хранилище; в репозиторий и клиентский код его класть нельзя. При утечке отзовите токен там же и выпустите новый.
Передавайте токен в каждом запросе: Authorization: Bearer fcp_….
Базовый адрес API: https://api.unimtrn.com/api/partner. API серверное: браузерные запросы (CORS) не поддерживаются, вызывайте его с вашего сервера.
2. Общие правила
Цена — как у вас в боте (тип цены, наценка, валюта из карточки клиента). Цену вы не передаёте никогда: её определяет сервер, в том числе по шкале для количества.
Склады и валюта — из каналов токена (карточка клиента ∩ политика менеджера ∩ выбор при выпуске). Если склад один, параметр warehouse можно не указывать. Узкий токен с одной валютой отдаёт цены только в ней.
Часы работы. У бота есть расписание: он принимает заказы только в рабочие часы. Часы на сегодня можно узнать запросом GET /schedule (он отвечает всегда, в том числе когда бот закрыт); менеджер тоже сообщит их.
Изменения заказа (добавить позицию, изменить количество, убрать строку, отменить заказ) вне рабочих часов не принимаются: ответ 423 bot_closed. Это действует всегда.
Каталог (/catalog, /brands, /categories) вне рабочих часов закрыт только в том случае, если менеджер включил вам соблюдение расписания; тогда он тоже отвечает 423 bot_closed. Если не включил, каталог доступен круглосуточно.
423 bot_closed — не ошибка запроса. Повторите его в рабочее время; при повторе используйте тот же Idempotency-Key: отказ по расписанию не запоминается, и действие выполнится заново.
Если время работы бота на сегодня известно, оно приходит прямо в ответе, в поле error.details: время открытия и закрытия и часовой пояс, в котором оно указано. Если известно только, что бот сейчас не принимает запросы, поля details в ответе нет. Пример:
HTTP 423
{
"error": {
"code": "bot_closed",
"message": "Бот закрыт. Сегодня работает с 10:00 до 18:00 (Asia/Dubai)",
"details": { "opensAt": "10:00", "closesAt": "18:00", "timezone": "Asia/Dubai" }
}
}
Лимиты запросов задаёт менеджер. При превышении — 429 rate_limited: подождите и повторите. Много неверных токенов подряд с одного IP тоже ведут к 429.
Версии в пути нет. Несовместимые изменения оформляются новыми полями и эндпоинтами: игнорируйте неизвестные поля в ответах.
Бот закрыт по расписанию; повторить в рабочее время
429
rate_limited
Замедлиться и повторить
503
order_busy, onec_unavailable
Временный сбой; повторить с тем же Idempotency-Key
4. Каталог
Запрос
Что отдаёт
GET /schedule
Работает ли бот сейчас и часы работы на сегодня
GET /brands
Бренды в наличии
GET /categories?brand=…
Категории бренда
GET /catalog
Позиции с ценами. Фильтры: brand, category, warehouse; страницы: limit (до 1000, по умолчанию 200) и cursor
GET /catalog/{itemCode}
Одна позиция, в том числе шкала цен по количеству (tiers)
Данные витрины обновляются раз в 30–60 секунд, чаще опрашивать смысла нет. Во всех примерах справа базовый адрес уже подставлен; токен передавайте в заголовке Authorization.
Фильтры и пагинация — в Query params у эндпоинта «Список позиций». Названия с пробелами передавайте через --data-urlencode.
GEThttps://api.unimtrn.com/api/partner/schedule
Часы работы на сегодня
Запрос отвечает всегда, в том числе когда бот закрыт. Нужен только действующий токен.
Поле
Значение
open
true, если бот сейчас принимает запросы
timezone
Часовой пояс, в котором указаны часы работы
today.opensAt, today.closesAt
Время открытия и закрытия сегодня в формате ЧЧ:ММ
today
null, если сегодняшних часов нет (выходной) или они не заданы. Тогда ориентируйтесь на open.
Часы на другие дни этим запросом не отдаются.
GEThttps://api.unimtrn.com/api/partner/brands
Бренды
Список брендов, доступных вам на витрине.
GEThttps://api.unimtrn.com/api/partner/categories
Категории бренда
Без brand — 400 bad_request.
Query params
Параметр
Обязательный
Тип
Описание
brand
да
string
Бренд из списка брендов. Регистр не важен
GEThttps://api.unimtrn.com/api/partner/catalog
Список позиций
В списке у позиции одна цена; шкала — только в карточке. nextCursor не null — есть следующая страница. Курсор непрозрачный.
Query params
Параметр
Обязательный
Тип
Описание
brand
нет
string
Фильтр по бренду (одно значение, регистр не важен)
category
нет
string
Фильтр по категории (одно значение). Несколько категорий — отдельные запросы
warehouse
нет
string
Код склада; по умолчанию все ваши склады
limit
нет
integer
Размер страницы: 1–1000, по умолчанию 200
cursor
нет
string
Значение nextCursor из предыдущего ответа. Непрозрачная строка
items — массив. Шкала tiers: «начиная с qty штук цена за штуку — price». Ступени выше доступного остатка скрыты. У уценённых позиций шкалы нет. Если позиции нет или она вам недоступна — 404 not_found.
Остаток приходит в поле available в ответах GET /catalog и GET /catalog/{itemCode}. Отдельного запроса для остатков нет.
Показ остатков включает менеджер. Если он не включён, поля available в ответах нет, а каталог и заказы работают как обычно.
Остатки меняются с каждым заказом. При добавлении в заказ сервер проверяет количество заново: если остатка не хватило, в ответе придут addedQty и capped: true.
Поля позиции каталога
Поле
Что означает
itemCode
Код позиции (передаётся в заказ)
name, brand, category
Название, бренд, категория
warehouse
Код склада
currency, price
Валюта и ваша цена за штуку
available
Остаток. Поля нет, если остатки вам не показываются
tiers
Шкала цен: только в карточке и только если включена
markdown, serial, comment
Уценка: признак, серийный номер, комментарий
warehouseName
Название склада (только если разрешено)
5. Заказы
Доступны, только если менеджер включил вам заказы, а токен выпущен с доступом «каталог и заказы». Заказ — тот же документ, что корзина в боте и мини-приложении.
Запрос
Действие
POST /orders/lines
Добавить позицию в заказ
GET /orders/current
Открытый заказ в текущей торговой сессии
GET /orders, GET /orders/{id}
История и один заказ со статусом
PATCH /orders/{id}/lines/{lineId}
Изменить количество строки
DELETE /orders/{id}/lines/{lineId}
Убрать строку
POST /orders/{id}/cancel
Отменить заказ
Отдельные действия (изменить количество, убрать строку, отменить) менеджер может отключить — тогда API ответит 403 forbidden.
Если остатка или лимита «в одни руки» хватило не на всё: "capped": true и фактическое addedQty. Если не добавить ничего — 422 order_rejected. Та же позиция, серия и цена — количество суммируется; иначе новая строка. Успех всегда 200; created — создан ли новый заказ.
Headers
Заголовок
Обязательный
Описание
Authorization
да
Bearer <токен>
Idempotency-Key
да
Уникальный ключ действия (8–128 символов A-Za-z0-9_.:-). Повтор — тот же ключ
Content-Type
да
application/json
Body (JSON)
Поле
Обязательное
Тип
Описание
itemCode
да
string
Код позиции из каталога
qty
да
integer
Количество, целое ≥ 1. Для уценки с serial — только 1
warehouse
условно
string
Код склада. Обязателен, если складов несколько; иначе берётся единственный
serial
условно
string
Серийный номер. Обязателен для уценённой позиции
Цену в теле передавать нельзя — её считает сервер.
Цена пересчитывается по шкале, поэтому lineId может смениться. При нехватке остатка — "capped": true. Серийные строки менять нельзя — 422 serial_line_qty_fixed.
Headers
Заголовок
Обязательный
Описание
Authorization
да
Bearer <токен>
Idempotency-Key
да
Уникальный ключ действия (8–128 символов A-Za-z0-9_.:-). Повтор — тот же ключ
Content-Type
да
application/json
Path params
Параметр
Обязательный
Тип
Описание
order_id
да
string
Id текущего заказа
line_id
да
string
Id строки из ответа API (не придумывайте сами)
Body (JSON)
Поле
Обязательное
Тип
Описание
qty
да
integer
Новое количество строки, целое ≥ 1. Чтобы убрать строку — DELETE
HTTP 403
{ "error": { "code": "forbidden", "message": "Удаление строк заказа через API отключено для этого клиента" } }
Числа, коды товаров, цены и идентификаторы в примерах условные.
6. Отгрузки
Накладные (расходные) по вашим заказам. Доступны, если менеджер включил вам заказы. Список — только заказы с номером накладной (deliveryNumber).
Запрос
Что отдаёт
GET /shipments
Список отгрузок (страницы: limit до 100, cursor)
GET /shipments/{deliveryNumber}
Накладная по номеру: JSON (по умолчанию) или PDF (format=pdf)
GET /orders/{id}/shipment
Та же накладная, но по id заказа
В JSON у позиций есть price/sum (цена клиента из заказа) и serials — серийные номера из накладной. Общая сумма — поле total. Если накладной нет или она недоступна — 404 / 422 shipment_unavailable.
GEThttps://api.unimtrn.com/api/partner/shipments
Список отгрузок
Только заказы с номером накладной. Листается через nextCursor.
Это исходящие уведомления: мы шлём POST на ваш HTTPS URL, когда статус заказа меняется. Это не эндпоинт Partner API — URL задаётся в политике (менеджер в админке или вы в миниаппе → Профиль → API, если самовыпуск разрешён).
Уведомления идут по всем заказам клиента (бот, миниприложение, API), кроме тестовых и реферальных. Повтор того же статуса по одному заказу не отправляется.
Зачем. Если ответ не получен, повтор «вслепую» опасен. Ключ гарантирует: повтор с тем же ключом вернёт ответ первого запроса, а не выполнит действие дважды.
Где нужен. Все изменяющие запросы заказов: POST /orders/lines, PATCH, DELETE, POST …/cancel. Без него — 400 idempotency_key_required. Для GET не нужен.
Кто создаёт. Ваша система, перед запросом (например UUID v4). Новое действие — новый ключ. Сохраните ключ до получения ответа.
KEY=$(uuidgen)
curl -sS -X PATCH "https://api.unimtrn.com/api/partner/orders/$ORDER/lines/$LINE" \
-H "Authorization: Bearer $FC_TOKEN" \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"qty": 5}'
# ответ не получен — повтор с тем же $KEY
# → 200 и заголовок Idempotent-Replay: true
Один ключ — одно действие. 8–128 символов: A-Za-z0-9_.:-.
Тот же ключ с другим запросом — 422 idempotency_key_reused.
Пока первый запрос выполняется — 409 request_in_progress; подождите и повторите.
Бизнес-отказы (409, 422) запоминаются. Временные (423, 429, 503) — нет.
9. Частые вопросы
403 api_disabled / orders_disabled. API или заказы не включены вам менеджером.
422 order_rejected. Нет остатка, исчерпана квота или позиция недоступна — причина в message.
422 onec_error. Учётная система не приняла изменение. Обратитесь к менеджеру, если повторяется.
Токен перестал работать. Проверьте срок и отзыв в Профиль → API; код ошибки 401 говорит, что именно произошло.