ĐẶC TẢ KỸ THUẬT API: SEARCH & FILTER (v2.6)

Dành cho: Frontend Engineering Team (Web, Mobile App)
Dịch vụ: AI Search Engine API — LOTTE Mart Vietnam
Phiên bản: 2.6.0 | Cập nhật: 11/10/2026 | Giao thức: JSON over HTTP/2


1. THÔNG TIN ENDPOINT & GATEWAY

  • HTTP Method: POST
  • Accept: application/json

1.1. Cấu trúc URL Endpoint (Đồng bộ tiền tố /api)

Hệ thống cung cấp 2 dịch vụ tìm kiếm qua API Gateway:

  1. Tìm kiếm Từ khóa & Bộ lọc (Text Search):

    • Đường dẫn RESTful (Khuyến nghị sử dụng qua Gateway):
      POST /api/v2/{lang}/{storeId}/products/search
      (Thứ tự tham số: {lang} mã ngôn ngữ vi | en | ko, tiếp đến {storeId} mã chi nhánh vd nsg)
    • Đường dẫn Canonical (Chuẩn dịch vụ nội bộ):
      POST /v2/p/mart/es/{storeId}/{lang}/products/search
      (Thứ tự tham số: {storeId} trước, {lang} sau)
  2. Tìm kiếm bằng Hình ảnh (Image Search):

    • Đường dẫn RESTful (Qua Gateway):
      POST /api/v2/{lang}/{storeId}/products/search-by-image
    • Đường dẫn Canonical (Dịch vụ nội bộ):
      POST /v2/p/mart/es/{storeId}/{lang}/products/search-by-image

1.2. Gateway Base URL (Môi trường DEV)

Môi trường Base Gateway URL URL Text Search Hoàn Chỉnh URL Image Search Hoàn Chỉnh
DEV https://dev-gateway.martonline.lotte.vn https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search-by-image

(Trong mạng nội bộ backend k8s / direct service: POST /api/v1/search)


2. REQUEST SPECIFICATION (THAM SỐ GỬI LÊN)

2.1. Cấu trúc JSON Request

Trường root Kiểu dữ liệu Bắt buộc Mặc định Mô tả & Ràng buộc
query string Có — Từ khóa tìm kiếm. Tối thiểu 1 ký tự sau khi trim. Chuỗi rỗng sẽ trả về HTTP 400.
paginationMode string Không "page" CHÚ Ý: Mặc định của backend là "page". Khi triển khai Infinite Scroll, Frontend bắt buộc phải truyền rõ "paginationMode": "cursor" ở mọi request. Nếu bỏ quên, server sẽ xử lý theo mode page và bỏ qua token cursor.
cursor string Không null Token phân trang Opaque Base64 do server trả về ở nextCursor. Bắt buộc có tiền tố cur_ (vd: cur_eyJvIjoyMCwicCI6Mn0). Server sẽ từ chối HTTP 400 nếu token thiếu tiền tố cur_.
page number Không 1 Số thứ tự trang (khi dùng paginationMode: "page", bắt đầu từ 1).
pageSize number Không 20 Số lượng sản phẩm trả về mỗi trang. Tối đa 100.
sort string Không "relevance" Tiêu chí sắp xếp: "relevance" (liên quan nhất), "price_asc" (giá tăng dần), "price_desc" (giá giảm dần), "newest" (mới nhất).
filters object Không {} Đối tượng chứa toàn bộ bộ lọc sản phẩm (Xem mục 2.2). Lưu ý: Bắt buộc dùng filters, không dùng tên cũ facetFilters.
fields string[] Không All Danh sách các trường cần lấy để tối ưu băng thông (Xem mục 2.3).

2.2. Chi tiết các cách Filter (filters)

Tất cả các bộ lọc bắt buộc nằm trong đối tượng filters. Giữa các nhóm bộ lọc khác nhau áp dụng toán tử AND.

