Transgran API v1 — интеграция (1С и другие системы)

Публичный REST-API поверх Transgran для внешних систем учёта (1С и др.).

Абстрагирует Текшер: свои URL, свои имена полей, единый формат ошибок.

Клиент не работает с Текшером напрямую — только через Transgran.

Base URL: https://transgran.kg/api/v1

Формат: JSON (Content-Type: application/json, Accept: application/json)

Кодировка: UTF-8


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

Все запросы — с API-ключом в заголовке:

Authorization: Bearer pak_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Без валидного ключа → 401 unauthorized. Ключ перестаёт работать и тогда, когда у учётной записи, создавшей ключ, выключен доступ к API или сама эта учётная запись заблокирована.

Ключ сотрудника

Если ключ создал сотрудник аккаунта под своей учётной записью, API открывает ему те же кабинеты и требует те же права, что сайт.

МетодПраво сотрудника
GET /cabinets, GET /cabinets/{cabinet}/balanceне нужно. Суммы в сомах (amount) — только с правом «Оплата», без него amount: null; codes_available видно всегда
POST /cabinets/{cabinet}/syncне нужно
GET /tnved, GET /tnved/{code}/attributesне нужно
GET /products, GET /products/{gtin}, POST /products, POST /products/{gtin}/publishне нужно
POST /orders«Заказ кодов и печать»
GET /orders/{id}, GET /orders/{id}/codesне нужно

2. Общие правила

Ответ

Успешный ответ — JSON с полем data: в нём объект или массив. У списков рядом лежат page, limit и total. Примеры ниже показывают ответ целиком.

Пагинация

Списки (/products, /tnved) поддерживают ?page=1&limit=50 (limit ≤ 200, по умолчанию 50). Ответ:

{ "data": [ ... ], "page": 1, "limit": 50, "total": 137 }

Ошибки

Единый формат + корректный HTTP-код:

{ "error": { "code": "validation_error", "message": "gtin: нужно от 8 до 14 цифр" } }
HTTPcodeКогда
400validation_errorНеверные данные запроса, в том числе заказ кодов на неопубликованный товар (раздел 6). Сюда же — отказ Текшера по существу при создании товара и при публикации, с его причиной (см. раздел 5)
401unauthorizedНет/невалидный API-ключ
402subscription_requiredЗапись недоступна: аккаунт отрезан от Текшера (guest — гость / истёкшие free и платные) или на заказ не хватает кодов
403forbiddenНет доступа к кабинету (не ваш и не закреплён за вами) или у сотрудника нет нужного права — см. «Ключ сотрудника» в разделе 1
404not_foundРесурс не найден
409conflictGTIN уже существует или коды заказа ещё не выпущены
429rate_limitedСлишком много запросов
502teksher_unavailableТекшер недоступен или подключение кабинета к Текшеру истекло — повторите позже. Отказ по существу Текшер иногда присылает с кодом 500 — у создания товара и публикации он придёт как 502 с его причиной («Текшер ответил 500: …»), см. раздел 5
500internal_errorВнутренняя ошибка. Так же иногда приходит сбой Текшера при чтении справочников — повторите позже

Идентификаторы


3. Кабинеты

GET /cabinets

Кабинеты, доступные ключу (владельцу — его кабинеты, сотруднику — закреплённый за ним, см. раздел 1), с группами и балансом.

{
  "data": [
    {
      "id": "ef7e1ee0-...",
      "name": "ОсОО \"Каныкей Трейдинг\"",
      "inn": "00411201910204",
      "groups": [
        { "alias": "perfumery", "name": "Духи и туалетная вода" },
        { "alias": "chemistry", "name": "Косметика, бытовая химия и товары личной гигиены" }
      ],
      "balances": [
        { "group": "perfumery", "amount": 250.0, "currency": "KGS", "codes_available": 364 },
        { "group": "chemistry", "amount": 98.59, "currency": "KGS", "codes_available": 143 }
      ]
    }
  ]
}

GET /cabinets/{cabinet}/balance

Баланс кабинета по группам (то же, что balances выше, отдельным запросом, и с тем же правилом для сумм у ключа сотрудника): { "data": [ ... ] }. Пустой data — баланс получить не удалось, повторите позже. Подключение кабинета к Текшеру истекло → 502 teksher_unavailable.

POST /cabinets/{cabinet}/sync

Обновить каталог товаров кабинета из Текшера прямо сейчас.

Товары в API — наш кэш: подтягиваются из Текшера фоном раз в час. Обычно этого достаточно; метод нужен, когда товар завели или изменили в кабинете Текшера руками и он требуется немедленно. Он же обновляет статус товара после отправки на публикацию. Товар, созданный через POST /products, синхронизировать обычно не нужно — он попадает в кэш сразу (раздел 5).

Тела нет. Ответ:

{ "data": { "started": true, "products": 412, "updated": 3, "removed": 0, "syncedAt": "2026-08-21T15:40:12.000Z" } }

