Keepa API Docs

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:

GET https://api.keepa.com/product?key=<yourAccessKey>&domain=<domainId>&asin=<ASIN>

Or request by product code (UPC, EAN, GTIN or ISBN-13):

GET https://api.keepa.com/product?key=<yourAccessKey>&domain=<domainId>&code=<productCode>

Parameters#

ParameterRequiredDescription
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 IDLocale
1com
2co.uk
3de
4fr
5co.jp
6ca
8it
9es
10in
11com.mx
12com.br

Optional Parameters#

ParameterExtra token costPurpose
statsnoneInclude a stats field with current prices and statistics.
update0 or 1 per productForce a refresh if the product's last update is older than specified hours.
historynoneExclude historical data fields to reduce response size and processing time.
daysnoneLimit historical data to the recent X days.
code-limitnoneLimit the number of products returned per code when using the code parameter.
offers6 per found offer pageRetrieve up-to-date marketplace offers; incurs additional token cost.
only-live-offersnoneInclude only live marketplace offers; reduces response size.
videosnoneInclude video metadata.
aplusnoneInclude A+ content.
ratingup to 1 per productInclude existing rating and review count history; may consume an extra token.
buybox2 per productInclude Buy Box related data; incurs additional token cost.
stock2 per productInclude stock information in offers and statistics; incurs additional token cost.
historical-variations1 per product with a parent ASINInclude 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 asin parameter 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 offers parameter 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 lastSeen field 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-offers is 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 offersSuccessful set to true.
  • If the product no longer exists on Amazon, the request is treated the same way: 5 tokens, offersSuccessful set to true, 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:

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:

ScenarioToken cost
Basic request (per requested product)1 token
offers used6 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 offers5 tokens (no offer page is found; offersSuccessful is true)
offers used, the product no longer exists on Amazon5 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 fails1 token (historical offers and product data are still returned, unless only-live-offers is used)
offers + only-live-offers, retrieval fails0 tokens
offers + update, last offers data update newer than update hours5 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 used0 tokens (no product data returned)
rating=1up 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, aplusno 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.