Trường trong filters Kiểu dữ liệu Toán tử Cú pháp gửi lên Mô tả hành vi & Ràng buộc
viTags string[] OR ["Sữa Tươi", "Ít Đường"] Lọc theo tag tiếng Việt. Tối đa 10 items. Sản phẩm khớp nếu có ít nhất 1 tag trong mảng.
enTags string[] OR ["Fresh Milk"] Lọc theo tag tiếng Anh. Tối đa 10 items.
krTags string[] OR ["우유"] Lọc theo tag tiếng Hàn. Tối đa 10 items.
tags string[] OR ["Organic"] Tag alias chung đa ngữ. Tối đa 10 items.
brandId string EQUAL "Vinamilk" Lọc theo mã thương hiệu (Khớp chính xác).
categoryId string PREFIX "110" Lọc theo mã ngành hàng. Khớp tiền tố phân cấp (vd: "110" khớp toàn bộ con "11001", "11002").
priceMin number >= 50000 Giá sàn tối thiểu (VND). Bỏ qua nếu <= 0.
priceMax number <= 200000 Giá trần tối đa (VND). Phải >= priceMin.
inStockOnly boolean EQUAL true Chỉ trả về sản phẩm còn tồn kho (inStock: true).
delivery string[] OR ["express"] Phương thức giao hàng hỗ trợ: "express" (siêu tốc), "standard" (tiêu chuẩn).
benefitFlags string[] OR ["free_gifts"] Cờ ưu đãi. Chỉ chấp nhận 6 giá trị hợp lệ: "special_price", "buy_and_get", "coupon", "free_gifts", "product_base_point", "purchase_with_purchase". (Lưu ý: Dùng "free_gifts", không dùng "gift" để tránh lỗi 400).
ratingMin number >= 4.0 Đánh giá tối thiểu từ 1.0 đến 5.0 (vd: 4.0 tương ứng từ 4 sao trở lên).
attrs object OR (trong key) {"country_of_manufacture": ["Việt Nam"]} Thuộc tính động chuẩn hóa. Chỉ chấp nhận đúng 8 keys cố định trong registry (Xem chi tiết bảng bên dưới).

Danh sách 8 Thuộc tính Động chuẩn hóa được hỗ trợ trong filters.attrs:

  1. country_of_manufacture (string[]): Nơi sản xuất / Xuất xứ (vd: ["Việt Nam", "Hàn Quốc"]).
  2. size (string[]): Kích thước / Dung tích (vd: ["1L", "180ml"]).
  3. material (string[]): Chất liệu sản phẩm (vd: ["Cotton", "Inox"]).
  4. unit (string[]): Đơn vị đóng gói (vd: ["Hộp", "Lốc", "Thùng"]).
  5. brand_origin (string[]): Xuất xứ thương hiệu (vd: ["Việt Nam", "Nhật Bản"]).
  6. sub_brand (string[]): Nhánh thương hiệu con (vd: ["Ông Thọ", "Ngôi Sao Phương Nam"]).
  7. enable_gift_wraping (string[]): Có hỗ trợ gói quà không (["Yes"] hoặc ["No"] / ["true"] / ["false"] / ["1"] / ["0"]). (Chú ý: tên key có 1 chữ 'p' theo index).
  8. is_installation (string[]): Có dịch vụ lắp đặt không (["Yes"] hoặc ["No"]).

CẢNH BÁO QUAN TRỌNG: Backend áp dụng cơ chế DisallowUnknownFields. Tuyệt đối không gửi các key thuộc tính ngoài danh sách 8 key trên (như pack_type, volume, flavor...) — server sẽ từ chối ngay lập tức bằng HTTP 400 Bad Request.

2.3. Chọn trường dữ liệu tối ưu (fields)

Frontend kiểm soát chính xác payload trả về bằng mảng fields:

  • Khối cấp 1: "products", "facets", "suggestedFilters".
  • Trường thẻ sản phẩm: Phải sử dụng đúng cú pháp products.<tên_trường> theo JSON tag của ProductCard:
    products.productId, products.sku, products.name, products.urlKey, products.brand, products.brandId, products.category, products.categoryIds, products.price, products.originalPrice, products.currency, products.inStock, products.stockQty, products.promotion, products.imageUrl, products.sponsored, products.pinned.
    (Lưu ý: Không dùng products.id vì backend không có trường này và sẽ bị bỏ qua).
  • Quy tắc tối ưu băng thông:
    • Trang 1: Gửi fields: ["products", "facets", "suggestedFilters"] để render thẻ sản phẩm và toàn bộ thanh bộ lọc.
    • Trang 2 trở đi (Infinite scroll): Chỉ gửi fields: ["products"] (bỏ qua tính toán facets, giảm 70% kích thước JSON).

