问题所在:记录在有照片之前好几个月就已经有了 VIN
CRM、ERP 或经销商管理系统(DMS)中的一条库存记录,起初只有 VIN、库存编号和价格。照片要等车场摄影师来拍才有,而有些库存车辆根本等不到:在途车辆、仍在整备中的置换车、车型名称与 DMS 图片源中任何条目都对不上的进口车、没人购买过宣传图授权的 1990 年代车型。所有显示这条记录的界面——销售人员的列表、收购人员的估价单、客户的报价单——显示的都是灰色占位图。
该 API 上的经销商和进口工具会根据记录中已有的信息填充这个占位图。如果记录有 VIN,只需一次免费解码即可获得图片。如果只有库存表上的一行描述,自由文本解析也能找到对应车辆。无论哪种方式,记录最终都会保存一个稳定的车辆 id,每个界面都会以相同方式渲染同一辆车。
经销商集成是什么样的
- 录入时解码。VIN 只在创建记录时解码一次,目录车辆 ID 与其一并存储。下游环节无需再拼写品牌或车型。
- 列表用一种视角,详情用另一种。库存列表使用宽画幅的正侧面
side;详情页和报价使用front-3-4。 - 年份跨度大。进口车和二手车库存可追溯到 1990 年代,渲染效果与新到车辆一样:目录涵盖从 1990 年到当前车型年份,包括日本国内市场车型。
- 应用内的签名 URL。CRM 运行在浏览器中,因此会加载由服务器生成、无需密钥的签名 URL,每次调用最多五十个;对于保留超过一周的记录会自动续期。
第 1 步:免费解码 VIN
GET /api/v1/vin/{vin} 完全免费,只需一个 API 密钥。它会返回解码后的年份、品牌、车型、配置、车身类型、发动机,以及 NHTSA vPIC 数据所含的所有其他属性;如果目录中有该车辆,还会返回一个 vehicle 对象,包含其稳定 id 和现成的 image_path。也支持部分 VIN:至少五个字符,每个未知位置用 * 表示,另可附加可选的 year 提示。
curl -s -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/vin/1HGCM82633A004352"{
"data": {
"vin": "1HGCM82633A004352",
"valid": true,
"year": 2003,
"make": "Honda",
"model": "Accord",
"trim": "EX-V6",
"body_class": "Coupe",
"vehicle": {
"id": "veh_3qfyk22gfhsx3",
"make": "Honda",
"model": "Accord",
"year": 2003,
"image_path": "/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3"
}
},
"request_id": "req_01j9x…"
}trim 和 body_class 作为文本保存在记录中,并显示在图片旁边,而不要声称图片展示的就是它们。校验位有误的 VIN 仍然可以解码,结果会带有 valid: false 并列出错误,因此即使库存表中有输入错误,流程也不会就此中断。第 1b 步:当您手头只有库存表上的一行信息时
进口车源通常以电子表格形式提供:年份、品牌、按拍卖行习惯拼写的车型名称,以及等级或配置代码。POST /api/v1/images/resolve 免费且结果确定:它会从短语中提取年份、颜色和视角词,用剩余部分搜索目录,并返回精确参数及可直接据以判断的置信度。
curl -s -X POST https://carimage.dev/api/v1/images/resolve \
-H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "2019 toyota voxy zs side"}'{
"data": {
"params": {
"vehicle_id": "veh_9w0nvw7jphp6r",
"make": "toyota",
"model": "voxy",
"year": 2019,
"view": "side",
"color": "silver"
},
"display": {
"make_name": "TOYOTA",
"model_name": "VOXY"
},
"confidence": "low",
"image_path": "/api/v1/images/car?make=toyota&model=voxy&year=2019&view=side&color=silver"
},
"request_id": "req_01j9x…"
}车辆识别正确(2019 款 Toyota Voxy),但置信度为 low,因为“ZS”是目录中没有的配置等级,只能绕开它进行匹配。在批量导入中,将 high 视为已完成,并把 medium 和 low 连同 candidates 列表交给人工审核。如果表格中已有单独的年份和品牌列,请将它们作为 year 和 make 字段发送,只在 query 中保留车型,匹配结果会准确得多。不含任何车辆相关词语的短语会返回 400;品牌存在但没有匹配车型时会返回 404,并列出该品牌的年份,方便您询问具体车型。
第 2 步:在记录中保存车辆 id
无论通过哪种方式获得,都请将 vehicle.id(或 params.vehicle_id)作为普通字符串列保存在库存记录中。它是确定且永久的:同一车辆在每次部署和每次目录发布后都具有相同的 id,因此可以安全地用作外键。此后,每个图片请求都是 vehicle=veh_…,不会拼错;即使厂商更改了品牌名称或数据源重新归档,已存储的 URL 也不会失效。
第 3 步:列表页用一个视角,详情页用另一个视角
库存列表宽而矮,因此通常选择 2:1 框中的正侧视图:每辆车朝向相同,并位于同一基线上。trim=1&padding=6 会在适配前先裁剪至车辆边缘,因此 Hilux 和 Yaris 在行中的填充方式一致;fit=contain 会让画布保持精确的 640×320,并带透明边距。详情页使用 1024 尺寸的 front-3-4,两者共享缓存:未指定的车漆颜色在两处都是银色。
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3&view=side&w=640&h=320&fit=contain&trim=1&padding=6&format=webp" \
-o stock-4471.webp第 4 步:通过签名 URL 在 CRM 中显示图片
CRM 运行在浏览器中,而浏览器绝不能持有 API 密钥。当页面列出一页库存时,服务器通过 POST /api/v1/image-urls 为每条记录生成一个签名 URL(每次调用最多五十个;每个 URL 的图片计为本月的一张车辆图片),页面像加载普通图片一样加载它们。对于在库数月的记录,有两项设置很重要:
ttl_seconds: 604800搭配renew: true:URL 在七天 TTL 过后仍可使用,续期会在其所在月份将图片计一次,如果当月已计过则不再计数。无人查看该车辆的月份不计数。- 同步的每一页使用一个
Idempotency-Key:重试的请求会重放首次响应,不会重复生成任何内容。
在控制台中将用于生成 URL 的密钥限制为 CRM 的来源,泄露到其他网站的 URL 将返回 403。吊销密钥会使其生成的所有 URL 失效。如果套餐当月的车辆图片已用完,续期请求会返回 402,待额度重置或套餐升级后,同一 URL 将恢复可用。完整的生命周期请参阅签名 URL 文档。
import { CarImageClient } from "@meterapp/car-image-sdk";
const client = new CarImageClient({ apiKey: process.env.CAR_IMAGE_API_KEY });
// On intake: VIN in, vehicle id on the record. Free.
const { data: decoded } = await client.decodeVin(stock.vin);
if (decoded.vehicle) {
stock.vehicleId = decoded.vehicle.id; // veh_…, permanent; the record never spells a car again
stock.trim = decoded.trim; // shown next to the image, never claimed by it
}
// When the CRM draws the stock list: one signed URL per record, up to fifty per call.
// The browser loads them; the key never leaves the server.
const { data: urls } = await client.createImageUrls(
page.map((row) => ({
vehicle: row.vehicleId, view: "side",
width: 640, height: 320, fit: "contain", trim: true, padding: 6, format: "auto",
})),
{ ttlSeconds: 604_800, renew: true, renewDays: 365, idempotencyKey: `stock-list:${syncRunId}:${pageIndex}` }
);CLI、SDK 和 MCP
# decode for free; the output names the vehicle id and a ready-to-run image command
npx @meterapp/car-image vin 1HGCM82633A004352
npx @meterapp/car-image vin 1HGCM82633A004352 --json | jq -r .data.vehicle.id
# a partial VIN from a faded door sticker: at least five characters, * for each unknown position
npx @meterapp/car-image vin "1HGCM826*3A" --year 2003
# the list image for one record
npx @meterapp/car-image get --vehicle veh_3qfyk22gfhsx3 --view side --width 640 --height 320 --fit contain --trim --padding 6 --format webp --out stock-4471.webp常见问题
- 为每条库存车辆记录配一张照片需要多少费用?
- VIN 解码免费。每辆车的每种车漆和视角为一张车辆图片,每月只计一次,无论展示多少次、尺寸如何;使用 If-None-Match 重新校验也是免费的。签名 URL 在生成时计入其图片;若设置了 renew: true,则在之后每个被打开的月份再计一次。库存有几千辆车的经销商集团每月展示几千张车辆图片,因此请按展示中的库存量选择方案。
- VIN 可以解码,但 vehicle 为 null,该怎么办?
- 解码器识别出了品牌、车型和年份,但目录中没有该组合的条目:可能是挂车、某些商用底盘,或数据源尚未收录的车型名称。请显示解码出的字段,用 GET /api/v1/vehicles?q= 搜索目录以防拼写不同,并在需求看板上提交该车辆的请求;POST /api/v1/requests 会为已有的未完成请求投票,而不会重复创建。
- VIN 解码是否涵盖进口车以及从未在美国销售的车辆?
- 解码器使用 NHTSA 的 vPIC 数据,因此向 NHTSA 备案的厂商的 VIN 可以完整解码。从未在美国认证的车辆,通常只能解码出厂商和年份而没有车型,有些则完全无法解码。对于这类库存,请改为根据登记文件进行解析:目录本身覆盖全球,从 1990 年起,Toyota Voxy 等日本国内市场车型也包含在内。
- 渲染图会显示记录中的配置吗?
- 不能。目录以品牌、车型和年份为键,因此 EX-V6 双门轿跑车和 LX 轿车都会渲染为同一款 2003 Accord。请将解码得到的 trim 和 body_class 作为文本放在图片旁边,切勿将渲染图描述为该具体车辆。
- 经销商网站能否使用与 CRM 相同的 URL?
- 使用允许来源列表中包含该网站的密钥来生成 URL,浏览器从其他任何网站加载该 URL 时都会返回 403 origin_not_allowed。没有 Referer 的加载(例如邮件客户端)可以通过。CRM 和网站可以共用一个密钥和一组 URL,也可以各用一个密钥,以便单独撤销其中任意一个。