Skip to content

Integration API v1.0

Integration API — стабильный REST-фасад для обмена опубликованными бизнес-данными с внешними системами. Он не предоставляет пользовательскую сессию, управление сотрудниками, настройками платформы или неопубликованными сущностями.

Базовый URL

text
/api/v1/integration-api

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

Владелец портала выдаёт каждой внешней системе отдельный API-ключ с минимальным набором точных доменных scopes. Каждый запрос передаёт ключ только в заголовке:

http
X-API-Key: spk_...

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

Метаданные текущего ключа

http
GET /api/v1/integration-api/meta
X-API-Key: spk_...

Ответ содержит только ресурсы, операции, события и scopes, разрешённые текущему ключу. Используйте этот ответ для определения фактически доступного контракта.

Бизнес-ресурсы

ResourceНазначениеRead scopeWrite scope
purchase-requisitionsЗаявки на закупкуpurchase_requisitions.readpurchase_requisitions.write
procurement-itemsПозиции доступных закупокpurchase_requisitions.readтолько чтение
supplier-rfqsЗапросы цен поставщикамsupplier_documents.readтолько чтение
supplier-quotesПредложения поставщиковsupplier_documents.readтолько чтение
catalog-itemsНоменклатураcatalog.readcatalog.write
counterpartiesКонтрагентыcounterparties.readcounterparties.write
warehousesСкладыwarehouses.readwarehouses.write
price-listsПрайс-листыprice_lists.readprice_lists.write
invoicesВходящие счетаfinance.readfinance.write

В OpenAPI каждый ресурс показан отдельными методами, поэтому разработчику не нужно подставлять строковое значение в общий параметр {resource}.

Для шести изменяемых ресурсов опубликованы:

http
GET   /api/v1/integration-api/:resource
POST  /api/v1/integration-api/:resource
GET   /api/v1/integration-api/:resource/:id
PATCH /api/v1/integration-api/:resource/:id

В строке :resource выше используется один из кодов: purchase-requisitions, catalog-items, counterparties, warehouses, price-lists или invoices. В Swagger они представлены отдельными paths и типизированными body/response-схемами.

PATCH возвращает актуальное представление записи и поэтому требует одновременно read- и write-scope ресурса. POST создания требует write-scope. Для входящих счетов дополнительно опубликован точный недеструктивный метод:

http
POST /api/v1/integration-api/invoices/:id/operations/change-status

Он принимает только paymentStatus из enum, показанного в OpenAPI.

Пример создания позиции

http
POST /api/v1/integration-api/catalog-items
X-API-Key: spk_...
Content-Type: application/json

{
  "sku": "PUMP-100",
  "name": "Насос циркуляционный",
  "brand": "Example"
}

Поля, отсутствующие в request-схеме ресурса, отклоняются. Ответ содержит только поля опубликованной response-схемы. Связь с ID внешней системы регистрируется отдельным PUT /links, чтобы для неё всегда проверялся собственный scope.

Позиции закупок, RFQ и предложения

Эти ресурсы опубликованы только для чтения:

http
GET /api/v1/integration-api/procurement-items
GET /api/v1/integration-api/procurement-items/:id
GET /api/v1/integration-api/supplier-rfqs
GET /api/v1/integration-api/supplier-rfqs/:id
GET /api/v1/integration-api/supplier-quotes
GET /api/v1/integration-api/supplier-quotes/:id

Общие параметры списка: search или q, page от 1, limit от 1 до 100, а также необязательные pipelineId, procurementId, status и updatedSince. Для RFQ и предложений доступен supplierId; для предложений — rfqId.

Позиции требуют purchase_requisitions.read. RFQ и предложения требуют supplier_documents.read. Во всех трёх случаях запись возвращается только тогда, когда её родительская закупка находится в портале ключа и в доступной создателю ключа воронке.

Ответы намеренно не содержат служебные metadata, технические снимки доставки, токены ссылок, внутренние комментарии, адреса получателей и поля управления пользователями. Методы создания, изменения и жизненного цикла для этих ресурсов во внешний контракт не входят.

Этапы обработки заявок

Внешняя система может прочитать доступные владельцу ключа воронки и этапы, а затем идемпотентно переместить конкретную заявку:

http
GET  /api/v1/integration-api/pipelines
GET  /api/v1/integration-api/pipelines/:pipelineId/stages
POST /api/v1/integration-api/procurements/:id/operations/move-stage

Перемещение требует read- и write-scope заявок, Idempotency-Key и актуальную version либо If-Match. Через внешний контракт нельзя создавать, изменять или удалять воронки и этапы, а также переводить заявку в отменяющее состояние.

Связи внешних идентификаторов

Связь сопоставляет ID внешней системы с опубликованной бизнес-сущностью:

http
GET /api/v1/integration-api/links?externalSource=source-system&externalId=1001&entityType=catalog_item
X-API-Key: spk_...
http
PUT /api/v1/integration-api/links
X-API-Key: spk_...
Content-Type: application/json

{
  "externalSource": "source-system",
  "externalId": "1001",
  "entityType": "catalog_item",
  "entityId": "entity-uuid",
  "idempotencyKey": "catalog-1001-link-v1"
}

Для чтения нужны external_links.read и read-scope целевого ресурса. Для записи нужны external_links.write и write-scope целевого ресурса.

Связи изолированы по API-ключу: ключ получает и изменяет только записи своего пространства внешних идентификаторов. В webhook payload эти связи не передаются.

Исходящие webhook-подписки

http
GET  /api/v1/integration-api/webhook
POST /api/v1/integration-api/webhook
PUT  /api/v1/integration-api/webhook/:id
POST /api/v1/integration-api/webhook/:id/test