3. RESPONSE SPECIFICATION (GIẢI THÍCH CHI TIẾT CÁC FIELD)

3.1. Các trường Siêu dữ liệu (Metadata)

Các trường này luôn luôn xuất hiện trong mọi response, không bị ảnh hưởng bởi tham số fields:

Trường Response Kiểu dữ liệu Ý nghĩa & Cách xử lý ở Frontend
queryId string UUID phiên tìm kiếm. Dùng gửi kèm event tracking click/view lên hệ thống analytics.
totalHits number Tổng số lượng sản phẩm khớp điều kiện tìm kiếm. Dùng hiển thị text: "Tìm thấy X sản phẩm".
tookMs number Thời gian OpenSearch thực thi truy vấn (milliseconds).
paginationMode string Chế độ phân trang đang chạy ("cursor" hoặc "page").
page number Số trang hiện tại.
pageSize number Số sản phẩm cấu hình trên mỗi trang.
pageCeiling number Ngưỡng số trang tối đa có thể tiếp cận (ceil(totalHits / pageSize)). Frontend dùng để khống chế Infinite Scroll không kích hoạt khi đã chạm tới pageCeiling.
hasMore boolean true nếu còn sản phẩm ở các trang tiếp theo; false nếu đã đến trang cuối cùng. Dùng ngắt trigger load-more.
nextCursor string | null Chuỗi token Opaque Base64 có tiền tố cur_ (vd: cur_eyJvIjoyMCwicCI6Mn0). Frontend giữ nguyên giá trị này và truyền vào cursor ở request tiếp theo.
redirect object | null Điều hướng chiến dịch tự động: Khi khác null (thường xảy ra khi từ khóa trúng từ khóa chiến dịch hoặc banner), trả về { "displayType": string, "urlKey": string }. Khi đó products sẽ rỗng, Frontend cần chuyển hướng người dùng ngay tới trang urlKey tương ứng.
suggestedFilters string[] Mảng các từ khóa bộ lọc gợi ý thông minh (vd: ["Ít Đường", "Có Đường", "1L"]) để render thành các chip gợi ý ngay dưới search bar ở Trang 1.
corrected boolean true nếu từ khóa đã được tự động sửa lỗi chính tả; false nếu giữ nguyên.
normalizedQuery string Từ khóa sau khi đã chuẩn hóa và tự động sửa chính tả. Dùng hiển thị: "Kết quả cho từ khóa: ... ".
didYouMean string | null Từ khóa gợi ý nếu hệ thống phát hiện từ khóa khả dĩ khác. Hiển thị: "Có phải bạn muốn tìm: ... "
resolvedMode string Thuật toán xếp hạng thực thi nội bộ ("text", "hybrid"...).

3.2. Danh sách thẻ sản phẩm (products[])

Mỗi phần tử trong mảng products đại diện cho một thẻ sản phẩm hoàn chỉnh:

Trường Kiểu dữ liệu Ý nghĩa & Cách hiển thị
productId string Mã định danh sản phẩm. (CHÚ Ý: Không dùng id mà phải dùng productId).
sku string Mã SKU sản phẩm.
name string Tên sản phẩm đầy đủ.
urlKey string Slug định danh chi tiết sản phẩm để điều hướng sang trang PDP (Product Detail Page).
brand string | null Tên hiển thị của thương hiệu (vd: "Vinamilk"). Dùng để render nhãn thương hiệu trên UI.
brandId string | null Mã định danh thương hiệu.
category string | null Tên hiển thị ngành hàng chính của sản phẩm.
categoryIds string[] Mảng danh sách mã ngành hàng phân cấp (từ cấp cha đến cấp con).
price number Giá bán thực tế hiện tại (VND).
originalPrice number | null Giá gốc niêm yết ban đầu trước khi giảm giá (VND). Nếu có originalPrice > price, Frontend tự tính % giảm giá: Math.round((1 - price/originalPrice) * 100).
currency string Đơn vị tiền tệ (vd: "VND").
inStock boolean Trạng thái tồn kho: true = còn hàng, false = hết hàng (hiển thị badge "Hết hàng" / mờ nút mua).
stockQty number | null Số lượng tồn kho thực tế khả dụng (nếu được cấp quyền).
promotion string | null Thông điệp khuyến mãi ngắn (vd: "Mua 1 Tặng 1", "Giảm 10K").
labels Label[] Mảng sticker đè lên ảnh sản phẩm: [{ "imageUrl": string, "position": number }].
imageUrl string Đường dẫn ảnh đại diện sản phẩm (CDN).
sponsored boolean true nếu là sản phẩm tài trợ quảng cáo. Gắn nhãn "Tài trợ" / "QC".
pinned boolean true nếu là sản phẩm được ghim ưu tiên bởi Merchandiser.

