QC 图片查询接口 · 通用对接规范
版本 v1 · 2026-09-24 · 发起方:QCradar(qcradar.com)
一句话:按「货源平台 + 商品 ID」查询这件商品在你们仓库拍过的全部 QC 照片。只读,不涉及任何用户或订单数据。
你们只需要实现一个接口。签名算法与购物车一键导入规范完全相同,同一套
clientId/secretKey、同一段校验代码即可复用。已有自己的 QC 开放接口?直接把文档发给我们(点击联系),我们按你们的契约适配。QCradar 目前已对接多家代购平台各不相同的 QC 接口,适配成本很低。本文是我们建议的最省事方案,也把我们在对接中踩过的坑一并写明,照着做可以少走弯路。
为什么要做这件事、QCradar 怎样推荐代购平台,见致各代购平台的公开信。
0. QCradar 怎么使用这些照片(先看这个)
| 事项 | 说明 |
|---|---|
| 展示位置 | 商品详情页的 QC 图集、QC 查看器、浏览器插件的商品卡片。 |
| 来源标注 | 每组照片标明来自哪家代购平台,并附「通过该平台购买」的入口(带你们的推广码)。 |
| 存储 | 照片会镜像到 QCradar 图床,避免热链给你们的图床增加负担。 |
| 不做的事 | 不从照片里提取或展示订单、用户信息。 |
对你们的价值:买家在决定「这件货值不值得买」的那一刻,看到的是你们仓库拍的照片,旁边就是在你们平台下单的入口。持续出现的新 QC,也是买家判断一家代购是否在正常运营的直接依据。
1. 全局约定
| 项 | 值 |
|---|---|
| 鉴权 / 签名 | 与购物车导入规范 §3 完全相同(HMAC-SHA256,4 个 X-* 请求头) |
| 凭据 | 可与购物车导入共用一套 clientId / secretKey,也可单独分配 |
| 编码 | UTF-8,application/json |
| 响应 | 任何情况都必须是 JSON,含 4xx / 5xx / 429 |
| 时间格式 | 统一 Unix 毫秒时间戳(数字)。请不要混用字符串日期。 |
2. 接口:按商品查询 QC
POST {BASE}/open/qc/query
Content-Type: application/json
X-API-Key / X-Timestamp / X-Nonce / X-Signature
查询接口也用 POST,是为了让签名代码与购物车导入完全一致(签名覆盖请求体,不必再定义 query 串排序规则)。
2.1 请求体
{ "platform": "weidian", "itemId": "7412345678", "cursor": null, "limit": 50 }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
platform | string | 是 | weidian / taobao / 1688(小写) |
itemId | string | 是 | 货源平台的原始数字商品 ID,不是你们站内的商品编号或加密 ID |
cursor | string | null | 否 | 翻页游标,首次传 null 或不传 |
limit | int | 否 | 每页条数,默认 50,上限由你们定(建议 ≥ 50) |
2.2 成功响应
{
"code": 200,
"msg": "success",
"data": {
"records": [
{
"recordId": "QC202609180001",
"skuId": "4501234567",
"specText": "颜色:黑色; 尺码:L",
"completedAt": 1758182400000,
"images": [
"https://img.example-agent.com/qc/2026/09/18/a1.jpg",
"https://img.example-agent.com/qc/2026/09/18/a2.jpg"
],
"measurements": { "lengthCm": 72.0, "widthCm": 58.0, "heightCm": null, "weightG": 820 }
}
],
"nextCursor": null
}
}
每条 record = 一次验货(一个规格、一次入库拍照),不是一张图。
| 字段 | 必填 | 说明 |
|---|---|---|
recordId | 是 | 验货记录 ID,你们侧唯一且稳定。我们用它去重,同一条记录重复返回不会重复展示。 |
images | 是 | 这次验货的照片 URL 数组(要求见 §3)。 |
completedAt | 是 | 验货完成时间,Unix 毫秒。买家很看重「最近一次 QC 是什么时候」,请给真实时间,不要给查询时间。 |
skuId | 强烈建议 | 货源平台的真实 SKU ID(微店 skuId / 淘宝、1688 的数字 sku_id)。有了它,我们才能把照片挂到对应的颜色/尺码上。 |
specText | 强烈建议 | 规格的中文原文,如 颜色:黑色; 尺码:L。请给源站原文,不要给翻译后的文本(我们见过同一批数据里混着西班牙语译文)。 |
measurements | 否 | 实测尺寸和重量。没有的项给 null,不要给 0。 |
| 翻页字段 | 说明 |
|---|---|
data.nextCursor | 还有下一页时给游标字符串,没有了给 null。记录按 completedAt 从新到旧排列。 |
✅ 最小可跑通字段集:
recordId / images / completedAt。skuId和specText缺了照片仍能展示,只是没法按颜色尺码分组。
2.3 没有 QC 与出错,请务必区分开
这是对接中最容易做错、影响也最大的一点。
| 情况 | 请这样返回 | QCradar 的理解 |
|---|---|---|
| 商品存在但从没拍过 QC | code 200 + records: [] | 确认没有,过一段时间再查 |
| 商品 ID 不存在 / 平台传错 | code 200 + records: [] | 同上 |
| 签名错、凭据错 | code 401 | 配置问题,停止重试 |
| 限流 | code 429,最好带 retryAfterMs | 退避后重试 |
| 你们侧临时故障 | code 500 / 503 | 稍后重试,不会当成「没有 QC」 |
⚠️ 请不要在出错时返回
code 200+ 空数组。那样我们会把「暂时查不到」误判成「这件货没有 QC」,买家就看不到你们其实拍过的照片。
3. 图片 URL 要求
| 要求 | 原因 |
|---|---|
| 公网可直接访问:无 Referer 校验、无 Cookie、无签名参数 | 我们的镜像服务直接下载。带签名的链接过期后,照片就永久拿不到了。 |
| 长期有效,至少 90 天 | 镜像有排队,新入库的照片可能数小时后才下载。 |
| 给原图或 ≥ 1600px 的大图 | 买家要放大看走线、Logo、做工细节,缩略图没有用。 |
| 支持 JPEG / PNG / WebP | 如果图床是阿里云 OSS 等对象存储,原图 URL 即可,不要拼缩略参数。 |
| 照片上已有你们的水印没问题 | 我们不会去掉你们的水印。 |
4. 可选:按时间增量拉取
如果你们愿意,再提供一个按验货完成时间翻页的接口,我们就能每天增量同步,不必逐个商品去问。你们的查询压力会小很多。
POST {BASE}/open/qc/page
{ "since": 1758096000000, "until": 1758182400000, "cursor": null, "limit": 200 }
响应中的每条 record 与 §2.2 相同,另外带上 platform 和 itemId 两个字段。这个接口不做也不影响上线。
5. 限流与调用方行为
- 请告诉我们你们能接受的 QPS 上限,我们会按上限的一半左右来控制调用频率。
- 同一商品的查询结果会在我方缓存,不会反复查。
- 超限请返回
429JSON,我方会退避。连续失败时,我方会自动熔断你们这个源 15 分钟,不会持续压你们的服务。 - 出口 IP 固定,需要加白名单的话告诉我们。
- 网关层的注意事项同购物车导入规范 §8:开放接口路径不要挂浏览器挑战,返回一律 JSON。
6. 签名测试向量
签名算法见购物车导入规范 §3。本接口用同一组示例凭据:
| 项 | 值 |
|---|---|
secretKey | demo_secret_0123456789abcdef0123 |
X-Timestamp | 1760000000 |
X-Nonce | 0123456789abcdef0123456789abcdef |
| 路径 | /open/qc/query |
| 请求体(69 字节,一行无空格) | {"platform":"weidian","itemId":"7412345678","cursor":null,"limit":50} |
| 请求体 SHA256 | 9d88c80dff125fbf7ed64fb6f78446926d780482374316bb704d3ff82ba02402 |
| X-Signature | b10c66e6a373033e3b7ec586b1d1841599a5abf22fd6fd9cd160b4805f033897 |
7. 对接时需要你们提供的信息
| # | 项 |
|---|---|
| 1 | 测试 / 生产 Base URL 与凭据(可与购物车导入共用) |
| 2 | 支持的货源平台(weidian / taobao / 1688) |
| 3 | QPS 上限 |
| 4 | 图床域名(我们要加进镜像白名单) |
| 5 | 大致的 QC 存量与每日新增量(用于我们安排同步节奏) |
| 6 | 联调对接人 |
8. 联调步骤
- 用 §6 的测试向量离线核对签名。
- 拿一个你们确定拍过 QC 的商品查一次,确认
records非空、图片能在浏览器无痕模式下直接打开。 - 拿一个确定不存在的商品 ID 查一次,确认返回
code 200+ 空数组。 - 确认
completedAt与你们后台显示的验货时间一致,skuId与源站规格对得上。 - 切生产凭据复测一遍,QCradar 上线该来源。
9. 联系方式
技术与商务对接统一走站内反馈系统:点击联系我们,打开后已预选「联系 → 合作」,写明平台名称和对接人即可。提交需要先登录 QCradar 账号,之后的往来都在同一个会话线程里。
本文所有域名、凭据、ID 均为示例。
QC Photo Query API · General Integration Spec
v1 · 2026-09-24 · Initiated by: QCradar (qcradar.com)
In one line: query all QC photos your warehouse has taken for a product, by "source platform + item ID." Read-only, no user or order data involved.
You only need to implement one endpoint. The signing algorithm is exactly the same as the cart import spec — the same
clientId/secretKeypair and the same verification code can be reused.Already have your own QC open API? Just send us the docs (contact us) and we'll adapt to your contract. QCradar has already integrated with several shopping agent platforms' differing QC APIs, so adapting is low-cost. This document is the easiest approach we recommend, and it also lays out the pitfalls we hit during integration, so following it can save you some detours.
For why we're doing this, and how QCradar recommends shopping agent platforms, see the open letter to shopping agent platforms.
0. How QCradar uses these photos (read this first)
| Item | Description |
|---|---|
| Where shown | Product detail page QC gallery, QC viewer, and the browser extension's product card. |
| Source attribution | Each set of photos is labeled with which shopping agent platform it came from, alongside a "buy via this platform" entry point (carrying your referral code). |
| Storage | Photos are mirrored to QCradar's image host, to avoid hotlinking adding load to your image host. |
| What we don't do | We don't extract or display order or user information from the photos. |
Value to you: at the moment a buyer decides "is this item worth buying," what they see are photos taken in your warehouse, right next to an entry point to order through your platform. A steady stream of new QC photos is also a direct signal buyers use to judge whether a shopping agent is operating normally.
1. Global conventions
| Item | Value |
|---|---|
| Auth / signing | Exactly the same as cart import spec §3 (HMAC-SHA256, 4 X-* request headers) |
| Credentials | Can share one clientId / secretKey pair with cart import, or be issued separately |
| Encoding | UTF-8, application/json |
| Response | Must always be JSON, including for 4xx / 5xx / 429 |
| Time format | Uniformly Unix millisecond timestamps (numbers). Please don't mix in string dates. |
2. Endpoint: query QC by product
POST {BASE}/open/qc/query
Content-Type: application/json
X-API-Key / X-Timestamp / X-Nonce / X-Signature
The query endpoint also uses POST, so the signing code stays identical to cart import (the signature covers the request body, so there's no need to define a separate query-string ordering rule).
2.1 Request body
{ "platform": "weidian", "itemId": "7412345678", "cursor": null, "limit": 50 }
| Field | Type | Required | Description |
|---|---|---|---|
platform | string | Yes | weidian / taobao / 1688 (lowercase) |
itemId | string | Yes | The source platform's original numeric product ID, not your site's internal product number or an encrypted ID |
cursor | string | null | No | Pagination cursor; pass null or omit on the first call |
limit | int | No | Records per page, default 50; the cap is up to you (recommend ≥ 50) |
2.2 Success response
{
"code": 200,
"msg": "success",
"data": {
"records": [
{
"recordId": "QC202609180001",
"skuId": "4501234567",
"specText": "颜色:黑色; 尺码:L",
"completedAt": 1758182400000,
"images": [
"https://img.example-agent.com/qc/2026/09/18/a1.jpg",
"https://img.example-agent.com/qc/2026/09/18/a2.jpg"
],
"measurements": { "lengthCm": 72.0, "widthCm": 58.0, "heightCm": null, "weightG": 820 }
}
],
"nextCursor": null
}
}
Each record = one QC inspection (one spec, one intake photo session), not one image.
| Field | Required | Description |
|---|---|---|
recordId | Yes | QC record ID, unique and stable on your side. We use it to dedupe — returning the same record repeatedly won't cause duplicate display. |
images | Yes | Array of photo URLs for this inspection (requirements in §3). |
completedAt | Yes | Inspection completion time, Unix milliseconds. Buyers care a lot about "when was the most recent QC," so give the real time, not the query time. |
skuId | Strongly recommended | The source platform's real SKU ID (Weidian's skuId / Taobao and 1688's numeric sku_id). With this, we can attach photos to the corresponding color/size. |
specText | Strongly recommended | The spec's original Chinese text, e.g. 颜色:黑色; 尺码:L. Please provide the source site's original text, not a translated version (we've seen Spanish translations mixed into the same batch of data). |
measurements | No | Measured dimensions and weight. Give null for missing fields, not 0. |
| Pagination field | Description |
|---|---|
data.nextCursor | A cursor string when there's another page, null when there isn't. Records are ordered by completedAt from newest to oldest. |
✅ Minimum viable field set:
recordId / images / completedAt. WithoutskuIdandspecText, photos can still be displayed, just not grouped by color/size.
2.3 Please distinguish "no QC" from an error
This is the point that's easiest to get wrong during integration, and has the biggest impact.
| Situation | Please return this | How QCradar interprets it |
|---|---|---|
| Product exists but has never had QC taken | code 200 + records: [] | Confirmed none; will query again later |
| Product ID doesn't exist / wrong platform passed | code 200 + records: [] | Same as above |
| Bad signature, bad credentials | code 401 | Configuration problem, stop retrying |
| Rate limited | code 429, ideally with retryAfterMs | Retry after backing off |
| Temporary failure on your side | code 500 / 503 | Retry later; will not be treated as "no QC" |
⚠️ Please do not return
code 200+ an empty array on error. Doing so makes us mistake "temporarily unavailable" for "this item has no QC," so buyers won't see photos you actually took.
3. Image URL requirements
| Requirement | Reason |
|---|---|
| Directly accessible on the public internet: no Referer check, no cookies, no signed parameters | Our mirroring service downloads directly. If the link carries a signature that expires, the photo becomes permanently unavailable. |
| Long-lived, at least 90 days | Mirroring is queued; newly added photos may not be downloaded until hours later. |
| Provide the original image or a large one ≥ 1600px | Buyers want to zoom in on stitching, logos, and craftsmanship details; thumbnails are useless. |
| Support JPEG / PNG / WebP | If your image host is object storage like Alibaba Cloud OSS, the original image URL is fine — don't append thumbnail parameters. |
| It's fine if photos already carry your watermark | We won't remove your watermark. |
4. Optional: incremental pull by time
If you're willing to also provide an endpoint that pages by inspection completion time, we can sync incrementally every day instead of querying product by product. This significantly reduces query load on your side.
POST {BASE}/open/qc/page
{ "since": 1758096000000, "until": 1758182400000, "cursor": null, "limit": 200 }
Each record in the response is the same as in §2.2, with the addition of platform and itemId fields. Not implementing this endpoint doesn't block going live.
5. Rate limiting and caller behavior
- Tell us your acceptable QPS ceiling, and we'll throttle our call rate to roughly half of that.
- Query results for the same product are cached on our side; we won't query repeatedly.
- When over the limit, please return
429JSON and we'll back off. On consecutive failures, we'll automatically circuit-break your source for 15 minutes, so we won't keep hammering your service. - Our outbound IP is fixed; let us know if you need to allowlist it.
- Gateway-layer notes are the same as cart import spec §8: don't put browser challenges on the open API path, and always return JSON.
6. Signature test vector
See cart import spec §3 for the signing algorithm. This endpoint uses the same set of example credentials:
| Item | Value |
|---|---|
secretKey | demo_secret_0123456789abcdef0123 |
X-Timestamp | 1760000000 |
X-Nonce | 0123456789abcdef0123456789abcdef |
| Path | /open/qc/query |
| Request body (69 bytes, one line, no spaces) | {"platform":"weidian","itemId":"7412345678","cursor":null,"limit":50} |
| Request body SHA256 | 9d88c80dff125fbf7ed64fb6f78446926d780482374316bb704d3ff82ba02402 |
| X-Signature | b10c66e6a373033e3b7ec586b1d1841599a5abf22fd6fd9cd160b4805f033897 |
7. Information you need to provide for integration
| # | Item |
|---|---|
| 1 | Test / production base URL and credentials (can be shared with cart import) |
| 2 | Supported source platforms (weidian / taobao / 1688) |
| 3 | QPS ceiling |
| 4 | Image host domain (we need to add it to our mirroring allowlist) |
| 5 | Rough QC volume on hand and daily new additions (used to plan our sync cadence) |
| 6 | Integration contact person |
8. Integration testing steps
- Verify the signature offline using the test vector in §6.
- Query a product you're certain has had QC taken, and confirm
recordsis non-empty and the images open directly in a browser's incognito mode. - Query a product ID you're certain doesn't exist, and confirm it returns
code 200+ an empty array. - Confirm
completedAtmatches the inspection time shown in your backend, and thatskuIdmatches the source site's spec. - Switch to production credentials and retest; QCradar will then bring this source live.
9. Contact
Technical and business contact both go through the on-site feedback system: contact us — it opens with "Contact → Partnership" pre-selected; just fill in your platform name and contact person. Submitting requires signing in to a QCradar account first, and all subsequent correspondence stays in the same thread.
All domains, credentials, and IDs in this document are examples.