API Auritech B2B

v1 https://b2b-api.auritech.ru/v1

Быстрый старт

Каталог и заказы по HTTP. Аутентификация — по ключу.

  1. Откройте b2b.auritech.ru, раздел API.
  2. Нажмите «Выпустить ключ». Ключ показывается один раз.
  3. Передавайте его в заголовке каждого запроса.
curl -H "Authorization: Bearer b2b_xxxxxxxx_…" \
     https://b2b-api.auritech.ru/v1/catalog?limit=5

Аутентификация

Ключ передаётся одним из двух заголовков — они равнозначны:

Authorization: Bearer b2b_xxxxxxxx_…
X-Api-Key: b2b_xxxxxxxx_…

Ключ обязателен для всех методов. Запрос без ключа или с недействительным ключом — 401.

У ключа есть области доступа: catalog:read, orders:read, orders:write, imei:read, imei:write, finance:read. Области выбираются при выпуске ключа в кабинете (раздел API) — отметьте только то, что нужно вашему сервису. Выдать ключу можно лишь те области, к которым есть доступ у сотрудника, выпускающего ключ. Обращение к методу вне выданных областей — 403.

Подписка

API — платный модуль с помесячной оплатой; подключается владельцем компании в личном кабинете (вкладка «Интеграции», раздел API). Без активной подписки все методы, кроме /health, отвечают 402 subscription_required, а вебхуки не отправляются. Ключи, адрес и секрет вебхука при этом сохраняются: подключите подписку снова — они заработают сразу, выпускать заново ничего не нужно. Каталог и заказы в самом кабинете подписки не требуют.

Ограничения

60 запросов в минуту на ключ. В каждом ответе:

ЗаголовокЗначение
X-RateLimit-Limitлимит запросов в минуту
X-RateLimit-Remainingостаток в текущей минуте
Retry-Afterсекунд до сброса лимита (при 429)

Формат данных

ПолеТипЗначение
priceintegerцена в копейках
totalintegerсумма в копейках
qtyintegerколичество, штук
createdAtstringдата и время, ISO 8601, UTC
skustringартикул, уникален в каталоге
Денежные поля — целые числа в копейках. 5200000 — это 52 000 ₽. Дробных значений в ответах не бывает; чтобы получить рубли, разделите на 100.

price: null — цена не установлена. Запросить её можно в личном кабинете.

Ответы в UTF-8. Списки постраничные: параметры page (с нуля) и limit, в ответе total.

Проверка доступности

GET/v1/health

Работает без ключа — так удобно проверить связь до его получения:

{ "ok": true, "service": "b2b-api", "version": 1 }

С ключом в заголовке Authorization ответ дополняется блоком key — рабочий ли ключ:

{ "ok": true, "service": "b2b-api", "version": 1,
  "key": { "valid": true, "works": true, "message": "Ключ рабочий",
           "scopes": ["catalog:read", "orders:read"], "rateLimitPerMinute": 60,
           "subscription": { "active": true, "paidUntil": "2026-10-26T00:00:00.000Z", "autoRenew": true } } }

valid: false — ключ неверный, отозван или его автор больше не в компании. works: false при верном ключе — не подключён модуль API.

Каталог

GET/v1/catalog

Область catalog:read.

ПараметрТипПо умолчаниюЗначение
limitinteger500размер страницы, максимум 1000
pageinteger0номер страницы
priced0 / 111 — только позиции с ценой, 0 — весь каталог

Сортировка по sku, порядок стабильный. model — модель без памяти и размера («iPhone 15»), variant — вариант внутри модели («128GB», «46mm»); у товаров без вариантов — пустая строка.

Если у модели есть исполнения (SIM, прошивка, вилка, раскладка), это отдельные позиции со своим sku, исполнение указано в названии: «iPhone 15 128GB Black (eSIM)».

curl -H "X-Api-Key: $KEY" \
  "https://b2b-api.auritech.ru/v1/catalog?limit=2"

{
  "total": 1061,
  "page": 0,
  "limit": 2,
  "items": [
    {
      "sku": "ip15-128black-esim",
      "brand": "Apple",
      "category": "Смартфоны",
      "model": "iPhone 15",
      "variant": "128GB",
      "name": "iPhone 15 128GB Black (eSIM)",
      "price": 5160000
    },
    {
      "sku": "ip15-128black-simesim",
      "brand": "Apple",
      "category": "Смартфоны",
      "model": "iPhone 15",
      "variant": "128GB",
      "name": "iPhone 15 128GB Black (SIM + eSIM)",
      "price": 5260000
    }
  ]
}

Уценка

GET/v1/catalog/used

Область catalog:read. Тот же товар, но не новый: активирован, восстановлен, повреждена упаковка и т. п. /v1/catalog отдаёт только новые товары. Позиция уценки — артикул и состояние: у одного артикула может быть несколько предложений с разным состоянием. conditions — метки состояния списком. Цена — ваша, в копейках.