products — сколько товаров в кабинете Текшера, updated — сколько карточек перечитали: новые, изменённые и часть давно не обновлявшихся (поэтому updated бывает больше нуля, даже когда в Текшере ничего не менялось), removed — сколько убрали из кэша, потому что в Текшере их больше нет.


4. Справочники (для создания товара)

GET /cabinets/{cabinet}/tnved?query=&group=&page=&limit=

Поиск кодов ТН ВЭД по справочнику кабинета. Код и название отдаются как в Текшере, без переформатирования; group — наш alias товарной группы.

{ "data": [
  { "code": "3303009000", "name": "Туалетная вода", "group": "perfumery" }
], "page": 1, "limit": 50, "total": 3 }

GET /cabinets/{cabinet}/tnved/{code}/attributes

Схема атрибутов для товара с этим кодом ТН ВЭД — какие поля заполнять при создании.

{ "data": [
  { "code": "2716", "name": "Заявленный объём", "required": true, "multiple": false,
    "type": "number", "units": ["мл","л","г"], "options": [] },
  { "code": "1034", "name": "Тип парфюмерии", "required": true, "multiple": false,
    "type": "enum", "units": [], "options": ["ДУХИ","ТУАЛЕТНАЯ ВОДА","ПАРФЮМЕРНАЯ ВОДА"] },
  { "code": "13836", "name": "Номер регламента/стандарта", "required": true, "multiple": false,
    "type": "enum", "units": [], "options": ["ТР ТС 009/2011 ...", "ТР ТС 005/2011 ..."] }
] }

5. Товары

GET /cabinets/{cabinet}/products?group=&query=&page=&limit=

Список товаров кабинета. Фильтры: group (alias группы) и query — поиск по подстроке, в том числе в названии, GTIN, бренде, коде ТН ВЭД, GCP и GLN, производителе и его ИНН, стране, значениях атрибутов, артикулах и штрихкодах маркетплейсов.

Список отдаём из нашего кэша: он обновляется из Текшера раз в час, сразу — через POST /cabinets/{cabinet}/sync. Товар, созданный через POST /products, обычно попадает в него сразу. На guest и при истёкшем подключении кабинета к Текшеру кэш не обновляется — в списке последнее известное состояние (см. раздел 7). Товары, скрытые на сайте, в API тоже есть.

{ "data": [
  {
    "gtin": "03660005806198",
    "name": "ГЕЛЬ ДЛЯ ДУША «ЛИМОН & БАЗИЛИК», 400 мл",
    "brand": "Yves Rocher",
    "group": "chemistry",
    "tnved": "3401300000",
    "status": "draft",
    "country": "KG",
    "attributes": [
      { "code": "12", "name": "Вид товара", "value": "ГЕЛЬ ДЛЯ ДУША", "unit": null }
    ]
  }
], "page": 1, "limit": 50, "total": 12 }

status: draft (черновик) | moderation (отправлен на публикацию, ждёт обработки) | published (опубликован) | rejected (отклонён). Изредка у Текшера бывают и другие статусы (например, publish_failed — публикация не прошла): их отдаём как есть, в нижнем регистре.

GET /cabinets/{cabinet}/products/{gtin}

Один товар (та же схема): { "data": { "gtin": "...", ... } }. Тоже из кэша.

POST /cabinets/{cabinet}/products

Создать товар (черновик в Текшере).

Тело:

{
  "gtin": "03660005371337",
  "name": "Туалетная вода \"Роза\", 50 мл",
  "brand": "Yves Rocher",
  "tnved": "3303009000",
  "country": "KG",
  "manufacturer": { "inn": "00411201910204", "name": "ОсОО \"Каныкей Трейдинг\"" },
  "attributes": [
    { "code": "2716", "value": "50", "unit": "мл" },
    { "code": "1034", "value": "ТУАЛЕТНАЯ ВОДА" },
    { "code": "13836", "value": "ТР ТС 009/2011 ..." }
  ]
}

Какие поля обязательны:

ПолеОбязательноПримечание
gtinда8–14 цифр. Короче 14 — дополним нулями слева сами; короче 8 или длиннее 14 — 400. Последняя цифра — контрольная GS1, должна сходиться
nameданазвание товара, непустое
brandдаторговая марка, непустое
tnvedдаточный код из /tnved
attributesзависитобязательны те, у которых required: true в /tnved/{code}/attributes — см. ниже
countryнеткод (KG) или название (КЫРГЫЗСТАН) из справочника Текшера, регистр не важен. Пусто → страна кабинета. Незнакомое значение → 400 validation_error с подсказкой, а не страна кабинета
manufacturerнет{inn, name}. Пусто → данные кабинета; то же для каждого поля по отдельности. inn — строкой, см. ниже

сходится — 400 validation_error, запрос до Текшера не дойдёт:

gtin: GTIN не проходит проверку контрольной цифры (последней) — скорее всего, в номере опечатка….

