Retail product catalog API
Purposes
- ability to target on products, brands and categories of products;
- ability to consider rules for advertising on products of competing brands when launching advertising campaigns;
- accounting information about remains of products in stores;
Implementation
Before you start
You should know the API URL of the advertising platform. Ask the advertising platform team to give it to you.
WARNING
If you fill in only the changed products ( the primary approach), the first time, you need to fill out a whole list of products from the current catalog and then iteratively add only the changed products.
There are a three endpoints which are used to upload information about products using HTTP protocol:
/api/v1/store
- to upload data about stores./api/v1/product
- to upload data about products./api/v1/remains/bystore
- to upload information about remains of products in stores.
Requests authorization
API is protected by API Key Authentication mechanism. Each request must contain a special API Key in the Authorization header: Authorization: Bearer <api key>
. API Key will be provided on the integration phase.
Stores upload
To upload a new or update an existing store use the endpoint PUT /api/v1/store
. The body of the request represents an array of store objects. It's available to upload a single store as well as all stores in one request.
Store object format
Parameter | Type | Description | Required |
---|---|---|---|
id | String | The unique name or identifier of the store | Yes |
regions | String[] | Regions which are served by the store. | regions or cities must be not empty |
cities | String[] | Cities which are served by the store. | regions or cities must be not empty |
[
{
"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"
}
}
}
}
}
Response
The response body will be empty in the case when request was successfully processed; otherwise the response body will contain the information about errors.
Response HTTP statuses:
- 200 - The request was successfully processed
- 400 - Some validation errors
- 401 - Unauthorized request (API KEY invalid or not provided)
- 500 - Internal server error
Products upload
To upload a new or update an existing product use the endpoint PUT /api/v1/product
. The body of the request represents an array of product objects. It's available to upload a single product as well as all products in one request.
Product object format
Parameter | Type | Description | Required |
---|---|---|---|
skuId | String | The unique product identifier | Yes |
skuName | String | The name of the product | Yes |
description | String | The description of the product | No |
manufacturer | String | The manufacturer of the product | No |
manufacturerCountry | String | The manufacturer country | No |
brand | String | The brand of the product | No |
categories | String[] | The array of categories of the product (must be the same as in ad requests) | No |
imgUrl | String | The image URL | No |
url | String | The URL of the product | No |
outdated | Bool | Indicates if the product exists | No |
ext | JSON | The additional information about the product | No |
::code-group
[
{
"skuId": "unique_sku_id",
"skuName": "product 1",
"description": "some description",
"manufacturer": "some manufacturer",
"manufacturerCountry": "France",
"brand": "some 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": "some parameter",
"param2": "another parameter"
}
}
]
{
"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"
}
}
}
}
}
}
:::
Response
The response body will be empty in the case when request was successfully processed; otherwise the response body will contain the information about errors.
Response HTTP statuses:
- 200 - The request was successfully processed
- 400 - Some validation errors
- 401 - Unauthorized request (API KEY invalid or not provided)
- 500 - Internal server error
Product Remains upload
To upload the information about remains of products in the store use the endpoint PUT /api/v1/remains/bystore
. The body of the request represents an array of stores and products inside them. It's available to upload a single store with products as well as all stores in one request. Products do not included in store object in the request are marked as absent in the store.
Remains object format
Parameter | Type | Description | Required |
---|---|---|---|
storeId | String | Unique identifier of the store (id of store object) | Yes |
products | String[] | Array of unique identifiers of products (skuId of product object) | Yes |
[
{
"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"
}
}
}
}
}
Response
The response body will be empty in the case when request was successfully processed; otherwise the response body will contain the information about errors.
Response HTTP statuses:
- 200 - The request was successfully processed
- 400 - Some validation errors
- 401 - Unauthorized request (API KEY invalid or not provided)
- 500 - Internal server error
Additional parameters in ad requests
brand - the product brand is obtained when the user is on the product screen/page (web, iOS, and Android applications).
city - the city that the user chose in the host app or the city detected by the app. Ad request from any page or screen (web, iOS and Android apps).
region - the region that the user chose in the host app or the region detected by the app. Ad request from any page or screen (web, iOS, and Android apps).
Web SDK example request
The following is an example of using custom parameters when creating a request in the Web SDK. For a more detailed of the Web SDK see documentation.
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 example request
The following is an example of using custom parameters when creating a request in the iOS SDK. For a more detailed of the iOS SDK see documentation.
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 example request
The following is an example of using custom parameters when creating a request in the Android SDK. For a more detailed of the Android SDK see documentation.
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()
}