ПараметрТипПо умолчаниюЗначение
limitinteger500размер страницы, максимум 1000
pageinteger0номер страницы
curl -H "X-Api-Key: $KEY" \
  "https://b2b-api.auritech.ru/v1/catalog/used?limit=1"

{
  "total": 214,
  "page": 0,
  "limit": 1,
  "items": [
    {
      "sku": "ip15-128black-esim",
      "brand": "Apple",
      "category": "Смартфоны",
      "model": "iPhone 15",
      "variant": "128GB",
      "name": "iPhone 15 128GB Black (eSIM)",
      "conditions": ["Активирован", "Повреждена упаковка"],
      "price": 4780000
    }
  ]
}

Выгодно

GET/v1/catalog/deals

Область catalog:read. Позиции дневной подборки «Выгодные позиции!» (её же получают в Telegram и видят во вкладке «Выгодно!» кабинета): товары, подешевевшие со вчерашнего дня. price — ваша цена сейчас, was — вчерашняя цена, в копейках. Только то, что подешевело хотя бы на 0,5 %; подорожавшее с утра из списка уходит. date — день подборки (обновляется в 12:00 по Москве). Список небольшой — целиком, самые сильные снижения первыми.

{
  "date": "2026-10-09",
  "total": 1,
  "items": [
    { "sku": "airpods4-anc", "brand": "Apple", "category": "Наушники", "model": "AirPods 4",
      "variant": "ANC", "name": "AirPods 4 ANC",
      "price": 1450000, "was": 1590000 }
  ]
}

Заказы

GET/v1/orders

Область orders:read. Сортировка по дате создания, новые первыми.

ПараметрТипПо умолчаниюЗначение
limitinteger100размер страницы, максимум 200
pageinteger0номер страницы
{
  "total": 4,
  "page": 0,
  "limit": 100,
  "orders": [
    {
      "number": "TG000004",
      "status": "new",
      "total": 22100000,
      "comment": "",
      "createdAt": "2026-08-31T15:19:42.117Z",
      "items": [
        { "sku": "airpodsmax2-orange", "conditions": [], "name": "AirPods Max 2 Orange",
          "price": 3880000, "qty": 5,
          "extra": [ { "id": "engraving", "name": "Гравировка", "price": 100000, "qty": 2 } ] },
        { "sku": "ip15-128black-esim", "conditions": ["Активирован", "Повреждена упаковка"],
          "name": "iPhone 15 128GB Black (eSIM) — уценка: Активирован, Повреждена упаковка",
          "price": 2500000, "qty": 1, "extra": [] }
      ],
      "paidFrom": null,
      "paid": { "bonus": 0, "money": 0 }
    }
  ]
}
statusЗначение
newНовый — ждёт проверки менеджером
approvedУтверждён — ждёт оплаты клиентом
processСобирается (оплатить можно и позже, до завершения)
readyСобран
shippedОтгружен
finishedЗавершён
cancelledОтменён

price в позиции заказа — цена, по которой заказ оформлен. conditions — состояние уценённого товара списком, как в /v1/catalog/used; у нового товара — пустой массив. paidFrom и paid — как оплачен заказ (см. POST /v1/orders). extra — допы к позиции, которые менеджер добавил при согласовании заказа: услуги (перепак, гравировка) и сопутствующие товары (переходник). У допа своя цена price в копейках за штуку и своё количество qty: например, товара 5 шт., а гравировка — на 2 из них. Сумма позиции — price × qty + Σ цена допа × его количество; total заказа их уже включает. Нет допов — пустой массив.

POST/v1/orders

Область orders:write. Оформляет заказ сразу составом — корзины в API нет, она нужна человеку в кабинете. Позиция — {sku, qty}, для уценки — {sku, qty, conditions} с conditions из /v1/catalog/used; одинаковые позиции складываются, до 500 позиций. Цены — те же, что отдают /v1/catalog и /v1/catalog/used на момент запроса. Позиции без цены в заказ не попадают и возвращаются в badSkus; если таких все — 400. Деньги при оформлении не списываются: менеджер проверяет заказ и утверждает его (status: approved), после чего заказ оплачивается вызовом POST /v1/orders/{number}/pay или клиентом в кабинете. О смене статуса приходит вебхук order.status_changed. В ответах paidFrom (bonus, balance, cash — оплачен наличными у менеджера, mixed или null, пока не оплачен) и paid — сколько списано с каждой кассы, в копейках; наличные по балансу проходят пополнением и тут же списанием под заказ, поэтому входят в money.

POST /v1/orders
Idempotency-Key: erp-order-1042
{ "items": [ { "sku": "ip15-128black-simesim", "qty": 2 },
             { "sku": "ip15-128black-esim", "qty": 1, "conditions": ["Активирован"] } ],
  "comment": "склад №2" }

