Open Platform (Open API) Integration Guide

Online docs (recommended): https://docs.rizzitgo.com — API reference stays in sync with this guide
Audience: external partners / third-party developers
Languages: English (this document) · 中文

This guide explains how to integrate with our /open-api/* open endpoints. The open endpoints are physically isolated from the consumer-facing /app-api and the admin /admin-api. They use OAuth2 client_credentials (client mode) for authentication, and control the set of callable endpoints per application via scope.


1. Overview and Architecture

Call sequence:

sequenceDiagram
    participant P as Partner App
    participant GW as API Gateway
    participant SYS as System Service
    participant BIZ as Business Service

    P->>GW: POST /open-api/system/oauth2/token<br/>Basic(clientId:clientSecret)
    GW->>SYS: forward token request
    SYS-->>P: access_token (userType=OPEN_API, expires_in)
    P->>GW: POST /open-api/goods/detail<br/>Bearer access_token + tenant-id
    GW->>BIZ: validate token + scope, then forward
    BIZ-->>P: business data (unified {code,data,msg})

2. Glossary

Term Description
clientId Client ID, the public identifier of the application.
clientSecret Client secret, shown only once at creation/reset. Treat it like a password and keep it secret.
scope Authorization scope; determines which endpoints can be called. Multiple values are space-separated (e.g. goods:detail:read).
tenant-id Tenant ID, the multi-tenant isolation identifier, passed as a request header.
access_token Access token, the credential for calling business endpoints; time-limited (see expires_in).
expires_in Remaining token lifetime, in seconds.
userType User type; always OPEN_API for open-platform tokens.

3. Onboarding Process

  1. Contact platform operations and submit: partner name, contact (name / email / phone), source IPs for callbacks (optional, for the IP whitelist), and the required scopes.
  2. Operations creates the application under Admin Console "Open Platform / Partner Applications" and issues:
    • clientId
    • clientSecret (shown only once; store it securely)
    • the granted scope list (e.g. goods:detail:read)
    • tenant-id
  3. The partner exchanges clientId + clientSecret for an access_token, then calls business endpoints with the token.

Pre-launch checklist:


3.1 Complete Scope Reference

Below is the full list of available scope values. Naming convention: {domain}:{resource}:{action}. When requesting a token, specify the required scopes via the scope parameter (space-separated). Endpoints corresponding to scopes not granted to your application will return 403.

# Scope Description Endpoint(s)
1 goods:detail:read Read goods detail POST /open-api/goods/detail
2 goods:qc:read Read goods QC data POST /open-api/goods/qc-detail
POST /open-api/goods/qc-images
POST /open-api/goods/qc-page
3 goods:search:read Search goods POST /open-api/goods/search-by-images
POST /open-api/goods/search-url-parse
4 promotion:redeem-code:redeem Redeem coupon code POST /open-api/promotion/redeem-code/redeem
5 promotion:member-coupon:read Query member coupons POST /open-api/promotion/member-coupon/page
6 promotion:member-coupon:extend Extend member coupons POST /open-api/promotion/member-coupon/extend
7 promotion:member-coupon:restore Restore expired coupons POST /open-api/promotion/member-coupon/restore
8 promotion:coupon-exchange-code:read Query coupon exchange code status POST /open-api/promotion/coupon-exchange-code/status
9 promotion:spreadsheet:read Query promoter spreadsheet products POST /open-api/promotion/spreadsheet/page
10 pay:order:create Create payment order POST /open-api/pay/order/create
11 pay:order:query Query payment orders POST /open-api/pay/order/query
POST /open-api/pay/order/page
12 pay:order:shipments Upload shipment info POST /open-api/pay/order/upload-shipments
13 order:bag-order:read Query bag orders POST /open-api/order/bag-order/query

Note: The OAuth2 token endpoints (/open-api/system/oauth2/token and /token/revoke) do not require any scope — they only need clientId + clientSecret authentication. The scope list expands as new business capabilities are added; always refer to the latest version of this document.


4. Environments and Domains

Environment Gateway domain Notes
Sandbox / Test api-qa.rizzitbuy.com For integration testing; data isolated from production.
Production api.rizzitgo.com Live environment.

The production gateway domain is api.rizzitgo.com (already used in the examples), and the test/sandbox gateway domain is api-qa.rizzitbuy.com. Replace placeholders such as {tenant-id}, {clientId}, {clientSecret} with the actual values issued by operations.


5. Obtaining an Access Token

Request parameters:

Parameter Location Required Description
Authorization Header Yes Basic base64(clientId:clientSecret)
tenant-id Header Yes Tenant ID
grant_type Body Yes Fixed value client_credentials
scope Body No Space-separated; if omitted, all scopes granted to the application are used

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token' \
  -H 'Authorization: Basic {base64(clientId:clientSecret)}' \
  -H 'tenant-id: {tenant-id}' \
  -d 'grant_type=client_credentials' \
  -d 'scope=goods:detail:read'

Response fields:

Field Type Description
access_token string Access token, carried in subsequent business requests
refresh_token string Empty string in client-credentials mode (no refresh token; re-fetch after expiry)
token_type string Fixed value Bearer
expires_in number Token lifetime in seconds, e.g. 1800
scope string The actually granted scopes, space-separated

Response example:

{
  "code": 0,
  "data": {
    "access_token": "xxxxxxxx",
    "refresh_token": "",
    "token_type": "Bearer",
    "expires_in": 1800,
    "scope": "goods:detail:read"
  },
  "msg": ""
}

Note: the open platform only supports client_credentials. Passing any other grant_type (such as authorization_code / password / refresh_token) returns 400 with the message "the open platform only supports the client_credentials grant". The token's userType is fixed to OPEN_API and cannot access /admin-api or /app-api.


6. Calling Business Endpoints

Every business request must include:

Header Required Description
Authorization Yes Bearer {access_token}
tenant-id Yes The tenant ID, matching the one used to obtain the token
Content-Type Yes (when there is a body) application/json

7. API Reference

7.1 Query Goods Detail (pilot)

Request body (application/json):

Field Type Required Description
goodsId string Yes Goods ID; must not be empty and must not be 0
source integer Yes Goods source: 1=Taobao, 2=1688, 3=Weidian

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/detail' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"goodsId":"123456","source":1}'

Response fields:

Field Type Description
goodsId string Goods ID
goodsTitle string Goods title
goodsDetailUrl string Goods detail page URL
goodsPicUrl string Goods main image
price string Price (in yuan)
priceInCents number Price (in cents)
orginalPrice string Original price (in yuan)
stockNum string Stock quantity
salesCount string Sales count
goodsImageUrlList string[] List of goods image URLs
postFee string Shipping fee (in yuan)
goodsSource integer Goods source: 1=Taobao, 2=1688, 3=Weidian

Response example:

{
  "code": 0,
  "data": {
    "goodsId": "123456",
    "goodsTitle": "Sample Goods",
    "goodsDetailUrl": "https://example.com/item/123456",
    "goodsPicUrl": "https://example.com/img/123456.jpg",
    "price": "99.00",
    "priceInCents": 9900,
    "orginalPrice": "129.00",
    "stockNum": "1000",
    "salesCount": "532",
    "goodsImageUrlList": [
      "https://example.com/img/1.jpg",
      "https://example.com/img/2.jpg"
    ],
    "postFee": "0.00",
    "goodsSource": 1
  },
  "msg": ""
}

7.2 Query Goods QC Detail

Request body (application/json):

Field Type Required Description
goodsId string Yes Goods ID; must not be empty and must not be 0
source integer Yes Goods source: 1=Taobao, 2=1688, 3=Weidian

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-detail' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"goodsId":"123456","source":1}'

Response fields:

Field Type Description
goodsId string Goods ID
qcPathList string[] QC photo URL list
length string Length (cm)
width string Width (cm)
height string Height (cm)
weight string Weight (g)
volume string Volume (cm3)
completionTime string QC completion time (yyyy-MM-dd HH:mm:ss)

Note: for internal information protection, the QC endpoints do not return inspector / photographer staff IDs or names.

Response example:

{
  "code": 0,
  "data": {
    "goodsId": "123456",
    "qcPathList": [
      "https://example.com/qc/1.jpg",
      "https://example.com/qc/2.jpg"
    ],
    "length": "30",
    "width": "20",
    "height": "10",
    "weight": "500",
    "volume": "6000",
    "completionTime": "2026-06-02 18:30:00"
  },
  "msg": ""
}

7.3 Query Goods QC Image List

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-images' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"goodsId":"123456","source":1}'

Response example: data is an array of QC image URLs.

{
  "code": 0,
  "data": [
    "https://example.com/qc/1.jpg",
    "https://example.com/qc/2.jpg"
  ],
  "msg": ""
}

7.4 Paginated QC Data Query by Time

Request body (application/json):

Field Type Required Description
pageNo integer Yes Page number, starting from 1
pageSize integer Yes Page size
goodsId string No Filter by exact goods ID
source integer No Goods source: 1=Taobao, 2=1688, 3=Weidian
createTime string[] No Record creation time range [start, end], format yyyy-MM-dd HH:mm:ss
completionTime string[] No QC completion time range [start, end], format yyyy-MM-dd HH:mm:ss

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-page' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{
        "pageNo": 1,
        "pageSize": 10,
        "completionTime": ["2026-06-01 00:00:00", "2026-06-02 23:59:59"]
      }'

Response fields: data.list is an array of QC details (same fields as 7.2), data.total is the total count.

{
  "code": 0,
  "data": {
    "list": [
      {
        "goodsId": "123456",
        "qcPathList": ["https://example.com/qc/1.jpg"],
        "length": "30",
        "width": "20",
        "height": "10",
        "weight": "500",
        "volume": "6000",
        "completionTime": "2026-06-02 18:30:00"
      }
    ],
    "total": 1
  },
  "msg": ""
}

7.5 Search Goods by Image

Request body (application/json):

Field Type Required Description
imagesUrl string Yes Image URL; must be a publicly accessible image address (common image extensions such as .jpg/.png). An invalid format returns "The image URL format is invalid"
page integer Yes Current page, starting from 1
source integer Yes Goods source: 1=Taobao, 2=1688, 3=Weidian

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/search-by-images' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"imagesUrl":"https://example.com/img/query.jpg","page":1,"source":1}'

Response fields:

Field Type Description
goodsList object[] Goods list; element fields below
page integer Current page
size integer Page size
totalPage integer Total pages
totalCount integer Total count

goodsList element fields:

Field Type Description
goodsId string Goods ID
goodsTitle string Goods title
goodsDetailUrl string Goods detail page URL
goodsPicUrl string Goods main image
goodsSource integer Goods source: 1=Taobao, 2=1688, 3=Weidian
price string Price (yuan)
priceInCents number Price (cents)
originPriceInCents number Original/strike-through price (cents)
salesCount string Sales count
hasDiscount boolean Whether a promotion applies
discountPriceInCents number Discounted price (cents)

Note: to protect internal information, the open API does not return member-scoped fields such as collection status or personalized share links.

Response example:

{
  "code": 0,
  "data": {
    "goodsList": [
      {
        "goodsId": "123456",
        "goodsTitle": "Sample Goods",
        "goodsDetailUrl": "https://example.com/item/123456",
        "goodsPicUrl": "https://example.com/img/123456.jpg",
        "goodsSource": 1,
        "price": "99.00",
        "priceInCents": 9900,
        "originPriceInCents": 9900,
        "salesCount": "532",
        "hasDiscount": true,
        "discountPriceInCents": 8900
      }
    ],
    "page": 1,
    "size": 20,
    "totalPage": 5,
    "totalCount": 100
  },
  "msg": ""
}

7.6 Parse Goods URL

Request body (application/json):

Field Type Required Description
searchUrl string Yes The goods link to parse. Supports short links, long links, and pasted text with noise (spaces and Chinese characters are stripped automatically).
rno string No Promotion code; when non-empty it is appended to the response targetGoodsDetailUrl.

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/goods/search-url-parse' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant id}' \
  -H 'Content-Type: application/json' \
  -d '{"searchUrl":"https://detail.tmall.com/item.htm?id=768650559131","rno":"ABC123"}'

Response fields:

Field Type Description
goodsId string Platform goods ID
goodsSource integer Goods source: 1=Taobao, 2=1688, 3=Weidian, 4=Other
goodsSourceName string Goods source name (taobao/alibaba/weidian)
goodsDetailUrl string Original platform goods detail page URL
targetGoodsDetailUrl string In-site share link (includes the promotion code when rno is non-empty)
success boolean Whether parsing succeeded
searchUrl string The cleaned input link

Response example:

{
  "code": 0,
  "data": {
    "goodsId": "768650559131",
    "goodsSource": 1,
    "goodsSourceName": "taobao",
    "goodsDetailUrl": "https://detail.tmall.com/item.htm?id=768650559131",
    "targetGoodsDetailUrl": "https://www.rizzitgo.com/detailPage?goodsId=768650559131&source=1&rno=ABC123",
    "success": true,
    "searchUrl": "https://detail.tmall.com/item.htm?id=768650559131"
  },
  "msg": ""
}

7.7 Redeem Coupon by Code (issue to a member by email)

Request body (application/json):

Field Type Required Description
code string Yes Redeem code
email string Yes Email of the recipient member, must exactly match a platform member account
requestId string No External request id for idempotency; the same requestId is processed only once within 10 minutes, duplicates return "Duplicate request, please do not retry"

Request example:

curl -X POST 'https://api.rizzitgo.com/open-api/promotion/redeem-code/redeem' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenantId}' \
  -H 'Content-Type: application/json' \
  -d '{"code":"E602F4DC626E4948","email":"user@example.com","requestId":"REQ-20260604-0001"}'

Response fields:

Field Type Description
code string Redeem code
email string Recipient member email
prize string Prize description, auto-generated from the coupon discount: percentage coupon as 30% OFF, amount coupon as $10 OFF (USD, converted from cents); comma-separated when multiple; falls back to coupon title when no discount info
success boolean Whether redemption succeeded
message string Result description
coupons object[] Coupons issued in this redemption (usually 1 in random mode); element fields below

coupons element fields:

Field Type Description
templateId number Coupon template ID
title string Coupon title
couponType integer Coupon type: 1=shipping, 2=product, 3=site-wide
discountType integer Discount type: 1=amount-off, 2=percentage-off
discountPrice number Discount amount (in cents)
discountPercent number Discount percent (effective when discountType=2, e.g. 80 means 20% off)
usePriceCondition number Threshold: minimum spend to use (in cents, 0 = no threshold)
validStartTime string Valid from
validEndTime string Valid until

Response example:

{
  "code": 0,
  "data": {
    "code": "E602F4DC626E4948",
    "email": "user@example.com",
    "prize": "30% OFF",
    "success": true,
    "message": "兑换成功,共获得 1 张优惠券",
    "coupons": [
      {
        "templateId": 1001,
        "title": "满100减10",
        "couponType": 2,
        "discountType": 1,
        "discountPrice": 1000,
        "discountPercent": null,
        "usePriceCondition": 10000,
        "validStartTime": "2026-06-01 00:00:00",
        "validEndTime": "2026-06-30 23:59:59"
      }
    ]
  },
  "msg": ""
}

Business errors: empty email returns "Email is required"; no member found by email returns "Member does not exist"; non-existent/expired/voided redeem codes and per-user or per-day (incl. per-IP) redemption limits reuse the existing redeem-code error codes. Redemption limits, validity and quotas are configured in the admin; please call within the agreed quota.


7.8 Member coupon query / extend / restore

Locate a member by email, member number (unionId), or user ID; query their coupons; extend unused coupons or restore expired ones. All three endpoints use the same user identifier rule: provide exactly one of the three fields, with priority userId > unionId > email.

Coupon status codes (string in both request and response, not numeric):

Code Meaning
UNUSED Not used
USED Used
FINISH Redeemed/settled
EXPIRE Expired
INVALID Voided

7.8.1 Paginated member coupon query

Request body (application/json):

Field Type Required Description
pageNo integer No Page number, starts at 1 (default 1)
pageSize integer No Page size (default 10)
email string One of three Member email
unionId string One of three Member number
userId number One of three User ID
status string No Exact status filter, e.g. EXPIRE for expired coupons
code string No Coupon code (fuzzy match)
templateId number No Coupon template ID

Response data: list (coupon items), total (count). Each item includes id, templateId, title, code, status (string code), discount fields, validStartTime, validEndTime, useTime, takeTime.

Example:

curl -X POST 'https://api.rizzitgo.com/open-api/promotion/member-coupon/page' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"email":"user@example.com","status":"EXPIRE","pageNo":1,"pageSize":10}'

7.8.2 Extend unused coupons

Field Type Required Description
email / unionId / userId One of three Locate member
couponIds number[] Yes Coupon ID list
extendDays integer Yes Extension days, 1–365

Response data: successCount, coupons (id, status, validEndTime).

7.8.3 Restore expired coupons

Field Type Required Description
email / unionId / userId One of three Locate member
couponIds number[] Yes Coupon ID list

Response data: successCount, coupons (id, status=UNUSED, validEndTime).

Business errors: 1_013_024_000 missing user identifier; 1_013_024_001 member not found; 1_013_024_002 coupon not owned by user; 1_013_024_003 invalid status code; 1_013_024_004 restore when not EXPIRE; extend when not UNUSED returns 1_013_003_005.


7.9 Promoter spreadsheet product pagination

Page a promoter's spreadsheet (shared product list) by referral code rno. Optional filters: custom category, keyword, product source, price range, and sort order.

Request body (application/json):

Field Type Required Description
pageNo integer No Page number, starting from 1 (default 1)
pageSize integer No Page size (default 10)
rno string Yes Promoter referral code
categoryCode string No Promoter custom category code; omit to list all categories
keyword string No Search keyword (product title)
source integer No Product source: 1=Taobao, 2=1688, 3=Weidian
sort integer No Sort: omit=created time desc; 1=sales desc; 2=price asc; 3=price desc
minGoodsPrice number No Minimum price in CNY cents
maxGoodsPrice number No Maximum price in CNY cents

Response data:

Field Type Description
list object[] Product list (see fields below)
total number Total count

Main fields in each list item: goodsId, goodsTitle, localGoodsTitle, priceInCents, priceInUsd (USD amount from CNY cents using DB exchange rate), goodsSource, goodsPicUrl, goodsDetailUrl (includes rno), goodsSaleCount, goodsSda, goodsCategoryCode.

Example:

curl -X POST 'https://api.rizzitgo.com/open-api/promotion/spreadsheet/page' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"rno":"ABC123","categoryCode":"cat_001","pageNo":1,"pageSize":10}'

Business errors: 1_013_025_000 missing rno; 1_013_007_000 promoter not found (invalid rno).


8. Revoking a Token (optional)

curl -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token/revoke' \
  -H 'Authorization: Basic {base64(clientId:clientSecret)}' \
  -H 'tenant-id: {tenant-id}' \
  -d 'token={access_token}'

9. Unified Response Structure and Error Codes

All endpoints return the unified structure { code, data, msg }: code = 0 means success, anything else means failure, and msg carries the message.

Common errors:

HTTP / code Meaning Suggested handling
401 Token missing / invalid / expired Obtain a new token and retry
403 Insufficient scope / wrong user type Contact operations to grant the required scope
429 Rate limited (per clientId) Lower the call rate, retry with exponential backoff, request a higher QPS if needed
400 Invalid parameter / unsupported grant_type Check request parameters and grant type

10. Security and Limits


11. Code Samples (obtain token -> query goods detail)

cURL

# 1) obtain token
TOKEN=$(curl -s -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token' \
  -H 'Authorization: Basic {base64(clientId:clientSecret)}' \
  -H 'tenant-id: {tenant-id}' \
  -d 'grant_type=client_credentials' \
  -d 'scope=goods:detail:read' | jq -r '.data.access_token')

# 2) query goods detail
curl -X POST 'https://api.rizzitgo.com/open-api/goods/detail' \
  -H "Authorization: Bearer ${TOKEN}" \
  -H 'tenant-id: {tenant-id}' \
  -H 'Content-Type: application/json' \
  -d '{"goodsId":"123456","source":1}'

Java (JDK 11+ HttpClient)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;

public class OpenApiDemo {

    static final String GATEWAY = "https://api.rizzitgo.com";
    static final String TENANT_ID = "{tenant-id}";
    static final String CLIENT_ID = "{clientId}";
    static final String CLIENT_SECRET = "{clientSecret}";

    public static void main(String[] args) throws Exception {
        HttpClient http = HttpClient.newHttpClient();

        // 1) obtain token
        String basic = Base64.getEncoder()
                .encodeToString((CLIENT_ID + ":" + CLIENT_SECRET).getBytes());
        HttpRequest tokenReq = HttpRequest.newBuilder()
                .uri(URI.create(GATEWAY + "/open-api/system/oauth2/token"))
                .header("Authorization", "Basic " + basic)
                .header("tenant-id", TENANT_ID)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .POST(HttpRequest.BodyPublishers.ofString(
                        "grant_type=client_credentials&scope=goods:detail:read"))
                .build();
        HttpResponse<String> tokenResp = http.send(tokenReq, HttpResponse.BodyHandlers.ofString());
        System.out.println(tokenResp.body());
        // In a real project, parse data.access_token with a JSON library
        String accessToken = "<parse data.access_token from tokenResp>";

        // 2) query goods detail
        HttpRequest bizReq = HttpRequest.newBuilder()
                .uri(URI.create(GATEWAY + "/open-api/goods/detail"))
                .header("Authorization", "Bearer " + accessToken)
                .header("tenant-id", TENANT_ID)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(
                        "{\"goodsId\":\"123456\",\"source\":1}"))
                .build();
        HttpResponse<String> bizResp = http.send(bizReq, HttpResponse.BodyHandlers.ofString());
        System.out.println(bizResp.body());
    }
}

Python (requests)

import base64
import requests

GATEWAY = "https://api.rizzitgo.com"
TENANT_ID = "{tenant-id}"
CLIENT_ID = "{clientId}"
CLIENT_SECRET = "{clientSecret}"

# 1) obtain token
basic = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
token_resp = requests.post(
    f"{GATEWAY}/open-api/system/oauth2/token",
    headers={"Authorization": f"Basic {basic}", "tenant-id": TENANT_ID},
    data={"grant_type": "client_credentials", "scope": "goods:detail:read"},
)
access_token = token_resp.json()["data"]["access_token"]

# 2) query goods detail
biz_resp = requests.post(
    f"{GATEWAY}/open-api/goods/detail",
    headers={
        "Authorization": f"Bearer {access_token}",
        "tenant-id": TENANT_ID,
        "Content-Type": "application/json",
    },
    json={"goodsId": "123456", "source": 1},
)
print(biz_resp.json())

12. FAQ


13. Online API Documentation

The gateway's Knife4j-aggregated Swagger includes an /open-api/** group, where you can view request/response definitions of each endpoint online to ease integration.


14. Document Version

Version Date Changes
v1.0 2026-06 Initial release: OAuth2 client-credentials integration, goods-detail pilot endpoint.
v1.1 2026-06 Added goods QC endpoints: QC detail, QC image list, paginated QC query by time (scope goods:qc:read); token_type corrected to Bearer.
v1.2 2026-06 Added search-goods-by-image endpoint /open-api/goods/search-by-images (scope goods:search:read).
v1.3 2026-06 Added coupon redeem endpoint /open-api/promotion/redeem-code/redeem (scope promotion:redeem-code:redeem), issuing coupons to a member by email.
v1.4 2026-06 Added goods URL parse endpoint /open-api/goods/search-url-parse (scope goods:search:read), with optional promotion code rno.
v1.5 2026-06 Added member coupon query/extend/restore endpoints (scopes promotion:member-coupon:read/extend/restore); status uses string codes.
v1.9 2026-07 Added promoter spreadsheet product pagination /open-api/promotion/spreadsheet/page (scope promotion:spreadsheet:read), query shared products by rno.