API g.pis для учётных систем
Версия 1. Адрес — https://g-pis.ru/api/v1.
Доступ — ключ кабинета в заголовке X-Api-Key. Ключ выдаёт администратор кабинета: «Интеграция» → «Приёмное API» → «Выдать ключ». Ключ показывается один раз, в g.pis хранится только его отпечаток. Права ключа: write — приём товаров и чтение каталога; read — только чтение; feed — только фид витрины.
Ключ определяет кабинет: чужой каталог им не виден и не изменяем.
Приём товаров: POST /api/v1/products
Пакет до 500 товаров в поле items. Ключ товара — артикул sku: повторная присылка того же товара обновляет его, второй карточки не заводит. Товары разбираются по одному: ошибка в одном не отменяет остальные.
curl -X POST "https://g-pis.ru/api/v1/products" \
-H "X-Api-Key: pim_…" -H "Content-Type: application/json" \
-d '{"items":[{
"sku": "A-1001",
"title": "Сковорода 24 см",
"brand": "Tefal",
"barcode": "3168430384934",
"category": "Посуда / Сковороды",
"description": "Антипригарное покрытие, подходит для индукции.",
"country": "Франция",
"weightGross": 1.2, "length": 45, "width": 26, "height": 8,
"attributes": {"Материал": "алюминий", "Диаметр (см)": 24},
"images": ["https://shop.example.ru/img/a-1001-1.jpg"],
"erpId": "0000-0012345"
}]}'Поля товара
| Поле | Что это |
|---|---|
sku | артикул, обязателен; ключ товара |
title | наименование, до 500 символов |
brand | бренд |
barcode | основной штрихкод; проверяется контрольная сумма EAN |
barcodes | все штрихкоды товара, массив до 100; первый годный станет основным, если barcode не передан |
category | раздел источника: путь «Раздел / Подраздел» или имя раздела; найденный в каталоге ставится товару без раздела |
description | описание, до 20 000 символов |
model | модель |
manufacturer | производитель |
country | страна производства |
vendorCode | артикул производителя |
tnved | код ТН ВЭД, 4–10 цифр |
color | цвет |
weightGross | вес с упаковкой, кг |
weightNet | вес без упаковки, кг |
length, width, height | габариты упаковки, см |
attributes | любые другие характеристики: {"название": значение}; единицу можно писать в значении («23 см») |
images | фото ссылками, до 30; первая — главная |
imageFiles | фото файлами: [{"name": "фото.jpg", "data": "<base64>"}], до 10 файлов по 10 МБ |
erpId | ваш внутренний код, например GUID 1С |
archived | true — снят с продажи, false — вернуть в работу |
Единицы не угадываются: вес — в килограммах, размеры — в сантиметрах.
Фото ссылками. g.pis сам скачивает файл и кладёт в своё хранилище. Узлы, откуда можно брать фото, задаёт администратор кабинета: «Интеграция» → «Приёмное API» → «Откуда брать фото по ссылкам» (склады картинок площадок разрешены всегда). Ссылка, уже забранная к товару, повторно не скачивается. Адреса внутренних сетей не принимаются.
Фото файлами — для систем, где у картинки нет адреса (1С): содержимое в base64.
Что учёт может перезаписать: штрихкод, бренд, вес, габариты (паспортные поля). Наименование и характеристики учёт только заполняет, если они пусты. Правку, сделанную человеком в g.pis, не перетирает никто.
Ответ
По каждому товару отдельно:
{"dryRun": false, "accepted": 1, "rejected": 1,
"results": [{"sku": "A-1001", "status": "created", "productId": "cmt…",
"category": {"найден": "Посуда / Сковороды"},
"images": {"принято": 1, "отказано": 0, "причины": []},
"unknownAttributes": ["Тип аптечки"]}],
"errors": [{"index": 1, "sku": "A-1002", "errors": ["barcode: контрольная сумма штрихкода не сходится"]}]}status:created|updated|unchanged|rejected.errors— товары, отклонённые при разборе: номер в пакете, артикул и причины словами.unknownAttributes— характеристики, которых нет в справочнике каталога: они сохранены в данных источника, но полем каталога не стали.category.неНайден— раздел не найден, товар принят без раздела.conflicts— паспортное значение учёта разошлось со значением площадки.rejectedBarcode— штрихкод не принят (товар принят без него).
Проверка без записи: POST /api/v1/products?dryRun=1
Тот же пакет, но ничего не записывается: ответ показывает, что будет с каждым товаром (created — заведётся, updated — обновится), какие характеристики и разделы не найдутся, какие поля с ошибкой. Работает и с ключом read. Тот же разбор — на экране «Интеграция» → «Проверить пакет без записи».
Отдача каталога: GET /api/v1/products
curl "https://g-pis.ru/api/v1/products?limit=200&updatedSince=2026-10-01" -H "X-Api-Key: pim_…"
| Параметр | Смысл |
|---|---|
limit | 1…200, по умолчанию 50 |
after | курсор: артикул последнего товара предыдущей страницы |
sku | один товар по артикулу |
brand | бренд или несколько через запятую; регистр не важен |
updatedSince | только изменённые с этого момента (2026-10-01 или 2026-10-01T10:00:00Z) |
images=0 | без адресов фото (быстрее) |
{"items": [{"sku": "A-1001", "title": "…", "brand": "Tefal", "barcode": "…", "origin": "erp",
"category": "Сковороды", "lifecycle": "draft", "updatedAt": "2026-10-19T10:00:00.000Z",
"attributes": {"Материал": {"value": "алюминий", "values": ["алюминий"], "source": "учётная система"}},
"images": ["https://g-pis.ru/media/…jpg"],
"listings": [{"marketplace": "wildberries", "status": "published", "externalId": "12345"}]}],
"nextAfter": "A-1001"}Страницы идут курсором по артикулу: идите, пока nextAfter не станет null. Номер страницы не используется — каталог меняется под чтением, и товар, изменившийся между запросами, потерялся бы.
Коды ответов
| Код | Когда |
|---|---|
| 200 | принято или отдано; отказы отдельных товаров — в results и errors |
| 400 | пакет не разобран или параметр неверен; текст называет поле и причину |
| 401 | ключ неизвестен, отозван или истёк |
| 403 | у ключа нет нужного права (например, read для записи) |
Пример на 1С
Готовое решение для 1С:Управление торговлей 11 — расширение «Выгрузка в PIM» (страница «Интеграция» → «1С»). Для своей конфигурации — тот же запрос:
Соединение = Новый HTTPСоединение("pim.example.ru", 443, , , , 300, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/api/v1/products");
Запрос.Заголовки.Вставить("X-Api-Key", Ключg.pis);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Товар = Новый Структура("sku, title, brand", Артикул, Наименование, Марка);
Запись = Новый ЗаписьJSON; Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Новый Структура("items", ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Товар)));
Запрос.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
// Ответ.КодСостояния = 200 → разберите results и errors по каждому товаруПример на Python
import requests
r = requests.post("https://g-pis.ru/api/v1/products", headers={"X-Api-Key": KEY},
json={"items": [{"sku": "A-1001", "title": "Сковорода 24 см", "brand": "Tefal"}]}, timeout=300)
r.raise_for_status()
for x in r.json()["results"]:
print(x["sku"], x["status"])
for e in r.json()["errors"]:
print("отклонён:", e.get("sku"), "; ".join(e["errors"]))Без программиста: g.pis забирает данные сам
«Интеграция» → «Источники данных»: файл выгрузки по ссылке (CSV, XLSX, JSON, YML), база данных (PostgreSQL, MySQL, MS SQL — один запрос SELECT) или 1С по OData — по расписанию, с журналом каждого прогона. Каждый прогон проходит тот же разбор, что и этот API.
События (вебхуки)
Каталог сам сообщает об изменениях, чтобы вам не приходилось опрашивать его по расписанию. Подписка заводится администратором на странице «Пользователи»; секрет подписи показывается один раз.
POST <ваш адрес>
X-Pim-Event: product.updated
X-Pim-Signature: sha256=<HMAC-SHA256 от тела запроса вашим секретом>
Content-Type: application/json
{"event":"product.updated","at":"2026-08-26T18:20:00.000Z","productId":"...","field":"Мощность","value":"1450","percent":57}События: product.updated (правка характеристики), product.published (площадка подтвердила карточку), listing.status (карточка сменила состояние: принята, отклонена, на проверке).
Проверка подписи (Node.js):
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, rawBody, signature) {
const expected = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`;
const a = Buffer.from(expected);
const b = Buffer.from(signature ?? "");
return a.length === b.length && timingSafeEqual(a, b);
}Ответ 2xx считается доставкой. Любой другой — поводом повторить: 1, 5, 25 минут, дальше час, всего пять попыток. После пятой событие помечается недоставленным и видно на экране подписок.