Сверьте номер с сертификатом GS1 или штрихкодом на товаре. Такой товар

Текшер создаёт, но не публикует, а на неопубликованный коды маркировки не

выпустить.

Кыргызстана, зарегистрированной 1–9 числа, начинается с 00. Число примем,

только если в нём 14 цифр или 12–13 цифр ИНН компании КР без нулей впереди

(их вернём сами), иначе — 400 validation_error:

manufacturer.inn: передайте ИНН строкой — в числе теряются ведущие нули.

Пробелы между частями номера уберём сами, если в каждой части есть цифра

(91440300 MA5F8KXQ2N), а также после кода страны (DE 123 456 789) и

вокруг дефиса (0101234567 - 001). Часть из одних букв (Yiwu 168 Trading)

— признак названия, а не ИНН. Такое значение, экспонента (2,07E+12),

кириллица, символы кроме цифр, латинских букв и дефиса, длина не 5–20

знаков — 400 с причиной, запрос до Текшера не дойдёт. Латинские буквы

допустимы: они бывают в номерах иностранных производителей.

POST /cabinets/{cabinet}/products/{gtin}/publish

Отправить товар на публикацию.

Тела нет — товар указывается GTIN-ом в пути.

Ответ:

{
  "data": { "gtin": "03660005371337", "status": "moderation", "alreadySent": false }
}

Пример:

curl -X POST https://transgran.kg/api/v1/cabinets/<id>/products/03660005371337/publish \
  -H "Authorization: Bearer pak_..."

6. Заказ кодов маркировки

POST /cabinets/{cabinet}/orders

Заказать коды для товаров. Товары должны быть заведены в кабинете и опубликованы.

Тело:

{ "items": [
  { "gtin": "03660005371337", "quantity": 1000 },
  { "gtin": "03660005806198", "quantity": 500 }
] }

Обязательны оба поля каждой позиции: gtin и quantity. Пустой items → 400 validation_error.

Ошибка проверки тела здесь, в отличие от товаров, поле не называет — приходит только текст валидатора, на английском: Expected string, received number (GTIN числом), Array must contain at least 1 element(s) (пустой items). Сверяйте тело с правилами ниже.

Ответ 202 Accepted — заказ принят в обработку (коды выпускаются асинхронно):

{
  "data": {
    "id": "8f50...",
    "status": "processing",
    "created_at": "2026-07-20T05:17:00Z",
    "items": [
      { "gtin": "03660005371337", "quantity": 1000, "status": "processing" }
    ]
  }
}

GET /cabinets/{cabinet}/orders/{id}

Статус заказа. status: processing | ready | partial (часть позиций выполнена, часть — нет) | failed. У позиций — processing | ready | failed; codes_count — сколько кодов по позиции уже выпущено.

{ "data": { "id": "8f50...", "status": "ready", "created_at": "...",
  "items": [ { "gtin": "03660005371337", "quantity": 1000, "status": "ready", "codes_count": 1000 } ] } }

GET /cabinets/{cabinet}/orders/{id}/codes

Коды заказа. Отдаём выпущенные коды, как только есть хотя бы один; пока нет ни одного — 409 conflict. Пока заказ в processing, список может быть неполным — забирайте коды, когда status стал ready или partial.

{ "data": { "codes": [
  "0103660005371337215Fk8lR...",
  "0103660005371337215Xy2Pq..."
] } }

Коды — полные DataMatrix-строки (GS1, с криптоподписью), готовы к печати. Коды всех позиций приходят одним списком; GTIN виден в самом коде — 14 цифр после 01. Выгрузки в CSV нет: коды приходят одним JSON-массивом.


7. Ограничения и заметки


8. Быстрый старт (пример)

# 1. Кабинеты
curl -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets

# 2. Создать товар — обычно он сразу виден API, sync не нужен
curl -X POST https://transgran.kg/api/v1/cabinets/<id>/products \
  -H "Authorization: Bearer pak_..." -H "Content-Type: application/json" \
  -d '{"gtin":"03660005371337","name":"...","brand":"Yves Rocher","tnved":"3303009000","attributes":[...]}'

# 3. Отправить на публикацию
curl -X POST -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets/<id>/products/03660005371337/publish

# 4. Дождаться status = published: sync (не чаще раза в 2 минуты), затем карточка
curl -X POST -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets/<id>/sync
curl -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets/<id>/products/03660005371337

# 5. Заказать коды — только на опубликованный товар, иначе 400
curl -X POST https://transgran.kg/api/v1/cabinets/<id>/orders \
  -H "Authorization: Bearer pak_..." -H "Content-Type: application/json" \
  -d '{"items":[{"gtin":"03660005371337","quantity":1000}]}'

# 6. Статус → коды
curl -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets/<id>/orders/<order>
curl -H "Authorization: Bearer pak_..." https://transgran.kg/api/v1/cabinets/<id>/orders/<order>/codes