主题
GET | POST /api/keepa/productfinder
选品场景的主力接口:按数百个 selection 字段(价格 / 排名 / 销量 / 品类 / 品牌 / 评分 / 折扣 / 历史最低等)组合筛选 Amazon 产品,返回满足条件的 ASIN 列表。对应 Keepa /query。
对应 Keepa 官方接口:Product Finder
接口
支持 GET / POST 两种形式(语义完全相同,与 Keepa 官方一致):
POST https://mcp.keepamore.com/api/keepa/productfinder
Content-Type: application/json
GET https://mcp.keepamore.com/api/keepa/productfinder?selection=<URL 编码的 selection JSON>
- 上游兼容别名:
/api/keepa/query(与 Keepa 官方端点同名)等价于本端点,GET / POST 与计费 / 缓存均共享- POST 时 body 直接为 selection JSON;GET 时把同一份 selection JSON 用
encodeURIComponent编码后塞进selection参数
计费
| 项目 | units |
|---|---|
| 基础(每次成功调用) | 1 |
| selection.stats=1(额外返回 searchInsights 聚合 KPI) | +30 |
例:仅查 ASIN 列表 = 1 unit;同时要 searchInsights = 1 + 30 = 31 units。
不论返回多少条结果(受
perPage影响),基础消耗都是 1 unit;上游 Keepa 也按一次查询计费,不按结果数累加。
selection JSON 字段
必填
| 名称 | 类型 | 说明 |
|---|---|---|
domain | integer | 站点 ID,参见 domain 映射。也可用 domainId / country 别名 |
分页与排序
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
perPage | integer | 50 | 每页 ASIN 数量,Keepa 限制 50–10000,且 (page+1)*perPage ≤ 10000 |
page | integer | 0 | 0-indexed 页码 |
sort | array[][] | — | 排序数组,如 [["current_SALES","asc"]] |
常用筛选(高频子集,完整字段见 Keepa 官方)
| 类别 | 字段 |
|---|---|
| 价格区间(分) | current_AMAZON_gte/lte、current_BUY_BOX_SHIPPING_gte/lte、current_NEW_gte/lte、current_USED_gte/lte |
| 排名 / 销量 | current_SALES_gte/lte、avg30_SALES_gte/lte、monthlySold_gte/lte、salesRankDrops30_gte/lte |
| 分类 / 品牌 | categories_include、categories_exclude、rootCategory、brand、productType |
| 评分 / 评论 | current_RATING_gte/lte(评分 × 10,如 45 = 4.5 星)、current_COUNT_REVIEWS_gte/lte、hasReviews |
| 价格变动 / 历史低 | deltaPercent30_BUY_BOX_SHIPPING_gte/lte、isLowest_BUY_BOX_SHIPPING |
| 标题 | title |
价格单位均为 分:
1000= 10.00 美元 / 英镑 / 欧元 / 等。
响应
json
{
"code": "0000",
"msg": "ok",
"data": {
"asinList": ["B0...", "B0..."],
"totalResultCount": 12345,
"searchInsights": null,
"fromCache": false
}
}拿到 ASIN 列表后,用 product / MCP keepa_get_product 拉详情(建议 detailLevel=summary 控制响应体大小)。
关于
searchInsights:selection 不带stats时该字段固定为null;selection 带"stats": 1时会返回完整的 Search Insights Object(命中 ASIN 的平均 Buy Box 价、FBA 占比、Top 卖家 / 品牌等聚合 KPI),同时按 +30 units 计费(见上文计费表)。
selection 字段所指代的产品维度(current_AMAZON / current_SALES / current_RATING / monthlySold 等)实质上是 Product Object 字段及其
csvPrice Type 索引 的别名;所有筛选 / 排序字段的取值含义、单位(cents / KeepaTime / 评分 ×10 等)均以字段速查为准。
示例
找美国站 Buy Box 价格 10–50 美元、评分 ≥ 4 星、月销 ≥ 100、近 30 天排名上升的产品,按销量升序前 100:
bash
# 请将 km_xxx 替换为你的 API Key
curl -X POST "https://mcp.keepamore.com/api/keepa/productfinder" \
-H "Content-Type: application/json" \
-H "X-API-Key: km_xxx" \
-d '{
"domain": 1,
"page": 0,
"perPage": 100,
"rootCategory": [284507],
"current_BUY_BOX_SHIPPING_gte": 1000,
"current_BUY_BOX_SHIPPING_lte": 5000,
"current_RATING_gte": 40,
"monthlySold_gte": 100,
"salesRankDrops30_gte": 5,
"sort": [["current_SALES", "asc"]]
}'bash
# 请将 km_xxx 替换为你的 API Key
# selection 必须 URL 编码(这里用 jq 演示)
SEL=$(printf '%s' '{"domain":1,"perPage":100,"current_RATING_gte":40}' | jq -sRr @uri)
curl "https://mcp.keepamore.com/api/keepa/productfinder?selection=$SEL" \
-H "X-API-Key: km_xxx"js
// 请将 km_xxx 替换为你的 API Key
const selection = {
domain: 1,
page: 0,
perPage: 100,
rootCategory: [284507],
current_BUY_BOX_SHIPPING_gte: 1000,
current_BUY_BOX_SHIPPING_lte: 5000,
current_RATING_gte: 40,
monthlySold_gte: 100,
salesRankDrops30_gte: 5,
sort: [["current_SALES", "asc"]],
};
const resp = await fetch("https://mcp.keepamore.com/api/keepa/productfinder", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "km_xxx",
},
body: JSON.stringify(selection),
});
console.log(await resp.json());python
# 请将 km_xxx 替换为你的 API Key
import requests
selection = {
"domain": 1, "page": 0, "perPage": 100,
"rootCategory": [284507],
"current_BUY_BOX_SHIPPING_gte": 1000,
"current_BUY_BOX_SHIPPING_lte": 5000,
"current_RATING_gte": 40,
"monthlySold_gte": 100,
"salesRankDrops30_gte": 5,
"sort": [["current_SALES", "asc"]],
}
resp = requests.post("https://mcp.keepamore.com/api/keepa/productfinder",
headers={"X-API-Key": "km_xxx"}, json=selection, 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/productfinder', [
'headers' => [
'X-API-Key' => 'km_xxx',
'Content-Type' => 'application/json',
],
'json' => [
'domain' => 1,
'page' => 0,
'perPage' => 100,
'rootCategory' => [284507],
'current_BUY_BOX_SHIPPING_gte' => 1000,
'current_BUY_BOX_SHIPPING_lte' => 5000,
'current_RATING_gte' => 40,
'monthlySold_gte' => 100,
'salesRankDrops30_gte' => 5,
'sort' => [['current_SALES', 'asc']],
],
'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 = """
{"domain":1,"page":0,"perPage":100,
"rootCategory":[284507],
"current_BUY_BOX_SHIPPING_gte":1000,
"current_BUY_BOX_SHIPPING_lte":5000,
"current_RATING_gte":40,
"monthlySold_gte":100,
"salesRankDrops30_gte":5,
"sort":[["current_SALES","asc"]]}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://mcp.keepamore.com/api/keepa/productfinder"))
.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{
"domain": 1,
"page": 0,
"perPage": 100,
"rootCategory": []int{284507},
"current_BUY_BOX_SHIPPING_gte": 1000,
"current_BUY_BOX_SHIPPING_lte": 5000,
"current_RATING_gte": 40,
"monthlySold_gte": 100,
"salesRankDrops30_gte": 5,
"sort": [][]any{{"current_SALES", "asc"}},
})
req, _ := http.NewRequest("POST",
"https://mcp.keepamore.com/api/keepa/productfinder", 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))
}典型配方
| 场景 | 关键字段 |
|---|---|
| 某品类高分爆款 | rootCategory=[<id>] + current_RATING_gte=40 + monthlySold_gte=100 |
| 历史最低 + 高评分 | isLowest_BUY_BOX_SHIPPING=true + current_RATING_gte=40 + current_COUNT_REVIEWS_gte=100 |
| 排名上升中(趋势品) | salesRankDrops30_gte=5 + current_SALES_lte=100000 + sort=[["salesRankDrops30","desc"]] |
| 价格区间 + 品牌过滤 | current_BUY_BOX_SHIPPING_gte/lte + brand=["BrandA","BrandB"] |
| 标题关键词搜索 | title="hunting gear" + current_RATING_gte=40 |
| 控制成本 | perPage=50(默认,不会触发结果集附加 unit) |
常见错误
| code | 场景 |
|---|---|
4000 | 缺 domain / JSON 非法 / GET 缺 selection |
QUOTA_* | 额度 / 限速不足 |
和 MCP 的对应
完整字段参考
- Finder Fields 字段参考(含全部 selection 参数、取值、互斥规则)