LƯU Ý QUAN TRỌNG: Các trường như discountRate, rating, reviewCount, deliveryMethod, isNew, isBest, isPromotion, tags HOÀN TOÀN KHÔNG CÓ TRÊN THẺ SẢN PHẨM CỦA SEARCH API. Frontend không bind data theo các trường này để tránh bị lỗi undefined.

3.3. Dữ liệu bộ lọc (facets)

Đối tượng facets chứa số lượng đếm để render sidebar và các chip lọc:

Nhóm Facet Cấu trúc dữ liệu Chi tiết & Cách xử lý ở Frontend
viTags, enTags, krTags, tags Bucket[] Danh sách tag và số lượng SP. Cơ chế Self-exclusion: Tag đang chọn vẫn giữ nguyên các tag anh em kèm số lượng dự kiến nếu chọn thêm.
brands Bucket[] Danh sách thương hiệu khớp.
categories Bucket[] Danh sách ngành hàng khớp.
priceRanges PriceBucket[] Cấu trúc phân khúc giá: Mảng các object gồm from, to, max, count (Xem cấu trúc bên dưới).
inStock Bucket[] Số lượng sản phẩm còn hàng (value: "true").
delivery Bucket[] Số lượng sản phẩm theo từng hình thức giao (value: "express", "standard").
benefitFlags Bucket[] Số lượng sản phẩm theo các cờ ưu đãi (value: "special_price", "free_gifts"...).
attrs Record<string, Bucket[]> Object Map chứa 8 thuộc tính: Duyệt bằng Object.entries(facets.attrs). Mỗi key là tên thuộc tính (vd: "country_of_manufacture"), value là mảng Bucket[].

Cấu trúc phần tử Bucket thông thường:

JSON Payload
{
  "value": "Vinamilk",  // Giá trị định danh để gửi lên filters (CHÚ Ý: là "value", KHÔNG PHẢI "key"!)
  "label": "Vinamilk",  // Tên hiển thị thân thiện trên UI
  "count": 45           // Số lượng sản phẩm khớp
}

Cấu trúc phần tử PriceBucket (Khoảng giá):

JSON Payload
{
  "from": 0,            // Giá bắt đầu
  "to": 50000,          // Mốc chặn trên (dùng hiển thị label: "0 – 50.000 đ")
  "max": 49999,         // Giá tối đa thực tế (gửi lên filters.priceMax)
  "count": 22           // Số lượng sản phẩm
}

4. VÍ DỤ cURL VÀ RESPONSE THỰC TẾ

4.1. cURL: Tìm kiếm cơ bản (Trang đầu tiên)

cURL / Bash
curl -X POST "https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "sữa tươi",
    "paginationMode": "cursor",
    "pageSize": 20,
    "fields": ["products", "facets", "suggestedFilters"]
  }'

4.2. cURL: Tìm kiếm kết hợp đầy đủ Bộ lọc (filters + sort + fields)

cURL / Bash
curl -X POST "https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "sữa tươi",
    "paginationMode": "cursor",
    "pageSize": 20,
    "sort": "relevance",
    "filters": {
      "viTags": ["Sữa Tươi", "Ít Đường"],
      "brandId": "Vinamilk",
      "priceMin": 20000,
      "priceMax": 100000,
      "inStockOnly": true,
      "delivery": ["express"],
      "benefitFlags": ["free_gifts"],
      "attrs": {
        "country_of_manufacture": ["Việt Nam"]
      }
    },
    "fields": ["products", "facets"]
  }'

4.3. cURL: Cuộn trang tiếp theo (Infinite Scroll bằng Cursor)

cURL / Bash
curl -X POST "https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "sữa tươi",
    "paginationMode": "cursor",
    "cursor": "cur_eyJvIjoyMCwicCI6Mn0",
    "pageSize": 20,
    "fields": ["products"]
  }'