201
{
  "number": "TG000012",
  "items": [ { "sku": "ip15-128black-simesim", "conditions": [], "name": "iPhone 15 128GB Black (SIM + eSIM)",
               "price": 5260000, "qty": 2 },
             { "sku": "ip15-128black-esim", "conditions": ["Активирован"],
               "name": "iPhone 15 128GB Black (eSIM) — уценка: Активирован", "price": 4780000, "qty": 1 } ],
  "paidFrom": null, "paid": { "bonus": 0, "money": 0 }
}

Повтор без второго заказа. Передайте заголовок Idempotency-Key — свой номер заказа или любую уникальную строку (1–100 печатных символов ASCII). Если связь оборвалась и вы повторили запрос с тем же ключом, второй заказ не создаётся: ответ 200 с тем же number и "replayed": true. Пока первый запрос ещё выполняется — 409 in_progress, повторите через несколько секунд. Отклонённый заказ (например, ни на одну позицию нет цены) ключ не занимает. Ключ хранится 7 дней и действует только в вашей компании.

Время работы. Если для заказов задано время работы, вне его заказ не принимается: ответ 409 closed с текстом и часами — { "error": "closed", "message": "Время работы с 10:00 до 19:00 (МСК) — сейчас оформить заказ нельзя", "hours": { "from": "10:00", "to": "19:00", "timezone": "Europe/Moscow" } }. Ключ Idempotency-Key такой ответ не занимает — повторите заказ в рабочее время.

Если время работы задано, но ограничение выключено, заказ вне него принимается, а в ответе есть поле notice — когда заказ соберут; цены в таком заказе пересчитываются на актуальные в рабочее время, итог придёт с утверждением заказа. Например: "Заказы, оформленные после 19:00, собираются на следующий день в рабочее время каталога. Цены в заказе будут пересчитаны на актуальные в рабочее время. Время работы: с 10:00 до 19:00 (МСК)".

GET/v1/orders/{number}

Область orders:read. Состав, статус и состояние согласования. review.state = awaiting_client означает, что менеджер изменил заказ при сборке и ждёт вашего ответа — без него заказ не соберут.

{ "order": {
    "number": "TG000012", "status": "process", "total": 10520000,
    "comment": "склад №2", "createdAt": "2026-10-12T09:14:03.511Z",
    "items": [
      { "sku": "ip15-128black-simesim", "conditions": [], "name": "iPhone 15 128GB Black (SIM + eSIM)",
        "price": 2870000, "qty": 2,
        "extra": [ { "id": "repack", "name": "Перепак", "price": 60000, "qty": 2 } ] },
      { "sku": "ip15-128black-esim", "conditions": ["Активирован"],
        "name": "iPhone 15 128GB Black (eSIM) — уценка: Активирован", "price": 4780000, "qty": 1, "extra": [] } ],
    "paidFrom": "mixed", "paid": { "bonus": 300000, "money": 10220000 },
    "review": { "state": "awaiting_client", "at": "2026-10-12T11:02:44.020Z" } } }

Поля позиций — как в GET /v1/orders. review — null, если менеджер заказ не правил.

POST/v1/orders/{number}/review

Область orders:write. Ответ на правки менеджера: { "decision": "approve" } — одобрить, { "decision": "cancel" } — отменить заказ (деньги возвращаются). Если правок, ожидающих ответа, нет — 409.

200
{ "ok": true, "number": "TG000012", "status": "approved" }

status — статус заказа после ответа: при отмене — cancelled.

POST/v1/orders/{number}/pay

Область orders:write. Оплата утверждённого заказа, оплата позже — пока заказ собирается, собран или отгружен, — или доплата разницы после одобренных правок: сначала бонусы, которым разрешены товары, остаток — с баланса, в пределах кредитного лимита, если он есть. Оплата утверждённого заказа переводит его в process, в остальных статусах статус не меняется. Завершается заказ только оплаченным. Не хватает средств — 402 insufficient_funds, ничего не списывается и заказ не меняется; пока заказ не утверждён или ждёт вашего ответа на правки — 409.

200
{ "ok": true, "number": "TG000012", "status": "process",
  "paidFrom": "mixed", "paid": { "bonus": 300000, "money": 10220000 }, "amount": 10520000 }

Проверки IMEI

Идентификаторы услуг — наши и постоянные: какой бы сервис проверок ни работал на нашей стороне, id не меняется. Зашивайте нужные id из таблицы ниже. Если проверка временно недоступна, в списке у неё available: false, а запуск отвечает 409 unavailable.

GET/v1/imei/services

Область imei:read. Услуги с ценами (в копейках), доступные — по возрастанию цены, недоступные — в конце с price: null. У большинства есть description — что проверяется и ограничения (только IMEI, только Apple и т.п.).

