Navbar

Workbook

Что нужно знать для начала работы с JSON API

Ограничения

JSON API доступен пользователям на всех тарифах, но на бесплатных тарифах доступен не весь функционал.

Для JSON API установлены следующие ограничения:

Также накладывается ограничение на максимальное число объектов (позиций, материалов, продуктов), передаваемых в одном массиве в запросе - не более 1000 элементов. В случае, если количество элементов коллекции превышает максимально допустимое, произойдёт ошибка со статусом 413. Если количество позиций превышает максимально допустимое, то для дальнейшего пополнения позиций нужно будет работать со специальным ресурсом, описание которого приведено в конкретной сущности.

Оптимизация количества запросов к JSON API

Частой проблемой исчерпания лимитов по запросам является ненастроенная интеграция. В данном разделе приведены основные ошибки при работе с JSON API, а также описаны варианты их решения.

Проблема повторяющихся запросов

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

Проблема избыточных запросов

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

Настройка переиспользования соединений

При большом количестве запросов открытие TCP соединения на каждый приводит к бану. Чтобы этого избежать, рекомендуется настроить переиспользование соединений (HTTP keep-alive/HTTP persistent connection).

При установлении соединения напрямую с МоимСкладом настройка keep-alive производится в библиотеке для http-запросов. При использовании proxy-сервера настройка выполняется на его стороне.

Увеличьте количество и время неактивности TCP соединений. Однако не рекомендуется использовать TCP соединения, неактивные более 30 секунд или делать более 100 запросов через одно соединение: это может приводить к 500м ошибкам.

Чтобы начать нужны

Первый запрос

Для запросов JSON API используются логин и пароль аккаунта МоегоСклада (Basic Auth) или токен для Аутентификации в json api.

Создадим первый товар. Для этого нужно только его наименование.

login:password - логин и пароль от МоегоСклада

Authorization: Bearer - токен для Аутентификации в json api

Content-Type: application/json - JSON API работает только с json

Lognex-Pretty-Print-JSON: true - заголовок, включающий вывод форматированного json

Метаданные

В начале каждого из ответов eсть поле meta, представляющее метаданные. В JSON API метаданные бывают нескольких видов.

Еще один вид метаданных - метаданные сущности - информация, относящаяся не к конкретному объекту, а ко всем объектам определенного типа, например списки дополнительных атрибутов, статусов

Обработка ошибок

Ошибки возвращаются в виде массива errors, содержащего объекты error, каждый из которых описывает отдельную ошибку.

Подробнее о структуре и видах ошибок в документации.

Методы HTTP (GET, POST, PUT, DELETE)

В JSON API различным методам HTTP соответствуют различные действия:

Метаданные товара содержат ссылку на этот товар ("href":"https://api.moysklad.ru/api/remap/1.2/entity/product/6b44332f-b0ac-11ea-ac14-000a00000002") - ее можно использовать для запроса конкретно этого товара.

Либо для изменения этого товара:

А также для удаления товара:

При успешном удалении возвращается пустой ответ с кодом 200, иначе ошибка с кодом 404.

Если нужно удалить больше чем один товар, то можно воспользоваться массовым удалением. Для этого нужно послать post запрос, в теле которого указать meta удаляемых сущностей. Результатом успешного удаления будет сообщение об успешном удалении сущностей.

Пустые поля

У товаров есть необязательное поле country (страна). Создавая товар мы его не заполнили, поэтому в выдаче этого товара оно отсутствует:

Заполним страну у товара. Поля, которые являются объектами, нужно передавать в виде метаданных

Чтобы удалить значение из поля типа объект, в запросе на обновление сущности нужно передать в данном поле null. Это возможно, если поле не является обязательным, или же если данное поле в основном интерфейсе может содержать пустое значение. Например, удалим у товара страну

Формат даты и времени

В JSON API поля типа дата-время (момент времени) - это строка в формате:

В параметрах фильтрации нужно указывать поля типа дата-время именно в этом формате.

Разделение на entity, report и context

Большинство методов JSON API разделены на три больших раздела - entity, report и context.

Все рассмотренные выше методы относятся к entity - работа с сущностями типа product (товар). Возможности фильтрации и сортировки определяются структурой полей конкретного типа. Каждая сущность имеет уникальный id, и существуют методы по работе с отдельными объектами.

Структура отчетов, а также возможности фильтрации специфичны для каждого отдельного отчета. Отчеты представляют собой определенный срез информации на основе совокупности документов. Для примера рассмотрим отчет остатков товаров на складе. Мы создали один товар и не создавали никаких документов, поэтому количество этого товара равно нулю. По умолчанию ненулевые остатки в этом отчете скрыты. Для того, чтобы они отобразились в запросе, использован параметр stockMode со значением all.

Фильтрация, листание, поиск и сортировка

Фильтрация

Для фильтрации выборки по нескольким полям используется url параметр filter. Значение этого параметра - urlencoded строка с поисковыми условиями, перечисленными через ';'. Каждое поисковое условие - это сочетание названия поля, оператора и константы. Фильтрация недоступна для полей-массивов (например поле barcodes).Фильтрация товаров по имени и времени обновления "filter=name=Новое наименование;filter=updated>2018-01-01 00:00:00"

Листание

Большинство списков и отчетов поддерживают листание. За него отвечают два параметра:

Если при запросе списка, возвращаются не все элементы, в метаданных коллекции присутствуют специальные поля: previousHref и nextHref, представляющие запросы предыдущей и следующей страниц данных.

Рассмотрим на примере запроса стран.

Поиск

