API для интеграции каталога товаров ритейл партнера
Цели
- Возможность таргетирования на товары, бренды и категории товаров;
- Возможность при запуске рекламных кампаний учитывать правила, предъявляемые к рекламе на товарах брендов-конкурентов.
- Учет информации об остатках товаров на складах.
Реализация
Прежде чем начать
Вам должен быть известен API URL инстанса рекламной платформы. Попросите команду рекламной платформы выдать его вам.
Внимание
Если предполагается заливать только изменненые продукты (подразумевается как основной подход), то первый раз необходимо будет залить полный слепок текущего каталога и потом уже добавлять итеративно только измененные продукты.
Загрузка информации о товарах осуществляется через HTTP запросы к трем конечным точкам:
/api/v1/store
- для загрузки данных о складах./api/v1/product
- для загрузки данных о товарах./api/v1/remains/bystore
- для загрузки информации об остатках на складах.
Авторизация запросов
API защищено API Key Authentication. Каждый запрос должен содержать специальный API Key в заголовке Authorization. Пример: Authorization: Bearer <api key>
. API KEY будет предоставлен на этапе интеграции с API.
Добавление складов
С помощью PUT запроса на конечную точку /api/v1/store
создаются новые склады и обновляются старые. В теле запроса ожидается массив с объектами, описывающими склад. Система позволяет добавить информацию для одного склада или загрузить все склады одним запросом.
Формат описания склада
Параметр | Тип | Описание | Обязательное |
---|---|---|---|
id | String | Название или порядковый номер | Да |
regions | String[] | Субъекты РФ, обслуживаемые складом. | regions или cities должно быть непустое |
cities | String[] | Названия городов, обслуживаемых складом. | regions или cities должно быть непустое |
[
{
"id": "store_1",
"regions": ["Region"],
"cities": ["City 1", "City 2", "City 3"]
}
]
[
{
"errors": [
{
"fieldName": "cities/regions",
"message": {
"ru": "пустое значение",
"en": "blank value"
},
"errorCode": 400
}
],
"requestJson": {
"id": "store_1",
"cities": [],
"regions": []
}
},
{
"errors": [
{
"fieldName": "id",
"message": {
"ru": "Поле обязательно",
"en": "Field is required"
},
"errorCode": 400
}
],
"requestJson": {
"id": null,
"cities": [],
"regions": ["Region"]
}
}
]
{
"metadata": {
"description": "Request's body schema describing the creation or updating of a product store."
},
"elements": {
"properties": {
"id": {
"type": "string"
},
"regions": {
"elements": {
"type": "string"
}
},
"cities": {
"elements": {
"type": "string"
}
}
}
}
}
Ответ
Тело ответа будет пустым, если запрос выполнился успешно; в противном случае в теле ответа будет указана произошедшая ошибка.
Возможные статусы ответа:
- 200 - Все данные были успешно загружены
- 400 - Валидационные ошибки
- 401 - Неавторизованный (API KEY невалиден или он отсутствует)
- 500 - Внутренняя серверная ошибка
Добавление товаров
С помощью PUT запроса на эндпоинт /api/v1/product
создаются новые товары в каталоге и обновляются старые. В теле запроса ожидается массив с объектами, описывающими товар. Система позволяет добавить информацию для одного товара или загрузить весь каталог одним запросом.
Формат описания товара
Параметр | Тип | Описание | Обязательное |
---|---|---|---|
skuId | String | Уникальный идентификатор продукта | Да |
skuName | String | Имя продукта | Да |
description | String | Описание продукта | Нет |
manufacturer | String | Производитель продукта | Нет |
manufacturerCountry | String | Страна производителя | Нет |
brand | String | Бренд продукта | Нет |
categories | String[] | Категории продукта (должно совпадать с тем, что присылается в рекламном запросе) | Нет |
imgUrl | String | URL картинки | Нет |
url | String | URL продукта | Нет |
outdated | Bool | Если продукт устаревший (не существует) | Нет |
ext | JSON | Дополнительная информация о продукте | Нет |
[
{
"skuId": "unique_sku_id",
"skuName": "некий продукт",
"description": "Описание продукта.",
"manufacturer": "Производитель",
"manufacturerCountry": "Россия",
"brand": "Бренд",
"categories": ["category_1", "category_2"],
"imgUrl": "https://domain.com/unique_sku_id/640/480",
"url": "https://domain.com/unique_sku_id",
"outdated": false,
"ext": {
"param1": "параметр 1",
"param2": "параметр 2"
}
}
]
{
"errors": [
{
"errors": [
{
"fieldName": "skuId",
"message": {
"ru": "Поле обязательно",
"en": "Field is required"
},
"errorCode": 400.0
},
{
"fieldName": "skuName",
"message": {
"ru": "Поле обязательно",
"en": "Field is required"
},
"errorCode": 400.0
}
],
"requestJson": {
"description": "Texas background",
"manufacturer": "Electronics",
"manufacturerCountry": "Ethiopia",
"brand": "Internal Implementation Administrator",
"categories": ["Manager"],
"imgUrl": "http://placeimg.com/640/480",
"url": "http://nickolas.info",
"outdated": false,
"ext": {
"param1": "Table Wooden Dalasi Senior enable",
"param2": "application District Liechtenstein bottom-line ADP"
}
}
}
]
}
{
"metadata": {
"description": "Schema of the Request for Create or Update Products"
},
"elements": {
"properties": {
"skuId": {
"type": "string"
},
"skuName": {
"type": "string"
}
},
"optionalProperties": {
"description": {
"type": "string"
},
"manufacturer": {
"type": "string"
},
"manufacturerCountry": {
"type": "string"
},
"brand": {
"type": "string"
},
"categories": {
"elements": {
"type": "string"
}
},
"imgUrl": {
"type": "string"
},
"url": {
"type": "string"
},
"outdated": {
"type": "boolean"
},
"ext": {
"optionalProperties": {
"format": {
"type": "string"
},
"activeIngredients": {
"type": "string"
},
"composition": {
"type": "string"
},
"pharmGroup": {
"type": "string"
},
"indications": {
"type": "string"
},
"contraindications": {
"type": "string"
},
"prescription": {
"type": "boolean"
},
"imgSmallUrl": {
"type": "string"
}
}
}
}
}
}
Ответ
Тело ответа будет пустым, если запрос выполнился успешно, в противном случае в теле ответа будет указана произошедшая ошибка.
Возможные статусы ответа:
- 200 - Все данные были успешно загружены
- 400 - Валидационные ошибки
- 401 - Неавторизованный (API KEY невалиден или он отсутствует)
- 500 - Внутренняя серверная ошибка
Добавление товарных остатков
С помощью PUT запроса на эндпоинт /api/v1/remains/bystore
добавляется информация об остатках товаров на тех или иных складах. В теле запроса ожидается массив с объектами, содержащими склад и список доступных товаров в нем. Товары, отсутствующие в этом списке считаются отсутствующими в данном складе.
Формат описания остатков
Параметр | Тип | Описание | Обязательное |
---|---|---|---|
storeId | String | Идентификатор склада | Да |
products | String[] | Массив уникальных идентификаторов продуктов | Да |
[
{
"storeId": "xI1d",
"products": ["d3456070-dd44-46cd-a558-d0d249777c98", "d3456070-dd44-46cd-a558-d0d249777c99"]
}
]
{
"results": [
{
"code": "PRODUCTS_NOT_FOUND",
"details": "The list of products which do not exists in the Product Catalog",
"products": ["d3456070-dd44-46cd-a558-d0d249777c98"]
},
{
"code": "STORES_NOT_FOUND",
"details": "The list of stores which do not exists in the Product Catalog",
"stores": ["xI1d"]
}
]
}
{
"metadata": {
"description": "The schema of the Request for Update Remains of Products"
},
"elements": {
"properties": {
"storeId": {
"type": "string"
},
"products": {
"elements": {
"type": "string"
}
}
}
}
}
Ответ
Тело ответа будет пустым, если запрос выполнился успешно, в противном случае в теле ответа будет указана произошедшая ошибка.
Возможные статусы ответа:
- 200 - Все данные были успешно загружены
- 400 - Валидационные ошибки
- 401 - Неавторизованный (API KEY невалиден или он отсутствует)
- 500 - Внутренняя серверная ошибка
Дополнительные параметры в рекламных запросах
- brand - наименование бренда товарова, полученного в момент когда пользователь находится в карточке товара (web, iOS и Android приложения)
- city - наименование города, который выбрал пользователь в приложении или определила само приложение по геопозиции пользователя.
- region - наименование региона, который выбрал пользователь в приложении или определила само приложение по геопозиции пользователя.
Пример запроса Web SDK
Ниже приведен пример использования дополнительных параметров при создании запроса в Web SDK. Для более детального изучения Web SDK смотри документацию.
import webSDK from 'https://test-sdk.com/web-sdk.js';
webSDK.init({
uid: "User ID if logged",
sessionId: "User Session ID",
bannerURL: "https://test.url",
});
webSDK.loadBanner('placement_id',
{
sizes: [{ w: 240, h: 300 }]
refresh: 30,
customParams: {
"skuId": "LG00001",
"skuName": "Lego bricks (speed boat)",
"category": "Kids",
"brand": "Lego",
"city": "City",
"region": "Region"
}
}
);
Пример заапроса iOS SDK
Ниже приведен пример использования дополнительных параметров при создании запроса в iOS SDK. Для более детального изучения iOS SDK смотри документацию.
class MyViewController: UIViewController {
@IBOutlet weak var creativeView: CreativeView!
private var creative: Creative!
override func viewDidLoad() {
super.viewDidLoad()
. . .
// Configure creative request query, here
creativeView.query = CreativeQuery(
placementId: "YOUR_PLACEMENT_ID",
sizes: [SizeEntity(width: 260, height: 106)],
floorPrice: 2.0,
currency: "USD",
customParams: [
"skuId": "LG00001",
"skuName": "Lego bricks (speed boat)",
"category": "Kids",
"gdprConsent": "CPsmEWIPsmEWIABAMBFRACBsABEAAAAgEIYgACJAAYiAAA.QRXwAgAAgivA",
"ccpa": "1YNN",
"coppa": "1",
"brand": "Lego",
"city": "City",
"region": "Region"
]
)
// Let's init creative controller
self.creative = .init(creativeView: creativeView)
// Finally, let's load creatives
self.creative.load()
}
}
Пример запроса Android SDK
Ниже приведен пример использования дополнительных параметров при создании запроса в Android SDK. Для более детального изучения Android SDK смотри документацию.
class MyActivity : AppCompatActivity() {
private lateinit var binding: ActivityMyBinding
private lateinit var creative: Creative
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMyBinding.inflate(layoutInflater)
val creativeView = binding.creativeView
// Configure creative request query, here
creativeView.query = CreativeQuery(
placementId = "YOUR_PLACEMENT_ID",
sizes = listOf(Size(width = 260, height = 106)),
floorPrice = 2.0,
currency = "USD",
customParams = mapOf(
"skuId" to "LG00001",
"skuName" to "Lego bricks (speed boat)",
"category" to "Kids",
"gdprConsent" to "CPsmEWIPsmEWIABAMBFRACBsABEAAAAgEIYgACJAAYiAAA.QRXwAgAAgivA",
"ccpa" to "1YNN",
"coppa" to "1",
"brand" to "Lego",
"city" to "City",
"region" to "Region"
),
)
// Let's init creative controller
creative = Creative(
lifecycle = lifecycle,
creativeView = creativeView
)
setContentView(binding.root)
// Finally, let's load creatives
creative.load()
}