By accessing our deals, you can find products that recently changed and match your search criteria. A single request will return a maximum of 150 deals. A query can provide up to 10,000 ASINs using paging. We recommend trying out our deals page first to familiarize yourself with the options and results before reading this documentation.
Note: Our deals only provide products that were updated within the last 12 hours.
Endpoint#
You can choose between an HTTP GET or POST request. Both take the same queryJSON object, described below.
GET format#
| Parameter | Required | Description |
|---|---|---|
key | required | Your private API key. |
selection | required | The query JSON contains all request parameters. It must be URL-encoded if the GET format is used. |
POST format#
| Parameter | Required | Description |
|---|---|---|
key | required | Your private API key. |
| POST payload | required | Must contain the queryJSON (no URL encoding needed). |
Tip: To quickly get a valid queryJSON, there is a link on the deals page below the filters that generates this JSON for the currently active selection.
The queryJSON Object#
The query JSON contains all request parameters. Its full structure:
{
"page": Integer,
"domainId": Integer,
"excludeCategories": [Long],
"includeCategories": [Long],
"priceTypes": [Integer],
"deltaRange": [Integer],
"deltaPercentRange": [Integer],
"deltaLastRange": [Integer],
"salesRankRange": [Integer],
"currentRange": [Integer],
"minRating": Integer,
"isLowest": Boolean,
"isLowest90": Boolean,
"isLowestOffer": Boolean,
"isHighest": Boolean,
"isOutOfStock": Boolean,
"isBackInStock": Boolean,
"titleSearch": String,
"isRangeEnabled": Boolean,
"isFilterEnabled": Boolean,
"hasReviews": Boolean,
"filterErotic": Boolean,
"singleVariation": Boolean,
"isRisers": Boolean,
"isPrimeExclusive": Boolean,
"mustHaveAmazonOffer": Boolean,
"mustNotHaveAmazonOffer": Boolean,
"warehouseConditions": [Integer],
"material": [String],
"type": [String],
"manufacturer": [String],
"brand": [String],
"model": [String],
"color": [String],
"size": [String],
"unitType": [String],
"scent": [String],
"itemForm": [String],
"pattern": [String],
"style": [String],
"itemTypeKeyword": [String],
"targetAudienceKeyword": [String],
"edition": [String],
"format": [String],
"author": [String],
"binding": [String],
"languages": [String],
"brandStoreName": [String],
"brandStoreUrlName": [String],
"websiteDisplayGroup": [String],
"websiteDisplayGroupName": [String],
"salesRankDisplayGroup": [String],
"sortType": Integer,
"dateRange": Integer
}
Parameters#
Core parameters#
| Parameter | Required | Description |
|---|---|---|
page |
optional | Most deal queries have more than 150 results (the maximum page size). To browse all deals found by a query (up to the limit of 10,000), iterate the page parameter while keeping all other parameters identical. Start with page=0 and stop when the response contains fewer than 150 results.Example: "page": 0 |
domainId |
required | The domainId of the Amazon locale to retrieve deals for. Not optional. See the domain ID table below for valid values. |
priceTypes |
required | Determines the deal type. Not optional: exactly one price type must be specified. Though it is an integer array, it can contain only one entry — multiple types per query are not supported. Only the price types listed below carry deal data; any other value is rejected as an invalid priceTypes.Example: "priceTypes": [0] |
dateRange |
optional | Our deals are divided into different sets, determined by the time interval in which the product changed. The shorter the interval, the more recent the change, which is good for significant price drops but may miss slow incremental drops. See the interval table below for valid values. Example: "dateRange": 0 |
Valid domainId values
| 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 |
Valid priceTypes values
| Value | Price Type |
|---|---|
| 0 | AMAZON: Amazon price |
| 1 | NEW: Marketplace New price |
| 2 | USED: Marketplace Used price |
| 3 | SALES: Sales Rank |
| 5 | COLLECTIBLE: Collectible price |
| 6 | REFURBISHED: Refurbished price |
| 7 | NEW_FBM_SHIPPING: New FBM with shipping |
| 8 | LIGHTNING_DEAL: Lightning Deal price |
| 9 | WAREHOUSE: Amazon Warehouse price |
| 10 | NEW_FBA: New FBA price |
| 18 | BUY_BOX_SHIPPING: New Buy Box with shipping |
| 19 | USED_NEW_SHIPPING: Used - Like New with shipping |
| 20 | USED_VERY_GOOD_SHIPPING: Used - Very Good with shipping |
| 21 | USED_GOOD_SHIPPING: Used - Good with shipping |
| 22 | USED_ACCEPTABLE_SHIPPING: Used - Acceptable with shipping |
| 27 | REFURBISHED_SHIPPING: Refurbished with shipping |
| 32 | BUY_BOX_USED_SHIPPING: Used Buy Box with shipping |
| 33 | PRIME_EXCL: Prime Exclusive Price |
Note (Lightning Deals, Prime Exclusive, and Warehouse Deals): The deltaLast, delta and deltaPercent entries for these price types are calculated with the Amazon or New price as the reference price (instead of the same price type’s previous price).
Valid dateRange values
| Value | Interval |
|---|---|
| 0 | Day (last 24 hours) |
| 1 | Week (last 7 days) |
| 2 | Month (last 31 days) |
| 3 | 3 Months (last 90 days) |
Filter options#
| Parameter | Required | Description |
|---|---|---|
isFilterEnabled |
optional | Switch to enable the filter options. Example: "isFilterEnabled": true |
excludeCategories |
optional | Used to exclude products listed in these categories. If it’s a subcategory, the product must be directly listed in this category; products in child categories of the specified ones will not be excluded unless it’s a root category. Array with up to 500 category node IDs. Example: "excludeCategories": [77028031, 186606] |
includeCategories |
optional | Used to include only products listed in these categories. Same rules as excludeCategories.Example: "includeCategories": [3010075031, 12950651, 355007011] |
minRating |
optional | Limit to products with a minimum rating. A rating is an integer from 0 to 50 (e.g. 45 = 4.5 stars). If -1, the filter is inactive.Example: "minRating": 20 (minimum rating of 2 stars) |
isLowest |
optional | Include only products for which the specified price type is at its lowest value (since tracking began). Example: "isLowest": true |
isLowest90 |
optional | Include only products for which the specified price type is at its lowest value in the past 90 days. Example: "isLowest90": true |
isLowestOffer |
optional | Include only products if the selected price type is the lowest of all New offers (applicable to Amazon and Marketplace New). Example: "isLowestOffer": true |
isHighest |
optional | Include only products for which the specified price type is at its highest value (since tracking began). Example: "isHighest": true |
isOutOfStock |
optional | Include only products that were available to order within the last 24 hours and are now out of stock. Example: "isOutOfStock": true |
isBackInStock |
optional | Include only products that were previously out of stock and have returned to stock within the last 24 hours. Example: "isBackInStock": true |
hasReviews |
optional | If true, exclude all products with no reviews. If false, the filter is inactive.Example: "hasReviews": false |
filterErotic |
optional | Exclude all products listed as adult items. Example: "filterErotic": false |
singleVariation |
optional | Provide only a single variation if multiple match the query. The one provided is randomly selected. Example: "singleVariation": true |
isRisers |
optional | Include only products whose price has been rising over the chosen dateRange interval.Example: "isRisers": true |
isPrimeExclusive |
optional | Include only products flagged as Prime Exclusive. Example: "isPrimeExclusive": true |
mustHaveAmazonOffer |
optional | Include only products that currently have an offer sold and fulfilled by Amazon. Example: "mustHaveAmazonOffer": true |
mustNotHaveAmazonOffer |
optional | Include only products that currently have no offer sold and fulfilled by Amazon. Example: "mustNotHaveAmazonOffer": true |
warehouseConditions |
optional | Include only products available under the specified Amazon Warehouse conditions. Use an array of integer condition codes (e.g. 1 = New, 2 = Used - Like New, 3 = Used - Very Good, 24 = Used - Good, 5 = Used - Acceptable). Example: "warehouseConditions": [1, 2] |
Product attribute filters
These filters match products by their listing attributes. Each is an array of strings; the examples below show typical values.
| Parameter | Required | Description |
|---|---|---|
material | optional | Include only products made of the specified material (e.g. “cotton”). Example: "material": ["cotton"] |
type | optional | Include only products matching the specified type (e.g. “shirt”, “dress”). |
manufacturer | optional | Include only products from the specified manufacturer. |
brand | optional | Include only products from the specified brand. |
model | optional | Include only products matching the specified model identifier. |
color | optional | Include only products matching the specified color attribute. |
size | optional | Include only products matching the specified size (e.g. “small”, “one size”). |
unitType | optional | Include only products with the specified unit type (e.g. “count”, “ounce”). |
scent | optional | Include only products with the specified scent (e.g. “lavender”, “citrus”). |
itemForm | optional | Include only products matching the specified item form (e.g. “liquid”, “sheet”). |
pattern | optional | Include only products matching the specified pattern (e.g. “striped”, “solid”). |
style | optional | Include only products matching the specified style attribute (e.g. “modern”, “vintage”). |
itemTypeKeyword | optional | Include only products matching the specified item type keyword (custom search term, e.g. “books”, “prints”). |
targetAudienceKeyword | optional | Include only products targeting the specified audience (e.g. “kids”, “professional”). |
edition | optional | Include only products matching the specified edition (e.g. “first edition”, “standard edition”). |
format | optional | Include only products in the specified format (e.g. “kindle ebook”, “import”, “dvd”). |
author | optional | Include only products by the specified author (applicable to books, music, etc.). |
binding | optional | Include only products with the specified binding type (e.g. “paperback”). |
languages | optional | Include only products available in the specified languages. Use an array of language names. |
brandStoreName | optional | Include only products sold under the specified brand store name on Amazon. |
brandStoreUrlName | optional | Include only products sold under the specified URL-friendly brand store identifier. |
websiteDisplayGroup | optional | Include only products in the specified website display group. |
websiteDisplayGroupName | optional | Include only products in the specified website display group name (a more user-friendly label). |
salesRankDisplayGroup | optional | Include only products belonging to the specified sales rank display group (e.g. “fashion_display_on_website”). |
Range options#
All range options are integer arrays with two entries: [min, max].
| Parameter | Required | Description |
|---|---|---|
isRangeEnabled |
optional | Switch to enable the range options. Example: "isRangeEnabled": true |
currentRange |
optional | Limit the range of the current value of the price type. Example: "currentRange": [105, 50000] (min price $1.05, max price $500) |
deltaRange |
optional | Limit the range of the difference between the weighted average value and the current value over the chosen dateRange interval.Example: "deltaRange": [0, 999] (max difference of $9.99) |
deltaPercentRange |
optional | Same as deltaRange, but in percent. Minimum percent is 10%; for Sales Rank, it is 80%.Example: "deltaPercentRange": [30, 80] (between 30% and 80%) |
deltaLastRange |
optional | Limit the range of the absolute difference between the previous value and the current one. Example: "deltaLastRange": [100, 500] (last change between $1 and $5 price decrease) |
salesRankRange |
optional | Limit the Sales Rank range of the product. Identical to currentRange if the price type is set to Sales Rank. If you want to keep the upper bound open, you can specify -1 (which translates to the maximum integer value).Important: once this range option is used, all products with no Sales Rank will be excluded. Set it to null or leave it out to not use it.Examples: "salesRankRange": [0, 5000] (Sales Rank between 0 and 5000), "salesRankRange": [5000, -1] (Sales Rank higher than 5000) |
Search and sort options#
| Parameter | Required | Description |
|---|---|---|
titleSearch |
optional | Select deals by a keyword-based product title search. The search is case-insensitive and supports up to 50 keywords. If multiple keywords are specified (separated by a space), all must match. Example: "titleSearch": "samsung galaxy" (matches products with both “samsung” AND “galaxy” in the title) |
sortType |
optional | Determines the sort order of the retrieved deals. To invert the sort order, use negative values. See the sort type table below for valid values. |
Valid sortType values
| Value | Sort By | Order |
|---|---|---|
| 1 | Deal age | Newest deals first (not invertible) |
| 2 | Absolute delta | Highest delta to lowest |
| 3 | Sales Rank | Lowest rank to highest |
| 4 | Percentage delta | Highest percent to lowest |
Token Cost#
5 tokens per request, providing up to 150 deals. To retrieve more than 150 results, issue additional requests with an incremented page parameter (5 tokens each); a single query can provide up to 10,000 ASINs this way.
Response#
The response contains a deals field with the following content:
{
"dr": [deal objects],
"categoryIds": [Long],
"categoryNames": [String],
"categoryCount": [Integer]
}
| Field | Description |
|---|---|
dr |
Ordered array of all deal objects matching your query. |
categoryIds |
Includes all root categoryIds of the matched deal products. The returned categories will update based on any filters used in your query, except for category filters. If category filters are applied, they will not affect the returned category information. |
categoryNames |
Includes all root category names of the matched deal products. The returned category names will update based on any filters used, other than category filters. If category filters are used, they will not affect the returned category information. |
categoryCount |
Indicates the number of deal products found in each respective root category. This count updates based on any filters used except for category filters. Applying category filters will not affect the returned category information. |
Note: Each deal product is listed in a single root category. The arrays categoryIds, categoryNames and categoryCount are related by their index positions. If the root category of a product cannot be determined, it will be listed in the category with the name "?" and the ID 9223372036854775807.
Example of one index: ID 165793011, name "Toys & Games", count 40. For more information about categories, visit the Category Object page.
Examples#
Example queryJSON#
A complete query selecting Amazon-price deals on amazon.com from one included root category, sorted by percentage delta over the last week:
{
"page": 0,
"domainId": 1,
"excludeCategories": [1064954, 11091801],
"includeCategories": [16310101],
"priceTypes": [0],
"deltaRange": [0, 10000],
"deltaPercentRange": [20, 100],
"deltaLastRange": null,
"salesRankRange": [0, 40000],
"currentRange": [500, 40000],
"minRating": -1,
"isLowest": false,
"isLowestOffer": false,
"isOutOfStock": false,
"titleSearch": null,
"isRangeEnabled": true,
"isFilterEnabled": false,
"filterErotic": true,
"hasReviews": false,
"singleVariation": true,
"sortType": 4,
"dateRange": 1
}
Example request#
Using GET, the queryJSON must be URL-encoded and passed in the selection parameter. A minimal query {"page":0,"domainId":1,"priceTypes":[0],"dateRange":1} becomes:
curl -s "https://api.keepa.com/deal?key=YOUR_API_KEY&selection=%7B%22page%22%3A0%2C%22domainId%22%3A1%2C%22priceTypes%22%3A%5B0%5D%2C%22dateRange%22%3A1%7D"
Using POST, the query is sent as the request payload — usually the more convenient option for larger queries:
KeepaAPI api = new KeepaAPI("YOUR_API_KEY");
DealRequest dealQuery = new DealRequest();
dealQuery.page = 0;
dealQuery.domainId = 1; // amazon.com
dealQuery.priceTypes = new int[]{0}; // AMAZON price type
dealQuery.dateRange = 1; // interval: last week
dealQuery.isRangeEnabled = true;
dealQuery.currentRange = new int[]{500, 40000};
dealQuery.deltaPercentRange = new int[]{20, 100};
dealQuery.sortType = 4;
api.sendRequest(Request.getDealsRequest(dealQuery))
.done(result -> {
for (Deal deal : result.deals.dr) {
System.out.println(deal.asin + " " + deal.title);
}
})
.fail(failure -> System.out.println(failure));<?php
use Keepa\KeepaAPI;
use Keepa\API\Request;
use Keepa\API\ResponseStatus;
use Keepa\objects\AmazonLocale;
use Keepa\API\DealRequest;
$api = new KeepaAPI("YOUR_API_KEY");
$dealQuery = new DealRequest();
$dealQuery->page = 0;
$dealQuery->domainId = 1; // amazon.com
$dealQuery->priceTypes = [0]; // AMAZON price type
$dealQuery->dateRange = 1; // interval: last week
$dealQuery->isRangeEnabled = true;
$dealQuery->currentRange = [500, 40000];
$dealQuery->deltaPercentRange = [20, 100];
$dealQuery->sortType = 4;
$response = $api->sendRequestWithRetry(Request::getDealsRequest($dealQuery));
if ($response->status == ResponseStatus::OK) {
foreach ($response->deals->dr as $deal) {
echo $deal->asin . " " . $deal->title . PHP_EOL;
}
}import requests
query = {
"page": 0,
"domainId": 1,
"priceTypes": [0],
"dateRange": 1,
"isRangeEnabled": True,
"currentRange": [500, 40000],
"deltaPercentRange": [20, 100],
"sortType": 4,
}
r = requests.post("https://api.keepa.com/deal",
params={"key": "YOUR_API_KEY"}, json=query)
data = r.json()
for deal in data["deals"]["dr"]:
print(deal["asin"], deal["title"])const query = {
page: 0,
domainId: 1,
priceTypes: [0],
dateRange: 1,
isRangeEnabled: true,
currentRange: [500, 40000],
deltaPercentRange: [20, 100],
sortType: 4
};
const res = await fetch("https://api.keepa.com/deal?key=YOUR_API_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(query)
});
const data = await res.json();
for (const deal of data.deals.dr) console.log(deal.asin, deal.title);curl -s -X POST "https://api.keepa.com/deal?key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"page":0,"domainId":1,"priceTypes":[0],"dateRange":1,"isRangeEnabled":true,"currentRange":[500,40000],"deltaPercentRange":[20,100],"sortType":4}'Paging through all results#
Iterate page starting at 0, keeping all other parameters identical, and stop once a response contains fewer than 150 deals (5 tokens per request, up to 10,000 ASINs in total):
page = 0
all_deals = []
while True:
query["page"] = page
r = requests.post("https://api.keepa.com/deal",
params={"key": "YOUR_API_KEY"}, json=query)
dr = r.json()["deals"]["dr"]
all_deals.extend(dr)
if len(dr) < 150:
break # last page reached
page += 1
Example response#
{
"timestamp": 1753651260000,
"tokensLeft": 55,
"refillIn": 42000,
"refillRate": 5,
"tokenFlowReduction": 0,
"tokensConsumed": 5,
"processingTimeInMs": 91,
"deals": {
"dr": [
{
"asin": "B0F3GWXLTS",
"title": "Stainless Steel Insulated Water Bottle, 32 oz",
"creationDate": 7663480,
"categories": [16310101, 2251595011],
"rootCat": 16310101,
"current": [1999, 2499, -1, 4123],
"currentSince": [7663480, 7660110, -1, 7663465],
"delta": [[500, 350, -1, 1200], [780, 410, -1, 2050]],
"deltaPercent": [[20, 12, -1, 23], [28, 14, -1, 33]],
"deltaLast": [-500, 0, -1, 0],
"avg": [[2499, 2849, -1, 5323], [2779, 2910, -1, 6173]],
"lastUpdate": 7663510,
"lightningEnd": 0,
"image": [54, 49, 107, 51, 76, 97, 121, 55, 74, 85, 76, 46, 106, 112, 103]
}
],
"categoryIds": [16310101, 165793011],
"categoryNames": ["Grocery & Gourmet Food", "Toys & Games"],
"categoryCount": [97, 40]
}
}
Response shortened for readability; illustrative values. Prices are integers in the smallest currency unit (e.g. 1999 = $19.99), timestamps like creationDate are in Keepa Time minutes, and image is an array of US-ASCII character codes (here decoding to 61k3Lay7JUL.jpg). See the Deal Object page for the full structure of the entries in dr.