Для списка нужен webhooks.read. Создание, изменение и тест требуют webhooks.write вместе с read-scope домена события.

Один элемент create-массива создаёт одну подписку на одно событие и один URL:

http
POST /api/v1/integration-api/webhook
X-API-Key: spk_...
Content-Type: application/json
json
[
  {
    "name": "Изменение статуса заявки",
    "event": "integration_api.procurement.status_changed",
    "url": "https://example.com/webhooks/procurements",
    "isActive": true
  }
]

Секрет HMAC возвращается только один раз в create-response в поле secretPlaintext. List-, update- и test-responses этого поля не содержат.

Подписка принадлежит создавшему её ключу. Другой ключ не может получить, изменить или протестировать её. Новые доставки прекращаются при отзыве или истечении ключа, утрате webhooks.write либо read-scope домена события.

Подробный каталог и минимальная схема payload: Исходящие webhook-события.

Генерация документов

Внешняя система может идемпотентно запустить генерацию документа и отдельно получить результат:

http
POST /api/v1/integration-api/document-generation-jobs
X-API-Key: spk_...
Idempotency-Key: document-request-1001-v1
Content-Type: application/json

{
  "procurementId": "entity-uuid",
  "kind": "SALES_INVOICE",
  "templateId": "template-uuid",
  "formats": ["pdf"],
  "scope": "all",
  "parameters": {
    "dueDate": "2026-08-15"
  }
}

Поле parameters закрытое: неизвестный ключ возвращает 400, а допустимый набор определяется значением kind.

kindДопустимые поля parameters
COMMERCIAL_PROPOSALsellerProfileId, customerId, customerContactId, title, subject, validUntil, plannedDeliveryDate, currencyCode, vatMode, paymentTermsText, deliveryTermsText, externalComment
SALES_INVOICEsellerProfileId, customerId, customerContactId, proposalId, dueDate, currencyCode, vatMode, paymentTermsText, externalComment
CONTRACTsellerProfileId, customerId, customerContactId, proposalId, title, subject, validUntil, currencyCode, totalAmount, paymentTermsText, deliveryTermsText, externalComment, assignedToId
Транспортные и сопроводительные документыlogisticsObjectIds, routeIds, batchIds, carrierName, carrierInn, driverName, driverPhone, driverLicense, vehicleNumber, vehicleModel, trailerNumber, attorneyName, attorneyPosition, attorneyPassport, attorneyBasis, recipientName, deliveryAddress, comment

К транспортным и сопроводительным относятся GOODS_WAYBILL, TRANSPORT_WAYBILL, GOODS_TRANSPORT_WAYBILL, POWER_OF_ATTORNEY_RECEIPT, ROUTE_SHEET, ACCEPTANCE_ACT, PICKING_LIST, DELIVERY_REQUEST, PRODUCTION_TRANSFER_WAYBILL и DISCREPANCY_ACT. Все идентификаторы имеют формат UUID, даты — ISO 8601, currencyCode — три заглавные буквы, а vatMode принимает только EXCLUSIVE, INCLUSIVE или NO_VAT. При scope: selected_items массив selectedItemIds обязателен и содержит только позиции указанной закупки.

http
GET  /api/v1/integration-api/document-generation-jobs/:jobId
GET  /api/v1/integration-api/generated-documents
GET  /api/v1/integration-api/generated-documents/:documentId
POST /api/v1/integration-api/generated-documents/:documentId/download-url

Повтор create-запроса с тем же Idempotency-Key возвращает исходное задание. Короткоживущая ссылка скачивания выдаётся только отдельным запросом и не передаётся в webhook. Для download URL одновременно требуются documents.read и documents.download.

Партии доставки и рейсы

http
GET  /api/v1/integration-api/delivery-batches
GET  /api/v1/integration-api/delivery-batches/:id
GET  /api/v1/integration-api/delivery-trips
POST /api/v1/integration-api/delivery-trips
GET  /api/v1/integration-api/delivery-trips/:id
POST /api/v1/integration-api/delivery-trips/:id/commands/:command

Списки используют cursor pagination. Следующая страница запрашивается с pageInfo.nextCursor.

Опубликованные команды рейса: plan, dispatch, arrive-stop, complete-stop, complete. Изменяющие запросы требуют:

  • Idempotency-Key;
  • version в body либо If-Match: W/"<version>";
  • любой разрешённый read-scope (delivery_trips.read или logistics.read) и любой разрешённый write-scope (delivery_trips.write или logistics.write); смешанная пара также допустима.

Ответ рейса содержит version, а HTTP-ответ — соответствующий ETag. При устаревшей версии API возвращает 409 Conflict.

Variable API

Variable API использует тот же заголовок X-API-Key, но отдельные маршруты:

http
GET  /api/v1/variables
POST /api/v1/variables/resolve

Требуются variables.read и read-scope запрошенного домена. Каталог и значения фильтруются по текущему ключу; поля других доменов не возвращаются.

Лимиты запросов

По умолчанию Integration API допускает 300 запросов в минуту на ключ. Ответы содержат RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset и RateLimit-Policy.

При превышении лимита API возвращает 429 Too Many Requests и Retry-After.

Ошибки

HTTPЗначение
400Запрос не соответствует опубликованной схеме
401Ключ отсутствует, недействителен или истёк
403Недостаточно scopes либо ресурс недоступен ключу
404Опубликованная сущность не найдена в доступной области
409Конфликт версии, статуса или идемпотентности
429Превышен лимит запросов

Связанные страницы

Документация платформы SNABZHENETS+.