{ "services": [
  { "id": "brand-model", "title": "Бренд и модель по IMEI", "price": 200, "available": true },
  { "id": "fmi", "title": "Find My (Локатор): включён или выключен", "price": 200,
    "available": true, "description": "Включён ли «Локатор» (Find My) на iPhone или iPad…" }
] }
idУслуга
brand-modelБренд и модель по IMEI
model-lookupМодель по IMEI или серийному номеру (все бренды)
fmiFind My (Локатор): включён или выключен
icloud-statusСтатус iCloud: чистый или потерян
blacklistЧёрный список GSMA
blacklist-proЧёрный список GSMA с историей
carrier-simlockОператор и SIM-lock (Apple)
simlockSIM-lock Apple (только IMEI)
warrantyГарантия, активация и замена (Apple)
warranty-snГарантия и активация по серийному номеру (Apple)
warranty-proГарантия Pro и активация (Apple)
apple-basicApple: базовая информация (PRO)
apple-fullApple: полная информация с оператором
apple-full-mdmApple: полная информация с оператором, MDM и Chimaera
apple-full-nocarrierApple: полная информация без оператора
apple-ultimateApple ULTIMATE: продавец, Chimaera, MDM, чёрный список
apple-customApple: расширенная информация с оператором (V2)
mdmMDM (корпоративная блокировка), Find My и описание модели
sold-by-gsxПродавец Apple и данные GSX
sold-byПродавец Apple (без GSX)
model-color-storageМодель, цвет, память и Find My (Apple)
model-descriptionОписание модели: модель, цвет, память (Apple)
model-description-mpnОписание модели, партномер и Find My (Apple)
replacement-activeСтатус замены: активное устройство (Apple)
replaced-originalСтатус замены: исходное устройство (Apple)
imac-fmiFind My на iMac и MacBook по серийному номеру
imei-to-snIMEI в серийный номер (Apple)
imei-pairIMEI1 и IMEI2 устройства Apple
eidEID по IMEI
serial-infoИнформация по серийному номеру Apple
demo-unitДемо-устройство Apple
chimaeraChimaera: внутренний чёрный список Apple
gsx-activationGSX: дата активации, Next Tether, последнее восстановление
verizon-esnVerizon (США): ESN чистый или потерян
tmobile-esnT-Mobile (США): проверка ESN
samsungSamsung: информация
samsung-knoxSamsung: информация и Knox Guard
samsung-knox-s2Samsung: информация и Knox Guard (сервер 2)
samsung-blacklistSamsung: информация и чёрный список
huaweiHuawei: информация
xiaomiXiaomi: Mi-блокировка и информация
oneplusOnePlus: информация
motorolaMotorola: информация
honorHonor: информация
pixelGoogle Pixel: информация и гарантия
POST/v1/imei/checks

Область imei:write. Одна проверка: { "imei": "356938035643809", "serviceId": "brand-model" }. Номер — 8–17 букв и цифр (IMEI или серийный номер, если услуга его принимает). Списание происходит до запроса: сначала бонусы (если им разрешены проверки), остаток — с баланса; в ответе paidFrom и paid — чем и на сколько оплачено. Если сервис не смог проверить номер (status: failed), деньги возвращаются автоматически.

201
{ "id": 318, "status": "done", "price": 200,
  "paidFrom": "balance", "paid": { "bonus": 0, "money": 200 },
  "result": { "imei": "356938035643809", "status": "success",
              "object": { "brand": "Apple Inc", "model": "Apple iPhone 17 Pro Max (A3526)",
                          "name": "iPhone 17 Pro Max (A3526)" },
              "result": "IMEI: 356938035643809<br>Brand: Apple Inc<br>…" } }

status: done — результат в result; pending — сервис ещё работает, опрашивайте GET /v1/imei/checks/{id} или подключите вебхук; failed — проверить не удалось, деньги возвращены. Поле result.result — готовый текст для показа, строки разделены <br>; result.object — структурные поля, набор зависит от услуги.

POST/v1/imei/checks/bulk

Область imei:write. До 100 номеров одной услугой: { "imeis": [ … ], "serviceId": "brand-model" }. Списание за каждый номер — сразу, сами проверки выполняются в фоне; результаты забирайте по id или получайте вебхуком. Повторы и мусор отклоняются с причиной (duplicate, bad_format), при нехватке средств остаток — payment_failed.

201
{ "accepted": [ { "id": 319, "imei": "355948398738346" } ],
  "rejected": [ { "imei": "35594", "reason": "bad_format" } ],
  "price": 200 }
GET/v1/imei/checks/{id}

Область imei:read. Одна проверка; незавершённая дотягивается у сервиса прямо в этом запросе.

