Retrieves the product object for the specified ASIN and domain. If our last update is older than ~1 hour, it will be automatically refreshed before being delivered to ensure near real-time pricing data.
You can request products via either their ASIN (preferred) or UPC, EAN, GTIN and ISBN-13 codes. You cannot use both parameters, asin and code, in the same request. If a requested ASIN or code does not exist, no product will be returned, but 1 token is still consumed per requested ASIN or code.
Note: Keepa cannot track Amazon Fresh.
Endpoint#
Request by ASIN:
Or request by product code (UPC, EAN, GTIN or ISBN-13):
Parameters#
| Parameter | Required | Description |
|---|---|---|
key |
required | Your private API key. |
domain |
required | Integer value for the Amazon locale you want to access. See the Domain IDs table below for valid values. |
asin |
required* | The ASIN of the product you want to request. For batch requests, a comma-separated list of ASINs (up to 100). |
code |
required* | The product code of the product you want to request. We currently allow UPC, EAN, GTIN, and ISBN-13 codes. For batch requests, a comma-separated list of codes (up to 100). Multiple ASINs can have the same product code, so requesting a product code can return multiple products. Use the code-limit parameter to limit the number of returned products per code. |
* Provide either asin or code — you cannot use both parameters in the same request.
Domain IDs#
| Domain ID | Locale |
|---|---|
| 1 | com |
| 2 | co.uk |
| 3 | de |
| 4 | fr |
| 5 | co.jp |
| 6 | ca |
| 8 | it |
| 9 | es |
| 10 | in |
| 11 | com.mx |
| 12 | com.br |
Optional Parameters#
| Parameter | Extra token cost | Purpose |
|---|---|---|
stats | none | Include a stats field with current prices and statistics. |
update | 0 or 1 per product | Force a refresh if the product's last update is older than specified hours. |
history | none | Exclude historical data fields to reduce response size and processing time. |
days | none | Limit historical data to the recent X days. |
code-limit | none | Limit the number of products returned per code when using the code parameter. |
offers | 6 per found offer page | Retrieve up-to-date marketplace offers; incurs additional token cost. |
only-live-offers | none | Include only live marketplace offers; reduces response size. |
videos | none | Include video metadata. |
aplus | none | Include A+ content. |
rating | up to 1 per product | Include existing rating and review count history; may consume an extra token. |
buybox | 2 per product | Include Buy Box related data; incurs additional token cost. |
stock | 2 per product | Include stock information in offers and statistics; incurs additional token cost. |
historical-variations | 1 per product with a parent ASIN | Include historical and out of stock variations; incurs additional token cost. |
stats#
Token cost: no extra token cost.
If specified, the product object will include a stats field (a statistics object) with quick access to current prices, min/max prices, and weighted mean values. If the offers parameter is used, it will also provide Buy Box information.
You can provide the stats parameter in two forms:
- Last x days (positive integer value): calculates the stats for the last x days.
- Interval: specify a date range for the stats calculation using two timestamps (Unix epoch time in milliseconds) or two date strings (ISO8601 format, UTC).
Note: If there is insufficient historical data for a price type, the actual interval of the weighted mean calculation may be shorter than specified. All data provided via the stats field are calculated using the product object's csv history field; no new data is provided through this parameter.
Examples:
&stats=180— last 180 days&stats=2015-10-20,2015-12-24— from Oct 20 to Dec 24, 2015&stats=2011-01-01,2025-01-01— entire history&stats=1445299200000,1450915200000— Unix epoch time in milliseconds, from Oct 20 to Dec 24, 2015
update#
Additional token cost: 0 or 1 per product.
Positive integer value. If the product's last update is older than update hours, force a refresh. The default value used by the API is 1 hour. This parameter also works in conjunction with the offers parameter.
Using this parameter, you can achieve the following:
- Speed up requests: if up-to-date data is not required, use a higher value than 1 hour. No extra token cost.
- Always retrieve live data: use the value 0. If our last update was less than 1 hour ago, this consumes 1 extra token.
- No update at all: use the value -1. If the product is missing in our database and the
asinparameter was used, the product request will consume 0 tokens, and you will not receive any product data. Use this if you are only interested in products we have historical data for to save tokens. - Reduced offers token usage: when combined with the
offersparameter and our last offers data update is newer than update hours, the offers token usage will be reduced to 5 tokens, and no update will take place, regardless of the number of offer pages requested.
Example: &update=48 — only trigger an update if the product's last update is older than 48 hours.
history#
Token cost: no extra token cost.
Boolean value (0 = false, 1 = true). If specified and set to 0, the product object will not include the csv, salesRanks, monthlySoldHistory, parentAsinHistory, couponHistory, buyBoxSellerIdHistory, buyBoxUsedHistory and salesRankReferenceHistory fields. If you do not need them, use this to have them removed from the response. This will improve processing time and considerably decrease the size of the response.
Example: &history=0
days#
Token cost: no extra token cost.
Any positive integer value. If specified with a positive value X, the product object will limit all historical data to the recent X days. This includes the csv, buyBoxSellerIdHistory, salesRankReferenceHistory, salesRanks, offers, and offers.offerCSV fields. If you do not need old historical data, use this to reduce the response size and improve processing time. The parameter does not use calendar days; so 1 day equals the last 24 hours.
Example: &days=90
code-limit#
Token cost: no extra token cost.
Any positive integer value. Sets a constraint on the maximum number of products returned for a given code when utilizing the code parameter. Use this parameter to limit the volume of product results associated with specific product codes.
Example: &code-limit=10
offers#
Token cost: 6 for every found offer page (contains up to 10 offers) per product, with a minimum of 5 tokens if the retrieval succeeds but no offer page is found.
Positive integer value between 20 and 100. Determines the number of up-to-date marketplace offers to retrieve. The additional token cost is calculated based on the number of found offers, not the requested amount (as a product can have fewer offers than requested). When using the offers parameter, the basic 1 token cost per ASIN of the product request does not apply.
If the offers parameter is used, the product object will contain additional data:
- Marketplace offer objects
- Information on the New and Used Buy Box, including a history of Buy Box winners
- Price history data for FBA (Fulfillment by Amazon), FBM (Fulfillment by Merchant), Warehouse Deals, Prime exclusive, and all Used and Collectible sub-conditions, including shipping and handling costs
- Rating and review count history
All offers-related data is updated independently, irregularly, and not as often as all other product data. Keep this in mind when evaluating the additional historical data.
Notes:
- The returned product may have more offers than specified because we keep a history of offers. The number specified in this parameter determines how many offers we attempt to retrieve/update from Amazon. Each offer object has a
lastSeenfield that can be used to filter up-to-date offers. - Batched requests are processed in parallel.
- All offers-related data is freshly updated and up-to-date.
- The request will require more time to complete, ranging from 2 to 20 seconds with an average of 5 seconds. Use batch requests or parallel requests to increase throughput when required.
- If we fail to retrieve/refresh the offers data, the request will consume 1 token. The request will return successfully and will contain, if available, all historical offers (unless
only-live-offersis used) and product data. You can retry the request after a few minutes. - If the retrieval succeeds but the product has no marketplace offers at all, no offer page is found and the request consumes 5 tokens. This is a successful retrieval, not a failure: the product object is returned with
offersSuccessfulset totrue. - If the product no longer exists on Amazon, the request is treated the same way: 5 tokens,
offersSuccessfulset totrue, no live offers. For the next 7 days on amazon.com, amazon.co.jp and amazon.de, or 6 hours on the other marketplaces, requests for it are answered from our data at the same cost.
Limitations: not available for digital products, movie rentals, product bundles, Amazon Fresh, luxury stores, Amazon Haul/Bazaar, and Amazon Pantry.
Example: &offers=40 — requested up to 40 offers, but the product only has 18 offers. Total token cost for the request: 6 per found offer page = 12 tokens.
only-live-offers#
Token cost: no extra token cost.
Boolean value (0 = false, 1 = true). If specified and set to 1, the product object will only include live marketplace offers (when used in combination with the offers parameter). If you do not need historical offers, use this to reduce the response size and improve processing time. If only live offers are requested and our system fails to retrieve them, the product request will consume no tokens.
Example: &only-live-offers=1
videos#
Token cost: no extra token cost.
Boolean value (0 = false, 1 = true). If specified and set to 1, the videos metadata will be provided when available. Using this parameter does not trigger an update to the videos data; it only gives access to our existing data if available. If you need up-to-date data, you have to use the offers parameter.
aplus#
Token cost: no extra token cost.
Boolean value (0 = false, 1 = true). If specified and set to 1, the A+ content will be provided when available. Using this parameter does not trigger an update to the A+ content; it only gives access to our existing data if available. If you need up-to-date data, you have to use the offers parameter.
rating#
Token cost: up to 1 extra token per product.
Boolean value (0 = false, 1 = true). If specified and set to 1, the product object will include our existing RATING and COUNT_REVIEWS history in the csv field, regardless of whether the offers parameter is used. The extra token will only be consumed if our last update to both data points is less than 14 days ago.
Using this parameter does not trigger an update to those two fields; it only gives access to our existing data if available. If you need up-to-date data, you have to use the offers parameter. Use this if you need access to the rating data, which may be outdated, but do not need any other data fields provided through the offers parameter to save tokens and speed up the request. If there is no rating data returned, you can still make another request using the offers parameter.
Example: &rating=1 — include the rating and review count data in the csv history data field of the product object and respective fields of the statistics object.
buybox#
Additional token cost: 2 per product.
Boolean value (0 = false, 1 = true). If specified and set to 1, the product and statistics object will include all available Buy Box related data:
- Current price, price history, and statistical values
buyBoxSellerIdHistory- All Buy Box fields in the statistics object
The buybox parameter does not trigger a fresh data collection. If the offers parameter is used, the buybox parameter is ignored, as the offers parameter also provides access to all Buy Box related data. To access the statistics object, the stats parameter is required.
Example: &buybox=1
stock#
Additional token cost: 2 per product.
Boolean value (0 = false, 1 = true). If set to 1, the response includes the stock data available for the product:
- together with the
offersparameter, the marketplace offer objects include thestockCSVfield; - together with the
statsparameter, the statistics object includes thestockAmazonandstockBuyBoxfields.
In both cases the product object includes the lastStockUpdate field. Without offers or stats, the parameter adds only lastStockUpdate and costs no extra tokens.
Token cost note: The stock parameter incurs 2 extra tokens only if lastStockUpdate is newer than 7 days and the response contains stock data for the product (stockCSV in an offer, or the stock fields of the statistics object).
Limitations & performance notes:
- Offer limit: usually, stock data is only retrieved for the top 10 offers.
- Data freshness: this parameter is not guaranteed to collect fresh stock data.
- Latency: the request will require more time to retrieve stock data, typically adding 1 to 2 seconds per offer to the total response time.
Example: &stock=1
historical-variations#
Additional token cost: 1 per product that has a parent ASIN.
Boolean value (0 = false, 1 = true). If specified and set to 1, the product object will have the historicalVariations field set, which provides a list of historical and out of stock variation ASINs of the requested product.
Example: &historical-variations=1
Token Cost#
The base cost is 1 token per product. If a requested ASIN or code does not exist, 1 token is still consumed. Optional parameters can add to — or in some cases replace or reduce — that cost:
| Scenario | Token cost |
|---|---|
| Basic request (per requested product) | 1 token |
offers used | 6 tokens per found offer page (up to 10 offers per page) per product; the basic 1 token per ASIN does not apply |
offers used, retrieval succeeds but the product has no offers | 5 tokens (no offer page is found; offersSuccessful is true) |
offers used, the product no longer exists on Amazon | 5 tokens (offersSuccessful is true, no live offers); for 7 days on .com, .co.jp and .de and 6 hours elsewhere, further requests are answered from our data at the same cost |
offers used, but offers retrieval/refresh fails | 1 token (historical offers and product data are still returned, unless only-live-offers is used) |
offers + only-live-offers, retrieval fails | 0 tokens |
offers + update, last offers data update newer than update hours | 5 tokens flat, no update takes place (regardless of the number of offer pages requested) |
update=0 and our last update was less than 1 hour ago | +1 extra token |
update=-1, product missing in our database, asin parameter used | 0 tokens (no product data returned) |
rating=1 | up to +1 token per product (only if our last update to both rating and review count data is less than 14 days ago) |
buybox=1 | +2 tokens per product |
stock=1 | +2 tokens per product (only if lastStockUpdate is newer than 7 days and the response contains stock data) |
historical-variations=1 | +1 token per product that has a parent ASIN |
stats, history, days, code-limit, only-live-offers, videos, aplus | no extra token cost |
Response#
A products field containing an array of product objects with an entry for each ASIN that was requested.
Examples#
Basic request (single ASIN)#
Request the product object for a single ASIN on amazon.com (domain 1):
KeepaAPI api = new KeepaAPI("YOUR_API_KEY");
Request r = Request.getProductRequest(AmazonLocale.US, null, null, "B0F3GWXLTS");
api.sendRequest(r)
.done(result -> {
if (result.status == ResponseStatus.OK) {
System.out.println(result.products[0].title);
}
})
.fail(failure -> System.out.println(failure));<?php
use Keepa\KeepaAPI;
use Keepa\API\Request;
use Keepa\API\ResponseStatus;
use Keepa\objects\AmazonLocale;
$api = new KeepaAPI("YOUR_API_KEY");
$response = $api->sendRequestWithRetry(Request::getProductRequest(AmazonLocale::US, null, null, null, 1, true, ['B0F3GWXLTS']));
if ($response->status == ResponseStatus::OK) {
echo $response->products[0]->title;
}import requests
params = {"key": "YOUR_API_KEY", "domain": 1, "asin": "B0F3GWXLTS"}
r = requests.get("https://api.keepa.com/product", params=params)
data = r.json()
product = data["products"][0]
print(product["title"], product["lastUpdate"])const res = await fetch("https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=B0F3GWXLTS");
const data = await res.json();
const product = data.products[0];
console.log(product.title, product.lastUpdate);curl -s "https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=B0F3GWXLTS"Example response#
{
"timestamp": 1783468800000,
"tokensLeft": 297,
"refillIn": 42000,
"refillRate": 5,
"tokenFlowReduction": 0.0,
"tokensConsumed": 1,
"processingTimeInMs": 812,
"products": [
{
"asin": "B0F3GWXLTS",
"domainId": 1,
"title": "Example Wireless Bluetooth Speaker (Black)",
"trackingSince": 1052640,
"listedSince": 1048200,
"lastUpdate": 7663880,
"lastPriceChange": 7663520,
"brand": "examplebrand",
"manufacturer": "ExampleBrand Inc.",
"model": "EB-100",
"color": "Black",
"rootCategory": 172282,
"categories": [3236451011],
"parentAsin": null,
"csv": [
[7650120, 2999, 7658340, 3199, 7663520, 3099],
[7650120, 2799, 7660100, 2749, 7663520, 2699],
null,
[7650120, 5310, 7663880, 4874]
]
}
]
}
Response shortened for readability; illustrative values. Prices are integers in the smallest currency unit (e.g. cents), and history timestamps are in Keepa Time minutes — see the product object for the full field reference and the conversion formula.
Batch request (comma-separated ASINs, up to 100)#
Request several products at once by passing a comma-separated list of ASINs (up to 100). Each returned product costs 1 token (plus any optional-parameter costs):
KeepaAPI api = new KeepaAPI("YOUR_API_KEY");
Request r = Request.getProductRequest(AmazonLocale.US, null, null,
"B0F3GWXLTS", "B0BDHWDR12", "B07FZ8S74R");
api.sendRequest(r)
.done(result -> {
for (Product product : result.products) {
System.out.println(product.asin + " " + product.title);
}
})
.fail(failure -> System.out.println(failure));<?php
use Keepa\KeepaAPI;
use Keepa\API\Request;
use Keepa\API\ResponseStatus;
use Keepa\objects\AmazonLocale;
$api = new KeepaAPI("YOUR_API_KEY");
$response = $api->sendRequestWithRetry(Request::getProductRequest(AmazonLocale::US, null, null, null, 1, true,
['B0F3GWXLTS', 'B0BDHWDR12', 'B07FZ8S74R']));
if ($response->status == ResponseStatus::OK) {
foreach ($response->products as $product) {
echo $product->asin . " " . $product->title . PHP_EOL;
}
}import requests
asins = ["B0F3GWXLTS", "B0BDHWDR12", "B07FZ8S74R"] # up to 100 per request
params = {"key": "YOUR_API_KEY", "domain": 1, "asin": ",".join(asins)}
r = requests.get("https://api.keepa.com/product", params=params)
data = r.json()
for product in data["products"]:
print(product["asin"], product["title"])const asins = ["B0F3GWXLTS", "B0BDHWDR12", "B07FZ8S74R"]; // up to 100 per request
const url = `https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=${asins.join(",")}`;
const res = await fetch(url);
const data = await res.json();
for (const product of data.products) console.log(product.asin, product.title);curl -s "https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=B0F3GWXLTS,B0BDHWDR12,B07FZ8S74R"Example response#
{
"timestamp": 1783468800000,
"tokensLeft": 294,
"refillIn": 38000,
"refillRate": 5,
"tokenFlowReduction": 0.0,
"tokensConsumed": 3,
"processingTimeInMs": 1420,
"products": [
{
"asin": "B0F3GWXLTS",
"domainId": 1,
"title": "Example Wireless Bluetooth Speaker (Black)",
"lastUpdate": 7663880
},
{
"asin": "B0BDHWDR12",
"domainId": 1,
"title": "Example USB-C Charging Cable, 2 m",
"lastUpdate": 7663910
},
{
"asin": "B07FZ8S74R",
"domainId": 1,
"title": "Example Smart Home Hub, 2nd Generation",
"lastUpdate": 7663845
}
]
}
Response shortened for readability; illustrative values. Each entry in products is a full product object.
Offers request#
Retrieve up-to-date marketplace offers with &offers=20. Note the different token accounting: 6 tokens per found offer page instead of the basic 1 token per ASIN.
KeepaAPI api = new KeepaAPI("YOUR_API_KEY");
Request r = Request.getProductRequest(AmazonLocale.US, null, 20, "B0F3GWXLTS");
api.sendRequest(r)
.done(result -> {
Product product = result.products[0];
System.out.println(product.offers.length + " offers");
})
.fail(failure -> System.out.println(failure));<?php
use Keepa\KeepaAPI;
use Keepa\API\Request;
use Keepa\API\ResponseStatus;
use Keepa\objects\AmazonLocale;
$api = new KeepaAPI("YOUR_API_KEY");
$response = $api->sendRequestWithRetry(Request::getProductRequest(AmazonLocale::US, 20, null, null, 1, true, ['B0F3GWXLTS']));
if ($response->status == ResponseStatus::OK) {
$product = $response->products[0];
echo count($product->offers) . " offers";
}import requests
params = {"key": "YOUR_API_KEY", "domain": 1, "asin": "B0F3GWXLTS", "offers": 20}
r = requests.get("https://api.keepa.com/product", params=params)
data = r.json()
product = data["products"][0]
for offer in product["offers"]:
print(offer["sellerId"], offer["lastSeen"])const res = await fetch("https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=B0F3GWXLTS&offers=20");
const data = await res.json();
const product = data.products[0];
product.offers.forEach(o => console.log(o.sellerId, o.lastSeen));curl -s "https://api.keepa.com/product?key=YOUR_API_KEY&domain=1&asin=B0F3GWXLTS&offers=20"Example response#
{
"timestamp": 1783468800000,
"tokensLeft": 282,
"refillIn": 29000,
"refillRate": 5,
"tokenFlowReduction": 0.0,
"tokensConsumed": 12,
"processingTimeInMs": 4380,
"products": [
{
"asin": "B0F3GWXLTS",
"domainId": 1,
"title": "Example Wireless Bluetooth Speaker (Black)",
"lastUpdate": 7663930,
"lastOffersUpdate": 7663930,
"buyBoxSellerIdHistory": ["7660100", "ATVPDKIKX0DER", "7663930", "A2L77EE7U53NWQ"],
"liveOffersOrder": [0, 1],
"offers": [
{
"offerId": 0,
"lastSeen": 7663930,
"sellerId": "A2L77EE7U53NWQ",
"condition": 1,
"isPrime": true,
"isFBA": true,
"offerCSV": [7655800, 2799, 0, 7663930, 2699, 0]
},
{
"offerId": 1,
"lastSeen": 7663930,
"sellerId": "ATVPDKIKX0DER",
"condition": 1,
"isPrime": true,
"isFBA": true,
"offerCSV": [7650120, 2999, 0, 7663930, 2749, 0]
}
]
}
]
}
Response shortened for readability; illustrative values. In this example 2 offer pages were found, so the request consumed 6 × 2 = 12 tokens. See the marketplace offer object for all offer fields.