4.4. Response JSON mẫu thực tế (Trang 1):

JSON Payload
HTTP/2 200 OK
Content-Type: application/json; charset=utf-8

{
  "queryId": "e3b0c442-98fc-1c14-9afe-432100000000",
  "totalHits": 45,
  "tookMs": 18,
  "paginationMode": "cursor",
  "page": 1,
  "pageSize": 20,
  "pageCeiling": 3,
  "hasMore": true,
  "nextCursor": "cur_eyJvIjoyMCwicCI6Mn0",
  "redirect": null,
  "suggestedFilters": ["Ít Đường", "Có Đường", "1L"],
  "resolvedMode": "hybrid",
  "corrected": false,
  "normalizedQuery": "sữa tươi",
  "products": [
    {
      "productId": "8934673123456",
      "sku": "8934673123456",
      "name": "Sữa Tươi Tiệt Trùng Vinamilk 100% Ít Đường 1L",
      "urlKey": "sua-tuoi-tiet-trung-vinamilk-100-it-duong-1l",
      "brand": "Vinamilk",
      "brandId": "Vinamilk",
      "category": "Sữa Tươi Tiệt Trùng",
      "categoryIds": ["110", "11001"],
      "price": 36500,
      "originalPrice": 41000,
      "currency": "VND",
      "inStock": true,
      "stockQty": 50,
      "promotion": "Giảm 11%",
      "labels": [],
      "imageUrl": "https://img.martonline.lotte.vn/p/8934673123456.jpg",
      "sponsored": false,
      "pinned": false
    }
  ],
  "facets": {
    "viTags": [
      { "value": "Sữa Tươi", "label": "Sữa Tươi", "count": 45 },
      { "value": "Ít Đường", "label": "Ít Đường", "count": 18 }
    ],
    "brands": [
      { "value": "Vinamilk", "label": "Vinamilk", "count": 45 }
    ],
    "priceRanges": [
      { "from": 0, "to": 50000, "max": 49999, "count": 30 },
      { "from": 50000, "to": 100000, "max": 99999, "count": 15 }
    ],
    "attrs": {
      "country_of_manufacture": [
        { "value": "Việt Nam", "label": "Việt Nam", "count": 45 }
      ]
    }
  }
}

5. MÃ LỖI HTTP & NGUYÊN NHÂN TỪ CHỐI (HTTP STATUS CODES)

Mã HTTP Tình huống Thông điệp lỗi mẫu Nguyên nhân & Cách khắc phục
200 OK Thành công Dữ liệu theo schema SearchResponse. Xử lý render bình thường.
400 Bad Request Từ khóa rỗng {"error": "query must not be empty"} Giá trị query bị rỗng sau khi trim. Client phải kiểm tra query.trim() trước khi gửi.
400 Bad Request Sai cấu trúc {"error": "unknown field \"facetFilters\""} Gửi tham số ngoài schema. Bắt buộc đổi tên thành filters. Không gửi trường dư thừa.
400 Bad Request Sai key attrs {"error": "unknown field \"pack_type\""} Gửi key thuộc tính ngoài 8 key chuẩn hóa. Chỉ dùng 8 key trong registry.
400 Bad Request Sai cờ ưu đãi {"error": "invalid benefit flag \"gift\""} Dùng "gift" thay vì "free_gifts". Chỉ dùng 6 cờ ưu đãi hợp lệ.
400 Bad Request Quá giới hạn tag {"error": "filters.viTags accepts at most 10 items, got 11"} Mảng tag vượt quá giới hạn 10 phần tử. Khống chế tối đa 10 tag được chọn trên UI.
400 Bad Request Sai cursor {"error": "cursor must start with \"cur_\""} Token cursor bị thiếu tiền tố cur_ hoặc sai định dạng. Gửi đúng chuỗi nguyên bản từ nextCursor.
500 Internal Error Lỗi máy chủ {"error": "Internal search error"} Lỗi hạ tầng backend. Hiển thị thông báo thân thiện và nút thử lại.

6. ĐẶC TẢ TÌM KIẾM BẰNG HÌNH ẢNH (IMAGE SEARCH API)

6.1. Quy trình 2 pha (Two-phase Workflow)