{ "check": {
    "id": 318, "imei": "356938035643809", "serviceId": "brand-model", "service": "Бренд и модель по IMEI",
    "price": 200, "paidFrom": "bonus", "paid": { "bonus": 200, "money": 0 },
    "status": "done",
    "result": { "imei": "356938035643809", "status": "success",
                "object": { "brand": "Apple Inc", "model": "Apple iPhone 17 Pro Max (A3526)", "name": "iPhone 17 Pro Max (A3526)" },
                "result": "IMEI: 356938035643809<br>Brand: Apple Inc<br>…" },
    "createdAt": "2026-10-12T08:40:11.302Z" } }

status: done, pending, failed (деньги возвращены). У незавершённой проверки result — null.

GET/v1/imei/checks

Область imei:read. Список проверок компании, новые первыми, постранично: limit (по умолчанию 100, максимум 200), page. Поля проверки — как в GET /v1/imei/checks/{id}.

{ "page": 0, "limit": 100,
  "checks": [
    { "id": 318, "imei": "356938035643809", "serviceId": "brand-model", "service": "Бренд и модель по IMEI",
      "price": 200, "status": "done", "paidFrom": "bonus", "paid": { "bonus": 200, "money": 0 },
      "result": { "imei": "356938035643809", "status": "success", "object": { … }, "result": "…" },
      "createdAt": "2026-10-12T08:40:11.302Z" } ] }

Финансы

Область finance:read. Только чтение — пополнения и бонусы проводятся через кабинет.

GET/v1/finance
{ "balance": 1250000, "available": 3250000,
  "creditLimit": 2000000,
  "bonus": 50000, "bonusByPurpose": { "orders": 50000, "imei": 5000, "subscriptions": 0 },
  "bonusScopes": ["orders", "imei"] }

available — баланс плюс кредитный лимит (на сколько баланс может уйти в минус; задаёт администратор). Бонусы начисляются отдельными начислениями, у каждого свои назначения: bonusByPurpose — сколько сейчас можно потратить на orders (товары), imei (проверки IMEI), subscriptions (подписки); одно начисление может входить в несколько назначений. bonusScopes — назначения, на которые есть что тратить.

GET/v1/finance/operations

Выписка по балансу, новые первыми, постранично: limit (по умолчанию 100, максимум 300), page. kind — deposit (пополнение), charge (списание), refund (возврат), adjustment (исправление); amount со знаком: списание — минус; balanceAfter — баланс после операции; orderNumber — заказ, если операция по заказу.

{ "page": 0, "limit": 100,
  "operations": [
    { "kind": "charge", "amount": -10220000, "balanceAfter": 1250000,
      "title": "Оплата заказа TG000012 — остаток 102 200 ₽ после бонусов 3 000 ₽", "orderNumber": "TG000012",
      "at": "2026-10-12T09:20:15.004Z" },
    { "kind": "deposit", "amount": 11470000, "balanceAfter": 11470000,
      "title": "Пополнение: перевод", "orderNumber": null, "at": "2026-10-11T16:05:40.118Z" } ] }
GET/v1/finance/bonus-operations

Те же поля по бонусам плюс grantId — начисление, к которому относится операция: kind — grant (начисление), spend (оплата), refund (возврат в то же начисление), revoke (начисление отозвано или его остаток обнулён администратором). balanceAfter — бонусов после операции (у старых операций может быть null).

{ "page": 0, "limit": 100,
  "operations": [
    { "kind": "spend", "amount": -300000, "balanceAfter": 200000,
      "title": "Оплата заказа TG000012 — часть бонусами 3 000 ₽ (из 105 200 ₽)", "orderNumber": "TG000012",
      "grantId": 7, "at": "2026-10-12T09:20:15.004Z" },
    { "kind": "grant", "amount": 500000, "balanceAfter": 500000,
      "title": "Начисление бонусов", "orderNumber": null, "grantId": 7, "at": "2026-10-10T12:00:00.000Z" } ] }

Порядок оплаты один для заказов, проверок и подписок: сначала бонусы (если назначение разрешает), остаток — с баланса, в пределах кредитного лимита, если он есть. Смешанная оплата видна как две операции с одним orderNumber: бонусная часть в /v1/finance/bonus-operations, денежная — в /v1/finance/operations; подписи операций называют обе части. Возврат идёт в ту же кассу, откуда списано.

Всё из кабинета

Остальная работа компании в личном кабинете доступна и через API — теми же правилами и с теми же проверками прав. Запрос выполняется от имени автора ключа с его текущими правами: урезали сотруднику права — ключ сузился; сотрудника заблокировали — ключ не работает. Ответы в формате кабинета: ошибка — { "error": "текст" }, деньги — в копейках (…Kopecks).

Открыто то, что нужно программе. Чего в API нет намеренно: корзины (заказ создаётся сразу составом — POST /v1/orders), счётчиков для значков меню, экрана каталога с фильтрами (программе отдаётся весь каталог /v1/catalog, «Выгодно!» — /v1/catalog/deals), файлов Excel для ручной правки и выгрузки прайса файлом, дублей родных методов, сотрудников с приглашениями и чата с менеджером — это работа человека в кабинете и в Telegram.