В JSON API можно осуществлять контекстный поиск среди списка сущностей определённого типа по их строковым полям. Проверка уникальна для каждой сущности. Поиск работает по префиксам слов. Для этого используется url параметр поиска search

Результатом поиска будет отсортированный по релевантности список сущностей данного типа, прошедших фильтрацию по переданной поисковой строке. В отличии от фильтрации выборки с помощью параметра filter, при которой значения проверяются на точное совпадение, при контекстном поиске проверка на совпадение не строгая.

Контекстный поиск стран "search=мари"

Сортировка

Для сортировки списка объектов используется url параметр order. Значение этого параметра - urlencoded строка с условиями сортировки, перечисленными через ';'. Каждое условие сортировки - это сочетание названия поля, запятой (опционально, если указывается направление сортировки), направления сортировки (опционально: может принимать значения asc и desc. Значение по умолчанию - asc).

Сортировка поддерживается для следующих типов полей: числовой, строковый, дата-время, логический и uuid.

Что такое expand

В JSON API в составе сущностей поля, которые являются объектами, выводятся в виде метаданных. Для того, чтобы вместо ссылок получить сами связанные объекты, не обязательно делать отдельные запросы для каждого из них. Вместо этого, вместе с запросом на получение сущности, нужно передать параметр expand. В качестве значения данного параметра нужно перечислить через запятую все необходимые поля, на месте которых вы бы хотели видеть объекты.

На expand действуют следующие правила:

Например, у товара есть поле owner (ссылка на Сотрудника), а у сотрудника есть поле group (отдел сотрудника). Запросим товар, чтобы у него был развернут owner, а у owner был развернут group.

Больше примеров и информации можно найти в разделе замена ссылок объектами с помощью expand.

Вебхуки

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

Что такое вебхук?

Вебхук - это механизм отправки уведомлений при наступлении в системе события, на которое подписано клиентское приложение. Под событием понимается изменение состояния системы. Например, событиями являются: создание нового товара, изменение полей у контрагента, удаление заказа покупателя. Уведомлением будет запрос метода POST, который будет содержать следующую информацию о наступившем событии: его тип и ссылку на изменившийся объект. Например, при изменении наименования товара, будет отправлено уведомление, которое будет содержать ссылку на измененный товар.

Непосредственно сам вебхук содержит описание изменения (тип объекта и ссылку на изменившийся объект), которое отправляется на указанный url.

В чем разница между АПИ и вебхуками

Есть 2 подхода для получения сведений об изменениях в системе: опрос через АПИ (polling) и подписка на вебхуки. Опрос через АПИ предполагает циклические запросы, чтобы получить изменения. Подписка на вебхуки предполагает получение уведомления об изменении в системе. Можно провести следующую аналогию. Предположим вы заказали товар, но его не оказалось в наличии, поэтому вы каждый день звоните в магазин, чтобы узнать о появлении товара, это похоже на опрос через АПИ. Но вы можете просто попросить менеджера в магазине позвонить вам по указанному номеру телефона, когда товар появится, это подписка на вебхуки. Очевидно, что подписка на вебхуки эффективнее и проще, так как гарантируется оперативное получение изменений в системе и меньшая нагрузка на клиентское приложение.

Когда нужно использовать АПИ, а когда вебхук

Несмотря на преимущество использования вебхуков, важно понимать, что подписка на вебхуки это всего лишь форма уведомления об изменениях в системе. Действия с сущностями (CRUD) необходимо выполнять с помощью АПИ.

Возможные сценарии, когда подписка на вебхуки выглядит предпочтительнее опросов через JSON API:

Как использовать вебхуки через JSON API

Вебхуки в JSON API

Работа с вебхуками в МоемСкладе возможна только через JSON API. Методы работы с вебхуками позволяют создать, удалить, обновить, получить и отключить вебхуки.

Ключевыми признаками вебхука являются адрес отправки (url), тип сущности (entityType) и тип события (action). Пара признаков (entityType и action) должна быть уникальной, т.е. не может повторяться в других вебхуках. Существуют следующие типы событий (action):

Данные типы событий могут быть применимы ко всем типам сущностей (базовые сущности и документы). Обратите внимание, что отчеты и аудит не являются сущностями.

Рассмотрим методы работы с вебхуками. Для создания вебхука достаточно указать url, entityType и action, как в примере ниже

В ответ должен придти json, содержащий описание вебхука

Как и в других запросах сущностей JSON API другие действия над вебхуками возможны только при указании идентификатора. В полученном json поле id. Пример получения вебхука по идентификатору.

У вебхука можно изменить поля, указанные при создании, а также включить/отключить его. Для этого выполняется PUT запрос с указанием идентификатора. Пример запроса с изменением события

Ограничения при работе с вебхуками

При работе с вебхуками есть ряд важных замечаний:

Отправка вебхука в клиентское приложение

