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- Ключ генерируется в личном кабинете: Настройки → API-ключи → Создать ключ. Метку («1С склад») можно не заполнять — она нужна, только чтобы отличать ключи.
- Раздел «API-ключи» появляется, когда для аккаунта включён доступ к API. Нет раздела — напишите в поддержку Transgran, доступ включаем мы.
- Ключ имеет вид
pak_и 64 символа. Показывается один раз при создании — сохраните. Потерян → создать новый. - Ключ привязан к учётной записи, которая его создала (не к кабинету), и открывает те же кабинеты, что сайт этому человеку: владельцу аккаунта — все его кабинеты, сотруднику — только закреплённый за ним. Подробнее — ниже, «Ключ сотрудника».
- Отзыв: там же, значком корзины напротив ключа. Отозванный ключ сразу перестаёт работать.
- Ключ = секрет. Не публикуйте, не кладите в клиентский код.
Без валидного ключа → 401 unauthorized. Ключ перестаёт работать и тогда, когда у учётной записи, создавшей ключ, выключен доступ к API или сама эта учётная запись заблокирована.
Ключ сотрудника
Если ключ создал сотрудник аккаунта под своей учётной записью, API открывает ему те же кабинеты и требует те же права, что сайт.
- Кабинеты.
GET /cabinetsпоказывает те же кабинеты, что переключатель кабинетов на сайте: сотруднику — только закреплённый за ним (закрепляет администратор аккаунта в разделе «Сотрудники»). Право «Подключение кабинетов» список не расширяет: кабинет, который подключил сотрудник, попадает в аккаунт компании и открывается ему после закрепления — как на сайте. Остальные методы принимают ровно эти кабинеты; чужой или незакреплённый кабинет →403 forbidden«Нет доступа к кабинету». - Права. Метод требует то же право сотрудника, что сайт на том же действии:
| Метод | Право сотрудника |
|---|---|
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 | не нужно |
- Нет нужного права →
403 forbiddenс его названием: «Недостаточно прав: нужно право «Заказ кодов и печать» — попросите администратора аккаунта». - Тариф и коды — владельца аккаунта. Сотрудник работает под тарифом владельца кабинета (раздел 7), а заказ списывает коды с баланса кодов владельца — как заказ на сайте.
- Владельцу аккаунта права не нужны: в своих кабинетах ему доступно всё.
- Если у сотрудника есть и свой аккаунт, роль считается по каждому кабинету отдельно: в своих кабинетах он владелец, в закреплённом за ним кабинете компании — сотрудник с её правами.
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 цифр" } }| HTTP | code | Когда |
|---|---|---|
| 400 | validation_error | Неверные данные запроса, в том числе заказ кодов на неопубликованный товар (раздел 6). Сюда же — отказ Текшера по существу при создании товара и при публикации, с его причиной (см. раздел 5) |
| 401 | unauthorized | Нет/невалидный API-ключ |
| 402 | subscription_required | Запись недоступна: аккаунт отрезан от Текшера (guest — гость / истёкшие free и платные) или на заказ не хватает кодов |
| 403 | forbidden | Нет доступа к кабинету (не ваш и не закреплён за вами) или у сотрудника нет нужного права — см. «Ключ сотрудника» в разделе 1 |
| 404 | not_found | Ресурс не найден |
| 409 | conflict | GTIN уже существует или коды заказа ещё не выпущены |
| 429 | rate_limited | Слишком много запросов |
| 502 | teksher_unavailable | Текшер недоступен или подключение кабинета к Текшеру истекло — повторите позже. Отказ по существу Текшер иногда присылает с кодом 500 — у создания товара и публикации он придёт как 502 с его причиной («Текшер ответил 500: …»), см. раздел 5 |
| 500 | internal_error | Внутренняя ошибка. Так же иногда приходит сбой Текшера при чтении справочников — повторите позже |
Идентификаторы
- cabinet — id кабинета (UUID), берётся из
GET /cabinets. - gtin — GTIN товара, 8–14 цифр. Удобнее всего 14 цифр с нулями слева, как в
GET /products, но та же форма без нулей слева (например, 13 цифр) находит тот же товар. Из адреса берём только цифры: пробелы, дефисы и другие знаки отбрасываем. Меньше 8 или больше 14 цифр →400; товара с таким GTIN в кабинете нет →404. - group — alias товарной группы (
perfumery,chemistry,lp, …).
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 }
]
}
]
}amount— остаток на счёте группы в Текшере, в сомах (currencyвсегдаKGS).codes_available— сколько кодов покрывает этот остаток по текущему курсу, с налогом с продаж (НсП) 3 %: Текшер берёт его сверху цены каждого кода. Оба бываютnull, если Текшер не дал данных для расчёта.amountприходитnullи тогда, когда ключ сотрудника без права «Оплата»: суммы в сомах сайт ему тоже не показывает.codes_availableпри этом есть — это рабочее число склада, а не деньги.- Баланс живой, из Текшера (кэш 30 секунд). Если Текшер не ответил, отдаём последнее известное значение; если его нет или подключение кабинета истекло —
groupsиbalancesпридут пустыми. Это не «ноль на счёте»: повторите запрос позже.
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 — сколько убрали из кэша, потому что в Текшере их больше нет.
- Не чаще раза в 2 минуты на кабинет (считая и фоновую синхронизацию). Если синхронизация была недавно, вернём
200и"started": false— это не ошибка, данные уже свежие:{ "data": { "started": false, "reason": "recent", "syncedAt": "...", "nextAllowedAt": "..." } }. - Синхронизация синхронная: ответ приходит, когда каталог уже обновлён. На больших каталогах это несколько секунд.
- Вызывайте её перед выгрузкой номенклатуры, после ручных правок в кабинете Текшера или чтобы увидеть итог публикации, а не в цикле: полная выгрузка — это десятки запросов к Текшеру.
- Синхронизация идёт в Текшер, поэтому подчиняется тарифу так же, как запись: без доступа к Текшеру →
402(см. раздел 7). 502 teksher_unavailable— Текшер не ответил или подключение кабинета к Текшеру истекло; данные остались прежними, можно повторить.
4. Справочники (для создания товара)
GET /cabinets/{cabinet}/tnved?query=&group=&page=&limit=
Поиск кодов ТН ВЭД по справочнику кабинета. Код и название отдаются как в Текшере, без переформатирования; group — наш alias товарной группы.
{ "data": [
{ "code": "3303009000", "name": "Туалетная вода", "group": "perfumery" }
], "page": 1, "limit": 50, "total": 3 }groupнеобязателен: без него ищем по всем группам кабинета.query— цифры ищутся по коду (можно с пробелами и точками:6109 10 000 0), буквы — по названию. Поиска по названию у Текшера нет вовсе: справочник кабинета мы держим у себя, поэтому «жилет» или «шампунь» найдутся только здесь.- Ищем по всему справочнику кабинета, а не по первой странице:
total— сколько нашлось всего,page/limitлистают уже результат. Точное совпадение кода стоит первым. - Пустой
query— витрина справочника, коды по возрастанию. - Всё это — когда мы знаем подгруппы кабинета. Если не знаем ни одной (или
groupс опечаткой либо такой группы у кабинета нет — сверяйте сgroupsвGET /cabinets), поиск идёт силами Текшера: только по цифрам кода, без пробелов и точек, и без фильтра по группе. Название или код с пробелами тогда вернут пустой список.
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 ..."] }
] }type:text|number|enum.optionsпусто → свободный ввод.units— допустимые единицы (если есть).required— обязательность.multiple— атрибут допускает несколько значений.- Производные атрибуты (они берутся из
name,tnvedиcountry) в схему не входят — присылать их не нужно. - Передавайте точный 10-значный код из
/tnved. Неполный код сервер ищет как часть кода и, если точного совпадения нет, без предупреждения отдаёт схему первого кода, в котором есть эти цифры:/tnved/6109/attributesвернёт схему какого-то из кодов 6109…, а подгруппы у них бывают разные.404 not_found— только когда таких цифр нет ни в одном коде.POST /productsс неполным кодом ответит400: там нужно точное совпадение.
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 — строкой, см. ниже |
- Без кода ТН ВЭД товар не создать: нет
tnved— вернём400 validation_error, запрос до Текшера не дойдёт. Код должен точно совпадать со справочником: похожий сервер не подбирает, иначе товар молча уедет в чужую подгруппу, где к нему не подойдут атрибуты. Если кода нет в справочнике —400, «Код ТН ВЭД … не найден». - Обязательность атрибутов решает Текшер, хотя в нашей схеме поле
attributesнеобязательное. Запросите/tnved/{code}/attributesи пришлите все, у которыхrequired: true: без них Текшер откажет в создании, а мы вернём его текст как400 validation_error. Для парфюмерии это, например, «Заявленный объём», «Тип парфюмерии» и «Номер регламента/стандарта». attributes— по схеме из/tnved/{code}/attributes. Присылайте{code, value}иunit, если у атрибута есть единицы: без единицы Текшер товар создаст, но при публикации откажет. Тип значения (число/строка) подставляется сервером автоматически — полеdataTypeслать НЕ нужно (для числовых атрибутов вроде объёма это делается за вас).- Дробное число можно прислать и с запятой (
6,5): в числовых полях заменим её на точку — с запятой Текшер товар создаёт, но не публикует. - Пустая строка и null — то же, что «не передано», но только у
country,manufacturer(и егоinnиname) и уunitатрибута:"country": ""или"manufacturer": nullне ошибка — подставим данные кабинета. Остальные поля так не прощаем:attributesлибо не присылайте, либо шлите массивом (можно пустым,[]) — наnullбудет400;name,brand,gtinиtnvedдолжны быть заполнены, аvalueатрибута — строка или число, неnull. gtin,tnved, коды и значения атрибутов принимаем и числом, и строкой: 1С шлёт по-разному.- Ошибка валидации называет поле:
manufacturer.name: Expected string, received number— так видно, что именно чинить. Тексты проверки типов — на английском, так их пишет валидатор. - Ответ:
201+ созданный товар в той же схеме:{ "data": { "gtin": "...", "status": "draft", ... } }. - Контрольная цифра GTIN (последняя) должна сходиться по правилу GS1. Не
сходится — 400 validation_error, запрос до Текшера не дойдёт:
gtin: GTIN не проходит проверку контрольной цифры (последней) — скорее всего, в номере опечатка….
Сверьте номер с сертификатом GS1 или штрихкодом на товаре. Такой товар
Текшер создаёт, но не публикует, а на неопубликованный коды маркировки не
выпустить.
409 conflict— если GTIN уже заведён.- ИНН производителя — строкой. В числе теряются ведущие нули: ИНН компании
Кыргызстана, зарегистрированной 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 с причиной, запрос до Текшера не дойдёт. Латинские буквы
допустимы: они бывают в номерах иностранных производителей.
502 teksher_unavailable— Текшер не ответил или подключение кабинета к Текшеру истекло, повторите позже. Отказ по существу Текшер иногда присылает с кодом 500 — тогда502придёт с его причиной: «Текшер ответил 500: …». Без причины (пустой ответ, служебная заглушка или трассировка сервера) — «Текшер недоступен». Если повторы раз за разом дают502на одном товаре, а другие запросы проходят, не повторяйте бесконечно: проверьте данные товара — обязательные атрибуты и их единицы.- Новый товар обычно сразу попадает в наш кэш. Перед ответом
201мы перечитываем из Текшера свежие товары кабинета — так же, как сайт после создания товара. ТогдаGET /products/{gtin}и публикация работают сразу,POST /syncпосле создания не нужен. Из-за этого ответ приходит позже — обычно на несколько секунд; дольше 10 секунд мы его не задерживаем. - Если Текшер в этот момент не ответил или отвечает медленно, товар всё равно создан и ответ —
201: повторять создание не нужно (повтор получит409). Кэш тогда может не успеть обновиться. ЕслиGET /products/{gtin}или публикация ответили404, вызовитеPOST /cabinets/{cabinet}/syncи повторите; без этого товар подтянет фоновая синхронизация (раз в час). - Созданный товар — черновик (
status: "draft"). Коды Текшер выдаёт только на опубликованный товар, поэтому отправьте его на публикацию — следующий метод.
POST /cabinets/{cabinet}/products/{gtin}/publish
Отправить товар на публикацию.
Тела нет — товар указывается GTIN-ом в пути.
Ответ:
{
"data": { "gtin": "03660005371337", "status": "moderation", "alreadySent": false }
}- Публикация не мгновенная. Мы отправляем заявку, дальше товар обрабатывается на стороне маркировки. Поэтому ответ —
moderation, а неpublished. Итоговый статус смотрите черезGET /cabinets/{cabinet}/products/{gtin}, предварительно обновив кэшPOST /cabinets/{cabinet}/sync(не чаще раза в 2 минуты). - После ответа
moderationтовар и в нашем кэше сразу «На публикации», как на сайте после публикации. Заказ кодов на него до решения модератора ответит400с причиной «На публикации»: дождитесь решения модератора Текшера (раздел 6). Когда товар опубликуют, обновите кэшPOST /sync— и заказ пройдёт. - Повтор безопасен. Публикуем только черновик. Если товар уже не черновик, вторая заявка не создастся: вернём
200с его текущим статусом (берём прямо у Текшера) и"alreadySent": true. - Отклонённый товар так не опубликовать. Для него ответ тот же —
200,"status": "rejected","alreadySent": true, — но заявка не уходит: товар сначала нужно исправить. 400 validation_error— Текшер отказал в публикации; в тексте ошибки — его причина. Чаще всего не заполнен обязательный атрибут товарной группы или у атрибута с единицами не указанunit. Если Текшер причину не прислал, в тексте только его код ответа: «Текшер вернул 400». Сверьте товар с/tnved/{code}/attributes(required: true); обязательные атрибуты присылайте ещё при создании товара. Всё заполнено, а отказ повторяется — напишите в поддержку Transgran.404 not_found— товара с таким GTIN в нашем кэше кабинета нет. Созданный черезPOST /productsтам обычно уже есть (если нет — см.POST /products); заведённый в кабинете Текшера руками сначала подтянитеPOST /sync.502 teksher_unavailable— Текшер не ответил или подключение кабинета к Текшеру истекло, повторите позже. Отказ по существу Текшер иногда присылает с кодом 500 — тогда502придёт с его причиной: «Текшер ответил 500: …». Без причины — «Текшер не ответил — повторите позже». Если повторы раз за разом дают502на одном товаре, а другие запросы проходят, проверьте товар так же, как при400.
Пример:
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). Сверяйте тело с правилами ниже.
gtin— строкой: числом не принимаем. Удобнее всего 14 цифр, как вGET /products; та же форма без нулей слева (например, 13 цифр) находит тот же товар. В заказ уходит форма из нашего кэша, а в ответе позиции остаются в вашей форме. Товара нет в нашем кэше →400«Товары не заведены в кабинете: …» (созданный черезPOST /productsтам обычно сразу; заведённый в кабинете Текшера руками или не успевший попасть в кэш — сначалаPOST /sync).- Коды — только на опубликованный товар (
status: "published"). Черновик, товар на модерации, отклонённый или с другим неопубликованным статусом Текшер отвергнет, поэтому такой заказ мы не принимаем целиком — как и сайт:400 validation_error, коды не списаны, в Текшер ничего не ушло. Уберите такие позиции или дождитесь публикации и пришлите заказ заново. - Текст отказа — как на сайте, по каждому товару название, GTIN и причина: «Заказ не отправлен: на эти товары Текшер коды не выдаст — Туалетная вода "Роза", 50 мл (03660005371337) — черновик: опубликуйте его в разделе «Товары». Уберите их из заказа или дождитесь, пока они станут опубликованными.» Причины бывают такие: черновик (опубликуйте его); на публикации, на проверке или изменения на модерации (дождитесь решения модератора Текшера); отклонён модератором (исправьте карточку и опубликуйте заново); любой другой статус (коды выдаются только опубликованному товару). Больше пяти товаров — первые пять и «и ещё N».
- Статус берём из нашего кэша. Товар опубликовали, а заказ всё ещё отвечает «На публикации» — обновите кэш
POST /syncи повторите. Если статус товара в кэше неизвестен, заказ не останавливаем — решает Текшер. - Ключу сотрудника нужно право «Заказ кодов и печать», иначе
403(раздел 1). quantity— целое 1…5000 на одну позицию (лимит Текшера на один GTIN). Больше — оформляйте отдельным заказом. Каждый GTIN уходит в Текшер одной операцией: лимит операции тоже 5000 (поднят Текшером 2026-07-28, раньше был 1000 и заказ резался на части).- Опционально:
note— пометка к заказу, до 50 символов (видна в списке заказов на сайте). Это строка; не нужна — не передавайте поле вовсе:"note": null→400. - Заказ списывает коды с баланса кодов владельца аккаунта в Transgran так же, как заказ на сайте (и для ключа сотрудника). Не хватает →
402 subscription_requiredс текстом «Не хватает кодов: нужно …, доступно …».
Ответ 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. Ограничения и заметки
- Тариф. Чтение (
GET) доступно любому аккаунту с доступом к API. Запись — заказ кодов (POST /orders), создание товара (POST /products), публикация (POST /products/{gtin}/publish) — и синхронизация (POST /sync) требуют доступа к Текшеру: разрешены на активном free-триале и платных тарифах, а на guest (гость / истёкшие free и платные) отрезаны →402. Это тот же пейволл, что на сайте и в мобильном приложении, и решает тариф владельца кабинета: ключ сотрудника работает под тарифом компании. Товары на guest не обновляются: фоновая синхронизация такие кабинеты пропускает, аPOST /syncотвечает402, — поэтомуGET /productsотдаёт последнее известное состояние. - Rate limit. До 120 запросов в минуту на ключ. При превышении —
429с заголовкомRetry-After(секунды до сброса окна). Запросы без ключа или с неверным ключом — до 30 в минуту с одного IP. - Свежесть данных. Товары — наш кэш (раз в час или по
POST /sync; созданные черезPOST /products— обычно сразу); на guest и при истёкшем подключении кабинета к Текшеру он не обновляется. Баланс — живой, из Текшера. Заказы и коды — наши, обновляются по мере выпуска. - Идемпотентность. Повторный
POST /productsс тем же GTIN →409(не дубль). ПовторныйPOST /publishбезопасен. А каждыйPOST /orders— новый заказ и новое списание кодов. Списка заказов в API нет: если ответ наPOST /ordersпотерялся, сначала проверьте заказы в личном кабинете на сайте и только потом повторяйте. - Асинхронность. Заказ кодов не мгновенный:
POST /orders→202, затем поллингGET /orders/{id}доready, потомGET /orders/{id}/codes. - Версионирование. Ломающие изменения →
/api/v2. v1 остаётся стабильной.
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