МетодОбластьЧто делает
GET /v1/meлюбаякто автор ключа, компания, права и доступные области
PATCH /v1/orders/{number} {items: [{sku, qty, conditions}]}orders:writeизменить состав заказа целиком (цену меняет только менеджер); правка уходит менеджеру
POST /v1/orders/{number}/status {status: "cancelled"}orders:writeотменить заказ, пока он в статусе new
GET /v1/orders/{number}/commentsorders:readкомментарии к заказу лентой: первый — при оформлении, дальше клиент и менеджер (side: client/staff, author, text, at)
POST /v1/orders/{number}/comments {text}orders:writeдобавить комментарий (до 1000 символов), только пока заказ можно изменить или клиент отвечает на правки менеджера; прежние не меняются. Комментарий можно передать и полем comment в PATCH /v1/orders/{number}
GET /v1/orders/{number}/export.xlsx (.pdf)orders:readзаказ файлом
GET /v1/price-requestsprices:readзапросы цены и ответы менеджера
POST /v1/price-requests {sku, qty}prices:writeзапросить цену позиции без прайса
POST /v1/imei/checks/{id}/refreshimei:writeперечитать результат проверки
GET /v1/bonusfinance:readбонусы: начисления с назначениями и остатками (движение — /v1/finance/bonus-operations)
POST /v1/finance/topups {amountRub}finance:writeзаявка на пополнение баланса
GET /v1/subscriptionsfinance:readплатные модули компании
POST /v1/subscriptions/{module}/activate, /auto-renewfinance:writeподключить модуль, автопродление
GET/PUT /v1/webhook, POST /v1/webhook/testwebhooks:writeвебхук компании — ключ владельца
/v1/integrations/avito…integrations:read / integrations:writeинтеграция с Авито — подключение, связки (по одной и пачкой), синхронизация, заказы; связки файлом Excel — только в кабинете

Примеры ответов

GET/v1/me
{ "id": 12, "name": "Иван Петров", "firstName": "Иван", "phone": "+79001112233",
  "role": "client", "isOwner": true,
  "permissions": { "catalog": "read", "orders": "write", "prices": "write", "finance": "write", "imei": "write", "api": "write" },
  "modules": { "catalog": "Каталог и цены", "orders": "Заказы", "prices": "Запросы цен",
               "finance": "Финансы и бонусы", "imei": "Проверки IMEI", "api": "Интеграции и API" },
  "apiScopes": ["catalog:read", "orders:read", "orders:write", "prices:read", "prices:write", "imei:read", "imei:write",
                "finance:read", "finance:write", "integrations:read", "integrations:write", "webhooks:write"],
  "bonusPurposes": { "orders": "товары", "imei": "проверки IMEI", "subscriptions": "подписки" },
  "company": { "id": 5, "name": "ООО Ромашка", "balanceKopecks": 1250000, "creditLimitKopecks": 2000000,
               "availableKopecks": 3250000, "bonusKopecks": 200000 } }

permissions — права автора ключа по разделам (none, read, write), apiScopes — области, которые он может выдать ключу. Без права «Финансы» вместо денег в company — "moneyHidden": true.

PATCH/v1/orders/{number}
{ "items": [ { "sku": "ip15-128black-simesim", "qty": 3 },
             { "sku": "ip15-128black-esim", "qty": 1, "conditions": ["Активирован"] } ],
  "comment": "добавьте одну позицию" }

200
{ "ok": true,
  "changes": [ { "kind": "changed", "sku": "ip15-128black-simesim", "name": "iPhone 15 128GB Black (SIM + eSIM)",
                 "was": { "qty": 2, "priceKopecks": 2870000, "conditions": [], "extra": [] },
                 "now": { "qty": 3, "priceKopecks": 2870000, "conditions": [], "extra": [] } } ],
  "settlement": null }

Состав передаётся целиком: позиции, которых нет в запросе, удаляются. changes — что изменилось (kind: added, removed, changed — количество, цена или допы), was/now — позиция до и после (null у добавленной и удалённой). settlement — перерасчёт оплаченного заказа: доплата или возврат, иначе null.

POST/v1/orders/{number}/status
{ "status": "cancelled" }

200
{ "ok": true }
GET/v1/orders/{number}/comments
{ "comments": [
    { "id": 41, "side": "client", "author": "Иван Петров", "text": "склад №2",
      "at": "2026-10-12T09:14:03.511Z", "initial": true, "mine": true },
    { "id": 44, "side": "staff", "author": "Менеджер", "text": "Отгрузим завтра",
      "at": "2026-10-12T10:01:12.090Z", "initial": false, "mine": false } ] }

initial — комментарий при оформлении заказа, mine — оставлен от имени автора ключа. POST с { "text": "…" } отвечает { "ok": true, "comments": [ … ] } — лента целиком.

