二手车价格评估 API:为什么返回的是区间,两个价格分别怎么用
做二手车业务时最容易被用户追问的一句话是「你们这个价格准不准」。如果接口吐出一个孤零零的数字,用户一定会当成报价:给低了他觉得你在压价,给高了后续验车又要往回调,投诉基本从这里开始。真实交易里本来就有议价空间——同一辆车,急着出手时是一个价,挂在店里慢慢卖又是另一个价。
api.xujian.tech
V:xujian_cq
usedcar.price 的设计就顺着这个现实走:传品牌型号 + 车龄 + 里程 + 车况 + 地域,返回的是 priceStart / priceEnd 两个值组成的价格区间(单位:万元),而不是一口价。一次 POST 就能把「多少参数能估出价」这件事收敛掉。
接口速览
| 关键事实 |
说明 |
| 接口地址 |
https://api.xujian.tech/openapi/usedcar/price |
| 接口编码 |
usedcar.price |
| 请求方式 |
POST(参数放 JSON body) |
| 鉴权方式 |
请求头 X-API-Key,不做签名、时间戳或加密 |
| 最简参数 |
brand 与 model 至少填一个 |
| 强建议参数 |
mileage、registrationDate、year、location、accidentHistory |
| 返回核心字段 |
priceStart(万元)、priceEnd(万元)、tip |
| 计费方式 |
按次计费,0.50 元/次 |
| 计费时机 |
估出价格才计费:先预鉴权,估不出价格就不扣费 |
| 不计费场景 |
brand 与 model 都为空、单字段超 50 字符、服务未启用、估不出价格区间、上游超时或网络异常 |
| 单次耗时 |
走一次推理估算,costMs 通常 1 秒以上,建议超时 20~30 秒 |
一、两个价格分别怎么用
| 字段 |
含义 |
典型用法 |
priceStart |
评估价格下限(万元) |
快速成交价、上门收车报价的上沿参考 |
priceEnd |
评估价格上限(万元) |
零售挂牌参考价、详情页「市场价」展示 |
tip |
结果说明 |
展示给终端用户时必须带上,表明这是网络信息推算的结果 |
页面上的常见写法是取中值做主展示、把区间放在副标题:「约 13.6 万(12.5 万 ~ 14.8 万)」。这样既给出了明确感知,又保留区间应有的不确定性。反过来切忌只展示 priceEnd 并称之为「评估价」——那是区间的乐观端,被当成承诺价最容易出纠纷。
二、哪些场景用得上
| 场景 |
具体用法 |
| C 端卖车估价 |
用户填品牌 / 车型 / 上牌时间 / 里程四项,先给区间再引导留资 |
| 收车报价辅助 |
车商录入车况后取 priceStart 作为谈判起点参考 |
| 车源详情页 |
给无标价的车源补一个「市场参考价」 |
| 金融授信 |
以保守口径(priceStart)做抵押物价值的下限估计 |
| 挂牌价合理性校验 |
卖家标价明显高于 priceEnd 时给出提示 |
| 批量估值 |
结合车源列表接口离线跑批,给车源库补价格维度 |
三、请求参数
3.1 请求头
| 参数名 |
类型 |
必填 |
说明 |
X-API-Key |
String |
是 |
开发者 API Key,缺失或无效直接返回失败 |
Content-Type |
String |
是 |
固定 application/json |
3.2 JSON 请求体字段
全部可选,但 brand 与 model 至少填一个,单个字段 ≤ 50 字符。
| 字段 |
类型 |
示例 |
说明 |
brand |
String |
大众 |
品牌 |
model |
String |
迈腾 |
型号 |
year |
String |
2023 |
年款 |
configuration |
String |
330TSI DSG 豪华型 |
配置版本 |
registrationDate |
String |
2022-03 |
上牌时间(YYYY-MM) |
mileage |
String |
8.5 |
行驶里程(万公里) |
accidentHistory |
String |
0 |
事故历史等级:0 无事故 / 1 轻微剐蹭 / 2 更换覆盖件 / 3 结构损伤 |
transferCount |
String |
0 |
过户次数 |
maintenanceRecord |
String |
全程4S店保养 |
保养记录描述 |
fuelType |
String |
汽油 |
燃油类型 |
transmissionType |
String |
自动 |
变速箱类型 |
displacement |
String |
2.0 |
排量(L) |
color |
String |
黑色 |
车身颜色 |
location |
String |
北京 |
车辆所在地 |
description |
String |
车辆外观完好,内饰9成新,无任何改装 |
车辆描述 |
vin |
String |
LSVAL41Z2N2123456 |
车架号 VIN |
engineModel |
String |
EA888 |
发动机型号 |
emissionStandard |
String |
国六 |
排放标准 |
underWarranty |
String |
是 |
是否在质保期 |
vehicleUsage |
String |
家用 |
车辆用途 |
参数重要度排序:mileage(权重最高)> registrationDate / year(车龄折旧)> location(地域差)> accidentHistory(车况)。这四五个字段务必让用户填准,其余字段是可选项,但填得越全结果越稳。
四、返回字段与调用示例
4.1 顶层结构与业务字段
| 字段 |
类型 |
说明 |
code |
int |
0 成功,非 0 失败(统一为 500) |
msg |
String |
成功为 success,失败为具体原因 |
data |
Object |
业务数据,失败时为 null |
data 内部:
| 字段 |
类型 |
示例 |
说明 |
priceStart |
Double |
12.5 |
评估价格下限(万元) |
priceEnd |
Double |
14.8 |
评估价格上限(万元) |
tip |
String |
估计信息来源网络内容,仅供参考 |
结果说明,展示时必须带上 |
apiCode / apiName / chargeType / balance / costMs |
— |
— |
公共字段 |
4.2 curl
curl -s -X POST "https://api.xujian.tech/openapi/usedcar/price" \
-H "Content-Type: application/json" \
-H "X-API-Key: 你的APIKey" \
-d '{
"brand": "大众",
"model": "迈腾",
"year": "2023",
"configuration": "330TSI DSG 豪华型",
"registrationDate": "2022-03",
"mileage": "8.5",
"accidentHistory": "0",
"transferCount": "0",
"maintenanceRecord": "全程4S店保养",
"fuelType": "汽油",
"transmissionType": "自动",
"displacement": "2.0",
"color": "黑色",
"location": "北京",
"description": "车辆外观完好,内饰9成新,无任何改装"
}'
4.3 成功响应
{
"code": 0,
"msg": "success",
"data": {
"priceStart": 12.5,
"priceEnd": 14.8,
"tip": "估计信息来源网络内容,仅供参考",
"apiCode": "usedcar.price",
"apiName": "二手车价格评估",
"chargeType": "PER_CALL",
"balance": 99.5000,
"costMs": 1200
}
}
4.4 Python:给表单做个估价函数
import requests
API_URL = "https://api.xujian.tech/openapi/usedcar/price"
def estimate_price(car: dict) -> tuple[float, float] | None:
"""评估二手车价格区间(万元);估不出返回 None 且不扣费"""
try:
resp = requests.post(
API_URL,
json=car,
headers={
"Content-Type": "application/json", "X-API-Key": API_KEY},
timeout=30,
)
result = resp.json()
except Exception as e:
print(f"请求异常:{e}")
return None
if result.get("code") != 0:
print(f"评估失败(不收费):{result.get('msg')}")
return None
data = result["data"]
return data["priceStart"], data["priceEnd"]
def render(start: float, end: float) -> str:
"""页面展示:中值主标题 + 区间副标题"""
mid = round((start + end) / 2, 2)
return f"约 {mid} 万({start} 万 ~ {end} 万,估计信息来源网络内容,仅供参考)"
if __name__ == "__main__":
car = {
"brand": "大众", "model": "迈腾", "year": "2023",
"registrationDate": "2022-03", "mileage": "8.5",
"accidentHistory": "0", "transferCount": "0",
"fuelType": "汽油", "transmissionType": "自动",
"displacement": "2.0", "color": "黑色", "location": "北京",
}
res = estimate_price(car)
if res:
print(render(*res))
4.5 Java(Hutool)
JSONObject req = JSONUtil.createObj()
.set("brand", "大众")
.set("model", "迈腾")
.set("year", "2023")
.set("configuration", "330TSI DSG 豪华型")
.set("registrationDate", "2022-03")
.set("mileage", "8.5")
.set("accidentHistory", "0")
.set("transferCount", "0")
.set("fuelType", "汽油")
.set("transmissionType", "自动")
.set("displacement", "2.0")
.set("color", "黑色")
.set("location", "北京");
String body = HttpRequest.post("https://api.xujian.tech/openapi/usedcar/price")
.header("Content-Type", "application/json")
.header("X-API-Key", apiKey)
.timeout(20000)
.body(req.toString())
.execute()
.body();
JSONObject json = JSONUtil.parseObj(body);
if (json.getInt("code") != 0) {
System.out.println("评估失败(不收费):" + json.getStr("msg"));
return;
}
JSONObject data = json.getJSONObject("data");
System.out.printf("评估区间:%.2f 万 ~ %.2f 万%n",
data.getDouble("priceStart"), data.getDouble("priceEnd"));
4.6 JavaScript(浏览器 / Node 18+)
const resp = await fetch("https://api.xujian.tech/openapi/usedcar/price", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-Key": API_KEY },
body: JSON.stringify({
brand: "大众", model: "迈腾", year: "2023",
registrationDate: "2022-03", mileage: "8.5",
accidentHistory: "0", location: "北京",
}),
});
const {
code, msg, data } = await resp.json();
if (code === 0) {
console.log(`评估区间:${
data.priceStart} 万 ~ ${
data.priceEnd} 万`);
console.log(`免责说明:${
data.tip}`);
} else {
console.warn("评估失败(不收费):", msg);
}
五、错误码与不计费说明
| code |
msg(示例) |
处理建议 |
| 0 |
success |
调用成功 |
| 500 |
缺少请求头 X-API-Key |
补充 X-API-Key |
| 500 |
API Key 无效 / API Key 已停用 |
检查 Key 或重新启用 |
| 500 |
客户不存在或已停用 |
联系平台确认账号状态 |
| 500 |
余额不足,请先充值 |
充值后重试,余额不足不扣费 |
| 500 |
brand 与 model 至少填一个(填写越完整估值越准确) |
至少补一个;不计费 |
| 500 |
xxx 长度不能超过 50 个字符 |
缩短该字段;不计费 |
| 500 |
二手车服务未启用 / 二手车服务未配置(上游凭证缺失) |
平台侧配置问题,联系平台处理;不计费 |
| 500 |
未能评估出该车的价格区间,请补充品牌、型号、上牌时间与行驶里程后重试;本次调用不计费 |
补齐关键四项后重试;不计费 |
| 500 |
数据服务暂时不可用(请求上游超时或网络异常),本次调用不计费 |
稍后重试;不计费 |
不计费场景汇总:brand 与 model 都为空、单字段超过 50 字符、服务未启用、估不出价格区间、上游超时或网络异常、鉴权失败、余额不足。
六、接入建议
mileage 传万公里 + registrationDate 传 YYYY-MM:这两个字段对结果影响最大,前端要做单位提示(用户很容易填成「8.5 万公里」或「85000」这种带单位的总里程)。
- 失败一定要落到「人工估价」而不是报错:「估不出价格」这条返回本身不收费,说明这类车的参数没覆盖到,正好可以做成收集线索的入口。
tip 原样展示:接口的免责说明是产品合规的一部分,别自作主张删掉或改写。
- 加缓存,别让同一次表单提交重复扣费:按「品牌 + 型号 + 上牌 + 里程 + 城市」拼 key 缓存几小时,用户在页面上反复改一个颜色不会再产生 0.5 元。
- 估值和车源列表搭配用:先用按次 0.01 元的车源列表接口把车源拉下来,再对缺价的车源跑估值,比把整个库都估一遍便宜得多。