Content
Overview
API Request Format
API Response Format
Other API Responses
Using the Page Parameter or the Next Page Approach
API Registration and Throughput
Testing the API
Securing the Communication
Overview
The Bulk Products API is a REST API endpoint that allows two software systems to talk to each other via a request/response-based communication. This API is optimized for bulk data transfer and allows client applications to query the most recently extracted pricing data on demand. It returns the latest extracted pricing data for your entire catalog in pages - batches of SKUs and associated competitor product listings.
API Request Format
GET request.
Base URL: https://pi-api.wiser.com
Path: /api/v1/products?key=<your_api_key>&page=<page_num>&crawl_recency_hours=<hours>
key=<your_api_key>
Is a required parameter.
It corresponds to the unique account API authentication key.
Ex: key=rWotPeHKnKgdNdUv6VC7YM9yrTkwzWTx
page=<page_num>
Is an optional parameter. It only accepts positive integer numbers.
It corresponds to the number of the page being requested.
Ex: page=1.
crawl_recency_hours=<hours>
Is an optional parameter. It only accepts positive integer numbers.
If used it will only return competitor products extracted in the last ‘selected number’ hours.
Ex: crawl_recency_hours=24
API Response Format
This API returns the latest extracted pricing data in pages - batches of up to 1,000 customer SKU products, including all associated competitor listings.
Successful response (status: 200)
Structure: {"data": [], "pagination_details": {}}
{"data": [
{
“sku”: { // information about customer product
"master_id": <str> non-nullable, // unique id of this master product in Wiser systems
“environment”: <str> non-nullable, // your PI environment where the data is being fetched from
“assortment”: <boolean> non-nullable, // false indicates this is a customer provided SKU; true is a generic clustering of similar products
"sku": <str> nullable, // your product's SKU alphanumeric code
"title": <str> nullable, // your product's title
“category_level_1”: <str> nullable, // your level 1 category name
“category_level_2”: <str> nullable // your level 2 category name
},
“matched_products”: [ // information about each competitor match
{
"id": <str> non-nullable, // unique id of this product in Wiser systems
"store_name": <str> non-nullable, // e-commerce store name
“marketplace_seller”: <str> nullable, // name of the lowest price seller if the store is a marketplace
"url": <str> non-nullable, // product's listing URL
“match type”: <str> non-nullable, // if the match type is 'exact' or 'equivalent'
"crawl_date": <date YYYY-MM-DD HH:MM:SS> non-nullable, // last crawl timestamp in UTC
"previous_price": <float> nullable, // second last price collected
"price": <float> non-nullable, // product listing's price
"regular_price": <float> nullable, // listing's regular price, aka “strike-through price”
“savings”: <float> nullable, // difference between price and regular price in monetary value
"savings_message”: <str> nullable, // promotional messages (ex: save $50 buying two or more).
“special_offer”: <string> nullable, // used to capture other promotional messages such as membership discounts
"shipping_price": <float> nullable, // product listing's shipping price
“shipping_message”: <str> nullable, // shipping message on the page (ex: "buy now receive tomorrow").
"in_cart": <boolean> nullable, // if price was extracted after adding item to cart
"availability": <boolean> nullable // product listing's stock information
}
{ …. } // subsequent set of attributes for each one of the products matched to this particular SKU
]
},
{
“sku”: {….},
“matched_products”: [ {…} ]
}
],
“pagination_details": { // information about the quantity of data available
“page_size”: <int> non-nullable, // number of products (your SKU) in the current page
“total_pages”: <int> non-nullable // total number of available pages
“page”: <int> non-nullable, // corresponds to the number of the current page and is only present when using the page parameter in the request
“next_page”: <str> nullable // contains the API request URL for the next page and is only present when there is no page parameter in the request
}
}
Note 1: If there are no competitor products matching the crawl recency filter the “matched_products” array will be empty.
Note 2: If you're subscribed to regional price intel (multiple zip codes set for a particular competitor domain), the Bulk Products API will return data for the main zip code only or average price across all zip codes, following the existing environment configuration.
Other API Responses
During implementation, besides successful response data, your application also needs to be prepared to handle error response scenarios.
Structure {"error": {"error_code": "<str>","error_message": "<str>"}} // information about the error for troubleshooting
If invalid request format
HTTP status code: 400 Bad Request
{"error": {
"error_code": “INVALID_REQUEST_FORMAT",
"error_message": "The request format is invalid. Please check the API documentation and ensure your request conforms to the required format."}}
If missing key:
HTTP status code: 401 Unauthorized
{"error": {
"error_code": “MISSING_API_KEY”,
"error_message": "The API key is missing from the request. Please include a valid API key and try again."}}
If invalid key:
HTTP status code: 401 Unauthorized
{"error": {
"error_code": “INVALID_API_KEY”,
"error_message": "The API key provided is invalid. Please check your API key and try again."}}
If invalid page_num (non-numeric, negative, 0 or fractional number):
HTTP status code: 400 Bad Request
{"error": {
"error_code": “INVALID_PAGE_NUMBER”,
"error_message": "The page number provided is invalid. Please provide a positive integer number and try again."}}
If page_num not available:
HTTP status code: 404 Not Found
{"error": {
"error_code": “PAGE_NOT_AVAILABLE”,
"error_message": "The requested page number is not available. Please check the page number and try again."}}
If page_num not supported (catalog >200k SKUs):
HTTP status code: 422 Unprocessable Content
{"error": {
"error_code": “UNSUPPORTED_PAGE_NUMBER”,
"error_message": "Your catalog size exceeds the supported limit. Please use the next_page approach to retrieve data."}}
If invalid crawl_recency_hours (non-numeric, negative, 0 or fractional number):
HTTP status code: 400 Bad Request
{"error": {
"error_code": "INVALID_CRAWL_RECENCY_HOURS”,
"error_message": "The crawl recency hours provided is invalid. Please provide a positive integer number and try again.}}
If the usage limit is reached
HTTP status code: 429 Too Many Requests
{"error": {
"error_code": “USAGE_LIMIT_REACHED",
"error_message": "You have reached the maximum number of requests per minute. Please wait and try again later."}}
If response timeout
HTTP status code: 504 Gateway Timeout
Note: There is no additional error information for this particular case.
If unexpected system errors
HTTP status code: 500 Internal Server Error
{"error": {
"error_code": “UNEXPECTED_ERROR",
"error_message": "An unexpected error occurred. Please try again later. If the problem persists, contact support."}}
Using the Page Parameter or the Next Page Approach
Client applications can utilize the page parameter to make sequential or parallel API requests when their catalog contains 200,000 SKUs or fewer. This method is effective for retrieving data page by page based on the page number specified in the request.
However, for faster response times, especially for larger catalogs, we recommend using the next_page approach. This method works as follows:
Initial request: Begin by making a request without specifying the page parameter. The API will respond with the first page of data and provide a next_page URL in the response.
Fetching the subsequent page: The next_page URL is encoded using UTF-8. To retrieve the next set of data, decode this URL, include your API key, and make a new API request using the decoded URL.
Repeat the process: Continue this process, using the next_page URL provided in each response, until the next_page value is null. This indicates that there are no more pages of data to fetch and that you have successfully retrieved all available pages for your catalog.
API Registration and Throughput
Your application needs an API key to authenticate the requests made to the Wiser API endpoints. If you have multiple environments (catalogs), you will need a key for each one of the environments or only for the one(s) you wish to use APIs.
Each API key has a rate limit of 20 requests per minute. This API typically responds with data in a few seconds, excluding any client-side network speed restrictions.
Please reach out to your Wiser representative for more information about creating a key and configuring usage limits.
Testing the API
For a simple test, you can make API requests and see the responses using a simple web browser (ex: Google Chrome). You just need to insert the full API request URL in the browser with the right parameters.
Securing the Communication
Data security is critical when integrating with Web APIs. Please make sure you're using common security practices, such as using proper connection security using HTTPS and keeping your API secret key safe to ensure bad actors cannot access your data.
Common security mistakes include sharing the complete request URL (including your API key) with peers in insecure channels, which may expose the API key to bad actors. So please review your data security policies and processes accordingly.
For additional data transfer security, this API also offers support for Mutual TLS (mTLS). This feature provides end-to-end encryption and mutual authentication between client and server, significantly enhancing data protection. If you're interested in implementing mTLS for your integration, please contact your Wiser representative or reach out to our support team at support@wiser.com for more information.