GET/v1/price-requests
{ "requests": [
    { "id": 77, "sku": "dyson-hs09-long-amber", "name": "Dyson HS09 Long Amber Silk", "qty": 2, "comment": "",
      "status": "answered", "answerKopecks": 4590000, "answerComment": "Цена на 3 дня",
      "createdAt": "2026-10-11T12:30:00.000Z", "answeredAt": "2026-10-11T13:02:10.000Z",
      "expiresAt": "2026-10-14T13:02:10.000Z", "revokedAt": null, "quoteActive": true,
      "companyName": "ООО Ромашка", "userName": "Иван Петров" } ] }

status — open (ждёт ответа) или answered; answerKopecks — цена ответа, действует до expiresAt (quoteActive), пока менеджер её не отозвал (revokedAt). POST с { "sku": "…", "qty": 2, "comment": "…" } (комментарий — по желанию) отвечает { "ok": true, "id": 78 }; если такой запрос уже ждёт ответа — тот же id и "alreadyOpen": true.

POST/v1/imei/checks/{id}/refresh
{ "ok": true, "status": "done", "result": { "imei": "356938035643809", "status": "success", "object": { … }, "result": "…" } }

Если незавершённая проверка не удалась — "status": "failed" и "refunded": true: деньги возвращены.

GET/v1/bonus
{ "bonusKopecks": 200000, "byPurpose": { "orders": 200000, "imei": 200000, "subscriptions": 0 },
  "text": "товары 2 000 ₽, проверки IMEI 2 000 ₽",
  "grants": [
    { "id": 7, "amountKopecks": 500000, "leftKopecks": 200000, "spentKopecks": 300000,
      "purposes": ["orders", "imei"], "purposesText": "товары, проверки IMEI", "title": "Начисление бонусов",
      "createdAt": "2026-10-10T12:00:00.000Z", "closedAt": null, "closedKind": null, "author": null, "untouched": false } ] }

Начисление — amountKopecks, из него потрачено spentKopecks, осталось leftKopecks; purposes — на что можно тратить; untouched — из него ещё ничего не тратили. В списке — начисления с остатком. text — остаток по назначениям строкой для показа.

POST/v1/finance/topups
{ "amountRub": 50000, "comment": "перевод по счёту 118" }

200
{ "ok": true, "id": 31 }

Заявка уходит менеджеру; после подтверждения сумма приходит на баланс (операция deposit в выписке).

GET/v1/subscriptions
{ "modules": [
    { "module": "avito", "title": "Интеграция с Авито", "group": "marketplaces", "priceKopecks": 1000000,
      "autoRenew": true, "paidUntil": "2026-11-10T00:00:00.000Z", "paidFrom": "balance",
      "paid": { "bonusKopecks": 0, "moneyKopecks": 1000000 }, "active": true } ],
  "canManage": true }

paidUntil — до какого времени модуль оплачен, autoRenew — продлевать ли автоматически. POST /v1/subscriptions/{module}/activate и /auto-renew ({ "on": false }) отвечают { "ok": true, "state": { … } } — модуль в том же виде, что в списке.

GET/v1/webhook
{ "url": "https://erp.example.ru/hooks/b2b", "enabled": true, "secret": "kQ3x…",
  "lastOkAt": "2026-10-12T09:20:16.000Z", "lastError": null }

PUT /v1/webhook с { "url": "https://…", "enabled": true } отвечает { "ok": true, "url": "…", "enabled": true, "secret": "…" }. secret — секрет подписи (см. Вебхуки); виден, только если автор ключа — владелец компании, иначе null. POST /v1/webhook/test отправляет пробное событие: { "ok": true, "message": "…" }, результат — в lastOkAt/lastError.

Авито

Интеграция с Авито работает по подписке «Интеграция с Авито» (см. /v1/subscriptions). Чтение — integrations:read, изменения — integrations:write.

