主题
GET | POST /api/keepa/deal
浏览 Keepa Browsing Deals:近 12 小时内有价格变动 / 折扣 / 历史新低的 Amazon 商品筛选。
对应 Keepa 官方接口:Browsing Deals
接口
支持 GET / POST 两种形式(语义完全相同,与 Keepa 官方一致):
POST https://mcp.keepamore.com/api/keepa/deal
Content-Type: application/json
GET https://mcp.keepamore.com/api/keepa/deal?selection=<URL 编码的 queryJSON>
- 上游兼容别名:
/api/keepa/deals(复数)等价于本端点,GET/POST 与计费 / 缓存均共享- POST 时 body 直接为 queryJSON;GET 时把同一份 queryJSON 用
encodeURIComponent编码后塞进selection参数
计费
| 项目 | units |
|---|---|
| 任意一次成功调用 | 5 |
单次最多返回 150 条。结果集偏大时建议在客户端做切片消费,不要反复发起完整请求。
queryJSON 字段
必填
| 名称 | 类型 | 说明 |
|---|---|---|
domainId | integer | 站点 ID(1–12) |
常用可选
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
priceTypes | integer[] | [0] | 价格类型(仅 1 个元素;Keepa 限制) |
sortType | integer | 4 | 排序方式(参考 Keepa 官方) |
dateRange | integer | 1 | 时间范围 |
page | integer | — | 页码 |
includeCategories / excludeCategories | integer[] | — | 最多 500 个分类 ID |
deltaRange / deltaPercentRange / deltaLastRange | [min, max] | — | 价格变动区间 |
salesRankRange / currentRange | [min, max] | — | 排名 / 当前价格区间 |
minRating | integer | — | 最低评分 |
titleSearch | string | — | 标题模糊 |
isLowest / isLowestOffer / isOutOfStock | boolean | — | 是否历史最低等 |
isRangeEnabled / isFilterEnabled | boolean | — | 是否启用对应筛选段 |
hasReviews / filterErotic / singleVariation | boolean | — | 其它开关 |
默认值:服务端自动注入
priceTypes=[0]、sortType=4、dateRange=1(对应"近 7 天按百分比降幅排序")。显式传入不会被覆盖。白名单校验:不在白名单的字段直接 400 拒绝,保证可预测性。
响应
json
{
"code": "0000",
"msg": "ok",
"data": {
"deals": {
/* Keepa 原生 /deal 响应;其中 dr[] 是按 dateRange 分组的 Deal Object 数组 */
},
"fromCache": false
}
}deals.dr[] 中每个元素的完整字段(current / delta / deltaPercent / avg 等二维数组与 Date Range 索引)见 Deal Object。
示例
bash
# 请将 km_xxx 替换为你的 API Key
curl -X POST "https://mcp.keepamore.com/api/keepa/deal" \
-H "Content-Type: application/json" \
-H "X-API-Key: km_xxx" \
-d '{
"domainId": 1,
"page": 0,
"priceTypes": [0],
"sortType": 4,
"dateRange": 1,
"includeCategories": [172282],
"deltaPercentRange": [30, 100],
"minRating": 40
}'bash
# 请将 km_xxx 替换为你的 API Key
# selection 必须 URL 编码
SEL=$(printf '%s' '{"domainId":1,"page":0,"priceTypes":[0],"sortType":4,"dateRange":1}' \
| jq -sRr @uri)
curl "https://mcp.keepamore.com/api/keepa/deal?selection=$SEL" \
-H "X-API-Key: km_xxx"js
// 请将 km_xxx 替换为你的 API Key
const query = {
domainId: 1,
page: 0,
priceTypes: [0],
sortType: 4,
dateRange: 1,
includeCategories: [172282],
deltaPercentRange: [30, 100],
minRating: 40,
};
const resp = await fetch("https://mcp.keepamore.com/api/keepa/deal", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "km_xxx",
},
body: JSON.stringify(query),
});
console.log(await resp.json());python
# 请将 km_xxx 替换为你的 API Key
import requests
query = {
"domainId": 1, "page": 0, "priceTypes": [0],
"sortType": 4, "dateRange": 1,
"includeCategories": [172282],
"deltaPercentRange": [30, 100],
"minRating": 40,
}
resp = requests.post("https://mcp.keepamore.com/api/keepa/deal",
headers={"X-API-Key": "km_xxx"}, json=query, timeout=180)
print(resp.json())php
<?php
// 请将 km_xxx 替换为你的 API Key
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$resp = $client->post('https://mcp.keepamore.com/api/keepa/deal', [
'headers' => [
'X-API-Key' => 'km_xxx',
'Content-Type' => 'application/json',
],
'json' => [
'domainId' => 1,
'page' => 0,
'priceTypes' => [0],
'sortType' => 4,
'dateRange' => 1,
'includeCategories' => [172282],
'deltaPercentRange' => [30, 100],
'minRating' => 40,
],
'timeout' => 180,
]);
echo $resp->getBody();java
// 请将 km_xxx 替换为你的 API Key(Java 11+ 标准库)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
String body = """
{"domainId":1,"page":0,"priceTypes":[0],
"sortType":4,"dateRange":1,
"includeCategories":[172282],
"deltaPercentRange":[30,100],
"minRating":40}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://mcp.keepamore.com/api/keepa/deal"))
.header("X-API-Key", "km_xxx")
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(180))
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());go
// 请将 km_xxx 替换为你的 API Key(Go 标准库 net/http + encoding/json)
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
func main() {
body, _ := json.Marshal(map[string]any{
"domainId": 1,
"page": 0,
"priceTypes": []int{0},
"sortType": 4,
"dateRange": 1,
"includeCategories": []int{172282},
"deltaPercentRange": []int{30, 100},
"minRating": 40,
})
req, _ := http.NewRequest("POST",
"https://mcp.keepamore.com/api/keepa/deal", bytes.NewReader(body))
req.Header.Set("X-API-Key", "km_xxx")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 180 * time.Second}
resp, err := client.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}⚠️ 浏览器地址栏直接打开
/api/keepa/deal不带selection=会返回 400(缺参数)。快速试用建议走 POST 形式。
典型配方
| 场景 | 关键字段 |
|---|---|
| 近 7 天 30%+ 降价(默认) | 全部留空,服务端自动注入 priceTypes=[0] sortType=4 dateRange=1 |
| 仅看历史最低 | isLowest=true + isFilterEnabled=true |
| 限定品类 | includeCategories=[<rootCategoryId>],最多 500 个 |
| 排除品类 | excludeCategories=[<id>, ...] |
| 价格 / 排名区间过滤 | currentRange=[min,max] / salesRankRange=[min,max] |
| 关键词标题模糊 | titleSearch="..." |