Quy trình tìm kiếm ảnh được thiết kế tối ưu băng thông mạng và pin thiết bị di động:

  • Pha 1 (Trang đầu tiên): Client gửi request dạng multipart/form-data chứa file ảnh image và tham số lọc params (JSON). Response trả về danh sách sản phẩm cùng mã imageRef (vector cache key).
  • Pha 2 (Trang 2+ Infinite Scroll): Client gửi request dạng application/json thông thường mang theo imageRef và cursor. Tuyệt đối không cần upload lại file ảnh, máy chủ tự động tra cứu vector đã tính toán trong bộ nhớ cache.

Pha 1: Upload ảnh (multipart/form-data)

  • Part image (Bắt buộc): Binary dữ liệu ảnh (hỗ trợ image/jpeg, image/png, image/webp). Dung lượng tối đa 5MB.
    (Khuyến nghị kỹ thuật: Khóa tỷ lệ ảnh vuông 1:1 (~800×800px) trên UI crop ảnh của app để trích xuất vector AI chính xác nhất).
  • Part params (Tùy chọn): Chuỗi JSON định nghĩa các tiêu chí bổ trợ:
    JSON Payload
    {
      "query": "loại không đường",          // (Tùy chọn) Text đi kèm để lọc hẹp trong kết quả ảnh
      "paginationMode": "cursor",           // Bắt buộc gửi rõ "cursor" nếu muốn cuộn trang
      "pageSize": 20,                       // Số sản phẩm mỗi trang (mặc định 20, max 100)
      "filters": {                          // Bộ lọc (y hệt cấu trúc filters của Text Search)
        "inStockOnly": true,
        "brandId": "Vinamilk"
      },
      "fields": ["products", "facets"]      // Chọn trường cần nhận
    }
    

Pha 2: Phân trang tiếp theo (application/json)

Khi người dùng cuộn xem trang tiếp theo, gửi body JSON:

JSON Payload
{
  "imageRef": "sha256:9f2a4c8e71b2d3...", // Token nhận từ response Pha 1 (BẮT BUỘC)
  "paginationMode": "cursor",
  "cursor": "cur_eyJvIjoyMCwicCI6Mn0",    // nextCursor từ trang trước (có tiền tố cur_)
  "pageSize": 20,
  "fields": ["products"]                  // Tiết kiệm băng thông: chỉ lấy products
}

Response của Image Search kế thừa toàn bộ cấu trúc của Text Search (products[], facets, totalHits, tookMs, nextCursor, hasMore), kèm theo các trường đặc thù:

Trường Response Kiểu dữ liệu Ý nghĩa & Cách xử lý
imageRef string Mã hash SHA256 định danh vector của bức ảnh trong cache. Client lưu chuỗi này để gửi lên ở request Pha 2+.
resolvedImageMode string Thuật toán vector ảnh thực thi nội bộ (vd: "vector_titan_multi").
caption object | null Thông tin chú thích nếu hệ thống chạy ở chế độ AI Caption (gồm query, outcome, modelId). Thường là null ở chế độ vector thông thường.
  • 404 Not Found (Mã lỗi IMAGE_SEARCH_DISABLED): Trả về khi tính năng tìm kiếm bằng ảnh bị tắt qua cấu hình hệ thống (feature.image_search). Frontend cần ẩn nút camera tìm kiếm ảnh hoặc thông báo tính năng đang bảo trì.

6.5. Ví dụ cURL Image Search Thực Tế

cURL Pha 1: Upload ảnh tìm kiếm lần đầu (Multipart)

cURL / Bash
curl -X POST "https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search-by-image" \
  -F "image=@san-pham.jpg;type=image/jpeg" \
  -F 'params={
    "paginationMode": "cursor",
    "pageSize": 20,
    "filters": {
      "inStockOnly": true
    },
    "fields": ["products", "facets"]
  }'

cURL Pha 2: Cuộn xem trang tiếp theo (JSON dùng imageRef)

cURL / Bash
curl -X POST "https://dev-gateway.martonline.lotte.vn/api/v2/vi/nsg/products/search-by-image" \
  -H "Content-Type: application/json" \
  -d '{
    "imageRef": "sha256:9f2a4c8e71b2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8",
    "paginationMode": "cursor",
    "cursor": "cur_eyJvIjoyMCwicCI6Mn0",
    "pageSize": 20,
    "fields": ["products"]
  }'