МойСклад отправляет вебхук в клиентское приложение с помощью метода POST, указывая заголовок User-Agent со значением MoySklad webhook touch agent 2.0 (/https://www.moysklad.ru). МойСклад добавляет к указанному адресу отправки (url) параметр запроса requestId - идентификатор уведомления.

При отправке уведомления вебхука, МойСклад ожидает ответ от клиентского приложения со статусом 200 или 204 в течение 1500 миллисекунд, чтобы считать уведомление доставленным. При невалидном ответе от клиентского приложения наша система осуществляет еще 3 попытки отправки. Данные попытки осуществляются последовательно, без таймаутов между ними. Если все попытки закончились неудачно или истекло время ожидания ответа - данное уведомление считается неотправленным и в дальнейшем удаляется, в клиентское приложение оно отправлено не будет, т.к. проблема на стороне клиентского приложения. Чтобы избежать неудачи при отправке уведомления из-за истечения времени ожидания ответа сервером и повторной отправки того же уведомления, рекомендуется разделить прием вебхуков и их обработку. Понять, что уведомление о событии было отправлено повторно, можно по параметру запроса requestId - при повторной отправке уведомления идентификатор останется прежним.

Как проверить, что вебхук работает?

Для проверки работоспособности вебхука удобен сервис https://webhook.site/. Он создает уникальный тестовый url, который необходимо указать в вебхуке, и интерактивно показывает входящие запросы, т.е. уведомления вебхуков.

  1. Переходим на сайт useful image
  2. Получаем уникальный url. Необходимо скопировать его, чтобы использовать при создании вебхука. useful image

3. Создаем вебхук, в примере ниже вебхук на создание услуги

4. Создаем услугу в МоемСкладе, в примере ниже создание услуги через JSON API

5. На наш уникальный адрес пришло уведомление!

useful image

Метаданные

Одним из ключевых понятий при работе с JSON API является понятие метаданных. В JSON API существует несколько типов метаданных:

Под метаданными объекта (конкретный объект в МоемСкладе, например, товар "Мяч футбольный") понимается краткое представление этого самого объекта в поле meta. Метаданные коллекции представляют элемент, описывающий размер коллекции, размер выборки, который вернулся запросом, пагинацию. Метаданные сущности описывают поля, относящиеся ко всему классу (например, ко всем товарам): статусы, типы цен, доп.поля и т.д.

Рассмотрим перечисленные типы метаданных подробнее.

Метаданные объекта

Возвращаемые JSON API объекты содержат поле meta, которое, по сути, является ссылкой на объект. Однако, meta не простое поле, a составной json-элемент, содержащий краткое описание объекта. Поле meta состоит из следующих атрибутов:

Рассмотрим запрос контрагента ООО "Поставщик"

В ответе содержится несколько полей meta. Вначале описывается сам объект, с указанием типа объекта, ссылки в JSON API и ссылки на веб-версию

Ссылки на сотрудника, создавшего контрагента, и отдел сотрудника указаны в полях owner и group, и содержат также поля meta.

Очевидно, что поля href и uuidHref содержат url для доступа к объектам и могут быть использованы для запроса. Например, используя значение поля href, запросим данные сотрудника

Аналогично и для значения из поля uuidHref можно открыть объект в веб-версии. useful image

Использование meta при создании/изменении объекта

meta используется в качестве ссылки на другой объект, рассмотрим на примерах.

Имея метаданные товара json "meta":{ "href":"https://api.moysklad.ru/api/remap/1.2/entity/product/3b336cc5-d10a-11e8-ac12-000b00000021", "metadataHref":"https://api.moysklad.ru/api/remap/1.2/entity/product/metadata", "type":"product", "mediaType":"application/json", "uuidHref":"https://online.moysklad.ru/app/#good/edit?id=3b335997-d10a-11e8-ac12-000b0000001f" } Выполним запрос на создание комплекта, указав товар в компонентах

В ответ получим новый комплект, который содержит указанный товар

Изменим товар, указав ему единицу измерения. При условии, что у товара еще не указана единица измерения.

В ответе видно, что единица измерения, поле uom, изменилось на переданный объект.

Метаданные коллекции

Для работы с пагинацией у коллекций в JSON API формируется несколько иное поле meta. Поле meta коллекций содержит частично те же атрибуты (href, type, mediaType), что и meta объектов, и ряд собственных атрибутов:

Например, при запросе вебхуков

будет следующий ответ

где видно, что коллекция содержит один элемент, и size также имеет значение равное 1.

Если значение атрибута size больше limit, то дополнительно выводятся атрибуты пагинации:

Добавим новые вебхуки и запросим их, но с лимитом равным 1

Применив лимит, была сформирована ссылка пагинации nextHref на следующую страницу коллекции. Перейдем по ней.

Как видим, были сформированы ссылки пагинации, доступные для перехода на следующую и предыдущую страницы коллекции.

Метаданные сущности

Кроме использования поля метаданных в качестве внешней ссылки и представления коллекции, метаданные могут описывать непосредственно сами сущности. Как правило, это описание вложенных сущностей, коллекций и дополнительных полей. Чтобы получить метаданные сущности, необходимо использовать ссылку из поля metadataHref. Запросим метаданные сущности контрагента из примера выше

В данном примере по запросу вернулись значения доп.полей, статусов и групп контрагентов. Подробнее о ресурсе метаданных сущностей можно узнать в документации.

Листание

Если у вас несколько документов одного типа, то при запросе:

вы получите не полный список документов (далее коллекция), а только первую 1000 документов.

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

Параметр limit

Для того, чтобы задать количество документов в коллекции необходимо использовать параметр limit.

Например, если хотите получить первые 10 заказов:

Если хотите получить первые 10 позиций конкретного заказа:

Параметр offset

Для того, чтобы пропустить вывод первых N объектов используется параметр offset. Данный параметр означает "сдвиг" указателя по коллекции, его можно понимать как "покажи мне Limit объектов, пропустив первые offset объектов."

Пример запроса заказов, пропустив первые 2 заказа:

Также можно использовать сдвиг и в списке позиций:

Комбинации offset и limit

Давайте представим, что мы читаем книгу, содержание которой, это все заказы. Тогда каждый запрос это страница, на каждой странице limit слов. Номер слова, с которого начинается страница, это offset. Например, мы прочли 4 страницы по 40 слов и хотим прочесть следующую страницу. Тогда offset = 160, limit = 40, т.е. запрос будет таким:

В таком виде вы получите в мете ответа 2 дополнительных параметра:

При таком запросе

Сортировка

Для большинства коллекций, возвращаемых JSON API, доступна сортировка.

Сортировка поддерживается для следующих типов полей:

Доступные поля для сортировки

В зависимости от вызываемого endpoint'а сортируемые поля могут отличаться. В таблицах ниже представлены сортируемые поля справочников и документов.

Endpoint (справочники) Сортируемые поля
Контрагент id, version, updated, updatedBy, name, description, code, externalCode, archived, created, phone, email, fax
Ассортимент name, code
Валюта id, name, archived, default, fullname, code, isoCode, multiplicity
Товар id, version, updated, updatedBy, name, code, externalCode, archived, pathName, isSerialTrackable, weighed, weight, volume, syncId
Услуга id, version, updated, updatedBy, name, code, externalCode, archived, pathName, syncId
Комплект id, version, updated, updatedBy, name, description, code, externalCode, archived, pathName, article, weight, volume, syncId
Модификация id,version, updated,updatedBy, name, description, code,externalCode
Группа товаров id, version, updated, updatedBy, name, externalCode, archived, pathName
Серия id,version, updated,updatedBy, name, description, code,externalCode
Договор id, version, updated, updatedBy, name, description, code, externalCode, archived, moment
Проект id,version, updated,updatedBy, name, code,externalCode, archived
Статья расходов id,version, updated,updatedBy, name, description, code,externalCode
Страна id,version, updated,updatedBy, name, description, code,externalCode
Отдел id
Единица измерения id, version, updated, name, description, code, externalCode
Сотрудник id, version, updated, updatedBy, name, description, externalCode,archived,email,phone,lastname, firstname, middlename, uid
Склад id,version, updated,updatedBy, name, description, code, externalCode, address, archived, pathName
Юрлицо id,version, updated,updatedBy, name, description, code,externalCode, archived, created, inn, actualAddress, legalTitle, legalAddress, kpp, phone, email, fax
Техкарта id, syncId, version, updated, updatedBy, name, description, externalCode
Точка продаж id,version, updated,updatedBy, name, description, externalCode, address, active
Задача id, created, version, updated, description, dueToDate, done
Endpoint (документы) Сортируемые поля
Розничная смена id, syncId, version, updated, updatedBy, name, description, externalCode, moment, applicable, sum, created, closeDate
Оприходования id, syncId,version, updated,updatedBy,name, description, externalCode,moment, applicable,sum, created
Заказ покупателя id, syncId,version, updated,updatedBy,name, description, externalCode,moment, applicable,sum, created, deliveryPlannedMoment
Заказ поставщику id, syncId,version, updated,updatedBy,name, description, externalCode,moment, applicable,sum, created, deliveryPlannedMoment
Счет покупателю id, syncId, version, updated, updatedBy, name, description, externalCode, moment, applicable, sum, created, paymentPlannedMoment
Счет поставщика id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, incomingNumber, incomingDate, paymentPlannedMoment
Входящий платеж id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, paymentPurpose, incomingNumber, incomingDate
Исходящий платеж id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, paymentPurpose
Приходный ордер id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, paymentPurpose
Расходный ордер id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, paymentPurpose
Отгрузка id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Приемка id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Списание id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Перемещение id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Розничная продажа id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Розничный возврат id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Внесение денег id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Выплата денег id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Возврат покупателя id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Возврат поставщику id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Счет-фактура выданный id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Счет-фактура полученный id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Инвентаризация id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Полученный отчет комиссионера id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, incomingDate
Выданный отчет комиссионера id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Прайс-лист id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created
Заказ на производство id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, deliveryPlannedMoment, quantity
Техоперация id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, quantity
Внутренний заказ id, syncId,version, updated,updatedBy, name, description, externalCode,moment, applicable, sum, created, quantity

Как использовать сортировку через JSON API

Для применения сортировки к коллекции необходимо добавить в запрос order=[field name],[asc/desc], где field name - имя поля для сортировки. Опционально через запятую можно указать направление сортировки:

Например, для сортировки поля name по возрастанию нужно использовать ?order=name, asc или ?order=name, а по убыванию ?order=name,desc.

Сортировка также доступна одновременно для нескольких полей, поля для сортировки необходимо указывать через разделитель ;. Например, ?order=name,asc;code,desc.

Рассмотрим применение сортировки. Предварительно создадим товары с различными наименованиями, которые могут начинаться с латиницы, кириллицы, цифр или специальных символов.

Чтобы получить коллекцию товаров, отсортированных по имени, необходимо указать поле name и направление сортировки, как в примере ниже

Ответ будет содержать следующий порядок по возрастанию:

name
12345
Pencil
Pencil 123
Pencil Blue
Pencil Red
!!! Карандаш
Карандаш 123
Карандаш желтый
Карандаш зеленый
!!! Это карандаш

Изменим направление сортировки

name
!!! Это карандаш
Карандаш зеленый
Карандаш желтый
Карандаш 123
!!! Карандаш
Pencil Red
Pencil Blue
Pencil 123
Pencil
12345

Попробуем отсортировать товары одновременно по убыванию логического поля weighed и по возрастанию поля name.

weighed name
true 12345
true Pencil Blue
true Карандаш желтый
false Pencil
false Pencil 123
false Pencil Red
false !!! Карандаш
false Карандаш 123
false Карандаш зеленый
false !!! Это карандаш

Добавим еще сортировку по числовому полю weight.

weighed weight name
true 0.12 Карандаш желтый
true 0.11 Pencil Blue
true 0.1 12345
false 0.4 Карандаш зеленый
false 0.32 Карандаш 123
false 0.2 Pencil Red
false 0.1 !!! Карандаш
false 0.1 !!! Это карандаш
false 0.01 Pencil
false 0.01 Pencil 123

Кроме текстовых, числовых и логических полей доступна сортировка по полям типов uuid и дата-время. Например, применим сортировку по полю syncId.

syncId name
1b7c97cf-cf77-4f7e-b200-d264125578ab Pencil Red
2b7c97cf-cf77-4f7e-b200-d264125578ab !!! Карандаш
3b7c97cf-cf77-4f7e-b200-d264125578ab Pencil 123
3d7c97cf-cf77-4f7e-b200-d264125578ab !!! Это карандаш
4b7c97cf-cf77-4f7e-b200-d264125578ab Карандаш 123
5b7c97cf-cf77-4f7e-b200-d264125578ab Pencil
7b7c97cf-cf77-4f7e-b200-d264125578ab Карандаш желтый
8b7c97cf-cf77-4f7e-b200-d264125578ab 12345
8c7c97cf-cf77-4f7e-b200-d264125578ab Карандаш зеленый
null Pencil Blue

У товара Pencil Blue отсутствует значение поля поэтому при сортировке по возрастанию, оно выводится в конце. Аналогичное поведение и для других полей со значением null.

Работа с остатками

JSON API позволяет получить информацию об остатках в разном виде в зависимости от задачи.

Полная синхронизация по товарам и остаткам

Вы можете провести полную синхронизацию с МоимСкладом, чтобы загрузить всю информацию о товарах (штрихкод, цены, описание, изображения) и их остатках. Для этого можно использовать Расширенный отчет об остатках или Отчет по остаткам в разрезе по складам. Также можно провести полную синхронизацию через запрос ассортимента.

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

Обновление информации по остаткам

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

Чтобы сократить объем передаваемых данных, при запросе Краткого отчета об остатках используйте параметр changedSince. Параметр позволяет получать данные об остатках только для тех товаров, чьи остатки изменились за период с changedSince по текущий момент. Это значительно сокращает время на обработку запроса.

Если заказы, приемки, отгрузки и другие документы создаются нерегулярно, подпишитесь на Вебхуки на изменение остатков по товарам или складам. Вебхуки позволяют получать уведомления об изменениях и запрашивать остатки только тогда, когда есть изменения. Получив уведомление, запросите данные по ссылке в вебхуке.

Регулярное обновление данных по товарам

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

Публикация документов

МойСклад позволяет печатать документы - формировать файлы в формате pdf или xls по специальным шаблонам, которые называются шаблонами печатных форм. Для большинства документов есть встроенные шаблоны, о создании собственных шаблонов можно прочитать в статье поддержки.

Публикация - это ссылка на печатную форму документа. Ее можно отправить по электронной почте. При публикации файлы формируются только в формате pdf. Публикации доступны для следующих видов документов:

Шаблоны печатной формы

В JSON API возможно запросить списки встроенных и пользовательских шаблонов печатных форм, чтобы впоследствии использовать их для печати и публикации документов.

По ссылке из поля content можно скачать сам шаблон.

Изменение или удаление шаблонов печатных форм через JSON API невозможно.

Создание публикаций в JSON API

Создание публикаций возможно средствами JSON API. Чтобы создать публикацию нужен документ, например, заказ покупателя, и шаблон печатной формы - встроенный или пользовательский.

Создадим публикацию для заказа покупателя

В ответ возвращается JSON представление публикации. Если такая публикация уже существовала, код ответа 200. Если публикация была создана - 201.

Список всех публикаций

Также можно запросить список всех публикаций документа.

Удаление публикаций

Через JSON API можно удалить публикацию:

Ссылки публикаций

По ссылке публикации (например, https://mskld.ru/7sDZyGqk5M) открывается страница, с которой можно скачать pdf-документ.

useful image

По ссылке будет доступна самая последняя версия документа, даже если вы вносите изменения в документ после его публикации.

Ссылка будет доступна, пока не удалена публикация.

Работа с дополнительными полями через JSON API

Для задания дополнительных свойств объекта в сервисе МойСклад есть возможность работы с дополнительными полями (атрибутами). Они представляют собой свойства сущности (объекта или документа), которые формируются пользователем и могут быть использованы для более подробного описания объекта или фильтрации по значениям этих полей. Подробнее о типах и свойствах дополнительных полей можно прочитать в документации.

В данной статье рассмотрим на примере магазина ноутбуков просмотр, создание, редактирование и удаление дополнительных полей средствами JSON API.

Значения дополнительных полей можно менять, обращаясь к конкретному объекту (документу). Это подробно описано в статье Дополнительные поля.

Предположим, что нам необходимо выбирать и сортировать ноутбуки по некоторым характеристикам, которых нет в свойствах товара по умолчанию. Например, материал корпуса, наличие CD/DVD-Rom, наличие разъема Type-C и т.д. Нужна возможность создавать, редактировать и удалять свойства товаров. Присваивать конкретным товарам значения этих свойств, а также осуществлять фильтрацию по ним. Фильтрация по значениям дополнительных полей в JSON API описана в статье Дополнительные поля. Для создания указанных характеристик будем использовать дополнительные поля (атрибуты) товара.

В web-приложении атрибуты объектов назначаются на странице списка объектов при нажатии на кнопку с шестеренкой справа. Открывается окно редактирования свойств объектов, где последним пунктом идет "Дополнительные поля". Здесь доступен просмотр, создание, редактирование и удаление атрибутов объекта. Весь этот функционал доступен и через JSON API.

Процесс создания атрибута товара через UI Settings UI

Creating attribute

Created attribute

UI filter

Дополнительные поля Услуг, Модификаций и Комплектов

Дополнительные поля у Товаров, Услуг, Модификаций и Комплектов общие и располагаются в метаданных Товаров.

Создание нового дополнительного поля через JSON API

Рассмотрим задачу добавления новых атрибутов к сущности (товару). Предположим, что хотим для имеющихся и закупаемых в будущем ноутбуков указывать материал корпуса. Для его указания будем пользоваться дополнительным полем типа строка. Этот пример рассмотрен в скриншотах web-приложения выше. Теперь попробуем сделать то же через JSON API.

Выполним POST-запрос, в теле которого укажем название и тип дополнительного поля (атрибута). Для этого достаточно в теле запроса указать обязательные поля "name" и "type". В данном случае добавим строковое поле, описывающее материал корпуса ноутбука.

Кроме имени и типа у создаваемого атрибута есть следующие поля:

Создание двух дополнительных полей с одинаковыми именами запрещено.

Создано дополнительное поле (атрибут), ему автоматически присвоен id. Значение свойства required по умолчанию устанавливается в false, что делает созданный атрибут не обязательным для заполнения при создании товара.

Создание нового дополнительного поля типа Справочник через JSON API

Стоит обратить внимание на создание атрибута с типом Справочник. Этот тип позволяет атрибуту принимать в качестве значения другие объекты, в том числе и пользовательские.

Описание атрибутов типа Справочник в документации

Предположим, что в нашем магазине есть также чехлы для ноутбуков. Создадим атрибут Справочник типа Товар. Теперь Появилась возможность для каждого ноутбука указать подходящий ему чехол как одно из свойств ноутбука.

Для создания атрибута Справочник типа товар нужно указать в поле "type" значение "product". В поле "name" укажем "Чехол".

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

Массовое создание(обновление) дополнительных полей через JSON API

С приходом в магазин новых моделей ноутбуков может появиться необходимость в создании новых атрибутов. Например, тип разъемов на ноутбуках некоторых производителей меняется с такой частотой, что предугадать заранее их тип и наличие невозможно. В таком случае может понадобиться добавление новых и редактирование существующих атрибутов.

В JSON API доступно массовое создание дополнительных полей. Для этого надо передать в теле POST-запроса массив со свойствами каждого из создаваемых атрибутов. Массив должен содержать данные по каждому создаваемому полю, перечисленные через запятую и заключенные в фигурные скобки. Обязательные к передаче свойства - это имя и тип поля. Если добавить к ним "meta" существующего дополнительного поля, то оно будет изменено. Сформируем тело запроса из 3 элементов. Для поля "Материал корпуса" укажем его "meta", свойство "name" изменим на "Материал корпуса (дополнение)". Новое значение свойства "name" не должно совпадать с существующими. Свойство "type" не может быть изменено. Два других элемента массива будут созданы, им автоматически присвоятся метаданные.

После выполнения данного запроса поле "Материал корпуса" обновится на "Материал корпуса (дополнение)". Добавятся новые поля "Наличие CD-Rom" и "Наличие type-C разъема" с типом флажок.

Вывод дополнительных полей через JSON API

Для отображения списка атрибутов сущности (в данном случае товара) нужно выполнить GET-запрос

Если указать в запросе id конкретного атрибута, то получим только его.

Редактирование дополнительных полей через JSON API

Если нужно изменить одно дополнительное поле без затрагивания существующих, удобно пользоваться следующим запросом. Например, нужно изменить название атрибута, чтоб сделать его блоее полным. Изменим название атрибута "Наличие CD-Rom" на "Наличие CD/DVD-Rom".

Для изменения свойств существующего дополнительного поля необходимо выполнить PUT-запрос, содержащий его id, а в теле запроса передать изменяемые свойства. Следует учесть, что свойство "type" не может быть изменено. Изменим название атрибута "Наличие CD-Rom":

Поле "Наличие CD-Rom" изменено на "Наличие CD/DVD-Rom". Неуказанные свойства останутся без изменений.

Удаление дополнительного поля через JSON API

Некоторые атрибуты могут стать неактуальными. Например такую полезную вещь как DVD-привод найти становится всё труднее. Такие дополнительные поля можно удалить, даже если они были назначены обязательными и были заполнены. Для удаления дополнительного поля через JSON API необходимо выполнить DELETE-запрос, содержащий id поля.

Получим пустой ответ со статусом 200. Атрибут с указанным id будет удален.

Массовое удаление дополнительных полей через JSON API

Для удаления сразу нескольких атрибутов нужно выполнить следующий POST-запрос, указав в теле meta-данные удаляемых полей:

Также получим пустой ответ со статусом 200. В результате удалены указанные атрибуты. Если в теле такого запроса указать meta несуществующего атрибута, то весь запрос не выполнится, даже если в нем присутствуют существующие meta.

Список сущностей

Список сущностей, для которых есть возможность создать доп. поля, вы можете посмотреть в документации

Работа с дополнительными полями в JSON API

В рамках JSON API можно создавать дополнительные поля и редактировать существующие. Подробно это описано в статье Работа с дополнительными полями через API.

Получение дополнительных полей

Доп. поля располагаются в метаданных необходимой сущности. Пример получения дополнительных полей товара:

Задание значений дополнительных полей через JSON API

Задать значение дополнительному полю можно как при создании объекта, так и при его обновлении.

Полученные в предыдущем примере идентификаторы дополнительных полей товаров можно использовать при создании новых товаров. Дополнительное поле "Подсветка клавиатуры" не является обязательным (required=false) и не передается в примере ниже.

Для нового товара "Ноутбук" мы указали значения двух дополнительных полей - Время работы от аккумулятора и Ссылка на интернет-магазин.

При обновлении товара мы можем как обновить уже имеющиеся значения дополнительных полей, так и задать новые.

В примере мы обновили значение поля Время работы от аккумулятора, проставленное при создании товара, а также задали значение полю Подсветка клавиатуры - при создании мы оставили его пустым.

Также для необязательных полей есть возможность обнулить значение поля. Для этого в поле value необходимо передать значение null.

Если в теле запроса на обновление/создание сущности в массиве дополнительных полей:

Возможные типы дополнительных полей

С возможными типами дополнительных полей вы можете ознакомиться в документации.

Дополнительное поле типа Файл

Для загрузки значения дополнительного поля типа файл нужно в поле file указать объект следующей структуры:

Пример создания товара с дополнительным полем типа Файл приведен ниже. Для краткости приведено неполное значение содержимого файла.

Дополнительное поле типа Справочник

Дополнительное поле типа Справочник ссылается на объект определенного справочника. Это может быть один из встроенных справочников: Товары, Контрагенты, Договоры, Сотрудники, Проекты, Склады. Или справочник, созданный пользователем.

Рассмотрим пример работы с дополнительными полями типа Справочник на примере контрагентов. В примере для них задано два дополнительных поля: встроенный справочник Проект и пользовательский справочник Регион:

Чтобы задать значение дополнительного поля типа Справочник в поле value нужно передать объект, содержащий поле meta с метаданными объекта, который будет значением дополнительного поля. Создадим контрагента с этими дополнительными полями:

Фильтрация по значению дополнительного поля

JSON API позволяет осуществлять фильтрацию по значению дополнительного поля. На примере дополнительных полей, приведенных выше, можно отфильтровать все товары, у которых значение дополнительного поля Время работы от аккумулятора больше или равно 5:

Для этого нам необходимо в параметре filter указать href дополнительного поля для фильтрации, знак сравнения (в нашем случае >=) и значение. В ответе вернутся все сущности, подходящие под переданный критерий.

Сортировка по дополнительному полю

Сортировка по дополнительным полям в данный момент не поддерживается.

Работа с Изображениями в Товарах, Модификациях и Комплектах

Иногда требуется добавить или изменить несколько изображений для товара. Это можно сделать несколькими способами: обновить список изображений в рамках обновления товара или воспользоваться эндпоинтами для работы с изображениями.

Для добавления изображения нужно задать поля filename и content, соответствующие названию и содержанию файла, закодированному в Base64, соответственно. Если нужно добавить или дублировать уже существующее изображение, то можно указать его meta.

Например, нужно создать Товар с несколькими изображениями. Это можно сделать следующим образом:

Стоит заметить, что в ответе нет перечисления всех изображений, а лишь указана meta для коллекции. Чтобы получить список изображений в рамках товара необходимо дабавить в конец запроса &expand=images&limit=100 при создании, получении или обновлении товара.

Теперь рассмотрим другой вариант работы с изображениями. Предположим, что есть товар, и нужно обновить его изображения. Для этого можно воспользоваться эндпоинтом для работы с изображениями товаров.

Подробнее про работу с изображениями можно прочитать тут.

Работа с Файлами в Документах, Номенклатуре и Контрагентах

Для расширенного описания и дополнения сущностей информацией, в сервисе МойСклад есть возможность работы с Файлами в Документах, Номенклатуре (Товары, Комплекты, Улуги, Модификации), Задачах и Контрагентах. Файлы можно прикрепить к сущностям и запросить их в любой удобный момент. Информация по файлам выводится вместе с json представлением сущности, к которой относится данный файл. Для получения файла необходимо использовать ссылку из описания json представления файла. Подробнее про Файлы и работу с ними можно прочитать в разделе Файлы.

Иногда для описания товара требуется, помимо указания полей, приложить какой-нибудь файл, например сертификат на данный товар или инструкцию по применению. Удобнее всего такие файлы держать рядом с описанием товара, к которому они относятся. Для этого можно воспользоваться новой функциональностью - работа с Файлами.

Например, нужно создать товар и прикрепить к нему инструкцию. Это можно сделать несколькими способами: через интерфейс сайта https://www.moysklad.ru или используя JSON API.

В сервисе МойСклад добавить, удалить или отредактировать список файлов товара можно через окно Карточки товара.

useful image

Для добавления файла через JSON API нужно задать поля filename и content, соответствующие названию и содержанию файла, закодированному в Base64, соответственно. Если нужно добавить или дублировать уже существующей файл, то можно указать его meta.

Стоит заметить, что в ответе нет перечисления всех файлов, а лишь указана meta для коллекции. Чтобы получить список файлов в рамках товара необходимо добавить в конец запроса &expand=files&limit=100 при создании, получении или обновлении товара.

Теперь рассмотрим другой вариант работы с файлами в Товарах. Предположим, со временем понадобилось обновить список файлов для Товара. Например устарела инструкция и нужно удалить старую и прикрепить новую. Это можно сделать через сервис МойСклад, как было указано ранее или воспользоваться средствами JSON API.

Как видно из примера, одним запросом был изменен полный список файлов для Товара. На одновременное добавление и изменение списка файлов через JSON API существует ограничение в 10 элементов. Подробнее описание приведено в разделе Файлы.

Для того, чтобы посмотреть файл, прикрепленный к сущности, его необходимо скачать. Это можно сделать используя ссылку, указанную в downloadHref в meta файла.

Ответ придет со статусом 302 (Found), где в заголовке ответа в Location будет указанна ссылка на скачивание. Важно учитывать то, что переход по данной ссылке уже не требуется заголовок Authorization.

Работа со Штрихкодами

В JSON API появилась возможность работать с различными штрихкодами в товарах, комплектах, услугах, модификациях и упаковках товаров. Поддерживается работа следующих типов штрихкодов:

Штрихкоды предоставляют удобный способ идентификации и работы с номенклатурой. Предположим нужно продавать товар и для удобства его поиска в системе был куплен сканер штрихкодов. После покупки сканера встает задача добавления штрихкодов к номенклатуре. Рассмотрим как это можно сделать на примере товара.

В случае, если штрихкоды больше не нужно использовать для номенклатуры, достаточно обновить товар, указав пустой список штрихкодов.

Работа с характеристиками в Модификациях

Предположим, что имеется магазин по продаже вещей. Ассортимент в магазине обширный и нужно как-то его описать. Сначала разделение было по типам: футболки, джинсы и брюки. Но имеется множество различных футболок, джинс и брюк. Они имеют различные параметры: размер, цвет и т.д. Их нужно как-то различать в системе, чтобы продавать их как отдельные товары. Модификации смогут решить данную проблему. По сути модификация - это товар со специфичными характеристиками, такими как цвет, вес, размер и так далее. Подробнее про работу с модификациями можно прочитать тут.

Прежде чем добавлять новые или использовать старые характеристики модификации нужно понять, какие уже были созданы и используются.

После того, как стало понятно, что каких-то характеристик не хватает, чтобы описать товар, в JSON API имеется возможность добавить недостающие характеристики. Это можно сделать через отдельный эндпоинт для работы с характеристиками.

После того как нужные характеристики были созданы, можно создавать модификации с данными характеристиками.

Работа с асинхронным обменом

Асинхронный обмен предоставляет возможность получать результаты длительных запросов асинхронно, не используя многократные запросы с листанием. В случае большого объема выгружаемых данных использование асинхронного обмена позволяет получить тот же результат, затрачивая меньше времени в блокировках.

Список запросов, для которых реализована возможность работы в асинхронном режиме, вы можете посмотреть в документации.

Рассмотрим преимущество работы с JSON API в асинхронном режиме на некотором примере. Допустим, требуется получить информацию по остаткам всей номенклатуры, чтобы пополнить резервы в магазинах.
При большом количестве номенклатуры и складов, ранее необходимо было запрашивать отчет остатков по складам несколько раз, указывая параметр offset, чтобы получить отчеты по всем позициям. Так как построение объемных отчетов занимает некоторое время, вплоть до 5 минут, сбор всей информации может занять продолжительное время. Кроме того, каждый отдельный запрос вынуждает держать открытое соединение в ожидании результата.

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

1. Создание асинхронной задачи

Делаем запрос остатков с параметром async=true. Параметры строки запроса limit и offset указывать не нужно, так как отчет будет построен полностью. В заголовке ответа Location будет ссылка на получение результата асинхронной задачи, а в заголовке Сontent-Location хранится ссылка на получение статуса выполнения асинхронной задачи. Пока задачи находятся в процессе выполнения, создание новых асинхронных задач будет ограничено текущими лимитами на очередь асинхронных задач и при повторении запроса будет ошибка 61002: Ошибка при создании асинхронной задачи: превышено ограничение на количество одновременно выполняемых асинхронных операций.

2. Опрос состояния асинхронной задачи

Чтобы определить, когда асинхронная задача будет выполнена, необходимо опрашивать статус выполнения асинхронной задачи. Это можно сделать, отправляя запросы на URL из заголовка Content-Location ответа на запрос создания задачи. Если статус задачи (поле state) имеет значение PROCESSING, значит результат задачи еще не готов, и запрос на получение результата нужно повторить через некоторое время. Как только статус задачи примет значение DONE - результат задачи готов, и можно переходить к получению результата.

Также можно следить за статусами выполнения нескольких задач. Для этого можно отправлять запросы на ресурс получения статусов асинхронных задач. Допустим, мы хотим получить все асинхронные задачи, для которых доступен результат. Для этого укажем фильтр на статус задачи со значением DONE и на время удаления меньше текущего времени.

3. Получение результата задачи

Когда статус задачи принимает значение DONE, запрос на получение статуса выполнения задачи содержит дополнительно 2 поля:

Результат запроса по URL из поля resultUrl является перенаправлением со статусом 302 FOUND, и в заголовке Location находится ссылка на файл результата задачи. Большинство HTTP-клиентов выполняют перенаправление автоматически. С момента получения ссылка действительна 5 минут.

Если ваш клиент не выполняет перенаправления автоматически, то для получения требуемого отчета остается отправить GET запрос на URL из заголовка Location.

Полученный отчет имеет незначительные отличия от синхронного варианта: meta не содержит полей limit и offset, а массив rows не ограничивается 1000 элементов.

Если статус задачи имеет значение API_ERROR, то в json ответе на запрос получения результата задачи будет указана ошибка, аналогичная той, которую вернул синхронный вызов ресурса.

Если в процессе выполнения задачи что-то пошло не так, например, у пользователя нет доступа к отчету или не указаны обязательные заголовки, то задача будет помечена как успешно выполненная, а результат будет содержать текст с описанием ошибки.

4. Настройка вебхука на завершение выполнения Асинхронной задачи

Для того, чтобы не опрашивать эндпоинт статуса выполняемой асинхронной задачи можно настроить вебхук на оповещение, когда задача будет завершена. Как и для обычных вебхуков, необходимо задать:

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