МетодОтвет
GET /v1/integrations/avitoconnected, accountName, avitoUserId, clientId, enabled, settings (syncMinutes, syncPrices, syncStocks, defaultStockQty, autoOrder: enabled, minAgeMin, times — время по Москве "ЧЧ:ММ", до 12 в сутки), lastSyncAt, lastError, subscription (как в /v1/subscriptions), warehouseHours (from, to) — часы работы склада по Москве: время автозаказа ставится внутри них, время вне прижимается к границе
PUT /v1/integrations/avito/connect {clientId, clientSecret}ok, accountName, avitoUserId
DELETE /v1/integrations/avitook — отключить
PATCH /v1/integrations/avito/settings — поля settings и enabled, менять можно частьok, settings, enabled
GET /v1/integrations/avito/errorserrors[]: id, at, message, details
DELETE /v1/integrations/avito/last-errorok
POST /v1/integrations/avito/items/refreshok, count — объявлений загружено, unlinked — новых объявлений без связки
GET /v1/integrations/avito/itemsitems[]: itemId, title, priceKopecks, status, url, linked
GET /v1/integrations/avito/linkslinks[]: id, enabled, ourSkus[] (sku, name), avitoItems[] (itemId, title), priceSource (min, max, avg, median — из цен связанных артикулов), priceRule (mode: percent, markup, fixed; value, min, max, outOfRange: clamp или skip), stockQty, orderSku, syncPrices, syncStocks
POST /v1/integrations/avito/links, PATCH …/links/{id}ok, link (как в списке), push — итог отправки на Авито
PATCH /v1/integrations/avito/links/bulkok, updated, push, links[]
DELETE /v1/integrations/avito/links/{id}ok
POST /v1/integrations/avito/syncok, prices и stocks — сколько обновлено, skipped, errors[], errorRows[] (message, details), ordersImported
GET /v1/integrations/avito/ordersorders[]: id, status, createdAt, items, totalKopecks, ourOrderNumber — наш заказ, если уже оформлен, fetchedAt
POST /v1/integrations/avito/orders/assemble {avitoOrderIds, comment}ok, number — наш заказ, unmatched — позиции без связки, badSkus

Через ключ нельзя: выпускать и отзывать сами ключи, управлять сессиями входа и личными настройками уведомлений — это управление доступом и личное, только в кабинете.

Вебхуки

Чтобы не опрашивать API, задайте адрес в кабинете (раздел API, «Вебхук») или методом PUT /v1/webhook — это делает владелец компании. Мы отправляем POST с JSON при событиях:

eventКогдаdata
order.createdоформлен заказ — в кабинете, в боте, файлом или через APIorderNumber, status, source, items[] (sku, name, conditions, qty, priceKopecks), totalKopecks
order.status_changedсменился статус заказаorderNumber, status
order.changedменеджер поправил заказ при сборке — нужен ваш ответorderNumber, totalKopecks, changes[] (sku, kind: added/removed/changed, was, now — priceKopecks, qty, extra[])
price.changedизменились ваши ценыchanges[] (sku, name, oldPriceKopecks, newPriceKopecks; null — цены нет), part, parts — пачками по 500
imei.check_completedпроверка завершиласьcheckId, imei, serviceId, status
pingкнопка «Проверить» в кабинетеmessage
POST https://ваш-адрес
X-B2B-Signature: 3f1a…   (HMAC-SHA256 тела, ключ — секрет из кабинета, hex)
X-B2B-Event: order.status_changed
X-B2B-Delivery: 7d0c…    (id события — тот же при повторе)
X-B2B-Attempt: 1

{ "id": "7d0c…", "event": "order.status_changed", "at": "2026-09-03T08:12:41.000Z",
  "data": { "orderNumber": "TG000012", "status": "shipped" } }

Проверяйте подпись: посчитайте HMAC-SHA256 от сырого тела запроса секретом из кабинета и сравните с заголовком. Отвечайте любым кодом 2xx в течение 10 секунд.

Повторы. Не дошло — повторяем через 1, 5, 30 минут, 2, 6, 12 и 24 часа: до 8 попыток за двое суток. Очередь переживает перезапуски сервиса. Повтор несёт тот же id — по нему отсекайте дубли. Порядок событий не гарантирован: сверяйтесь с полем at. После всех попыток событие считается недоставленным, причина видна в кабинете. Событие — ускорение, а не единственный источник истины: при сомнении перечитайте объект через API. Адрес должен быть внешним http(s); редиректы не выполняются.

Ошибки

Ошибка — это JSON с полем error и пояснением.

{ "error": "unauthorized", "message": "Ключ недействителен" }
КодerrorПричина
400bad_requestТело запроса не разобрано
401unauthorizedКлюч отсутствует, отозван или недействителен
403forbiddenМетод вне выданных областей либо доступ закрыт
402subscription_requiredПодписка на API не активна
402rejectedНедостаточно средств для операции
404not_foundМетод или объект не существует
409rejectedОперация невозможна в текущем состоянии
409in_progressЗаказ с этим Idempotency-Key ещё создаётся
409closedВне времени работы: заказы принимаются с hours.from до hours.to (по Москве)
409unavailableПроверка IMEI сейчас недоступна
502upstreamВнешний сервис проверок недоступен
429rate_limitedПревышен лимит запросов
503startingСервис перезапускается
500internalВнутренняя ошибка

Ключи

Ключи выпускаются и отзываются в личном кабинете, раздел API. Там же указано время последнего использования каждого ключа.

Отзыв действует немедленно. Восстановить ключ нельзя — вместо этого выпускается новый.

Ключ даёт доступ к вашим данным. Не кладите его в репозиторий и не передавайте в параметрах адреса: они оседают в логах и в истории браузера. Только заголовок. Если ключ мог утечь — отзовите и выпустите новый.

На компанию можно держать до десяти действующих ключей — по одному на каждую интеграцию.